Mercurial > hg > rlgwebd
comparison rlgwebd.js @ 174:dc12ba30d559
Fix further crashes when following dgamelaunch games.
The crashes apparently resulted from reading a ttyrec header and
then trying to read the data chunk before dgamelaunch produced it.
When the data chunk did become available, it would be read by the
header function.
The simplest solution was to store the position for reading the
ttyrec file in the DGLSession, and to leave it unchanged if anything
unexpected occurs when reading.
author | John "Elwin" Edwards |
---|---|
date | Mon, 12 Jan 2015 17:10:35 +0000 |
parents | 671bed5039aa |
children | 4dd87508fc96 |
comparison
equal
deleted
inserted
replaced
173:60605bacde36 | 174:dc12ba30d559 |
---|---|
256 var fname = basename.slice(firstsep + 1); | 256 var fname = basename.slice(firstsep + 1); |
257 this.ttyrec = path.join("/dgldir/ttyrec", this.pname, this.gname, fname); | 257 this.ttyrec = path.join("/dgldir/ttyrec", this.pname, this.gname, fname); |
258 /* Flag to prevent multiple handlers from reading simultaneously and | 258 /* Flag to prevent multiple handlers from reading simultaneously and |
259 * getting into a race. */ | 259 * getting into a race. */ |
260 this.reading = false; | 260 this.reading = false; |
261 this.rpos = 0; | |
261 this.framebuf = new Buffer(1024); | 262 this.framebuf = new Buffer(1024); |
262 this.frameoff = 0; | 263 this.frameoff = 0; |
263 this.framepush = function(chunk) { | 264 this.framepush = function(chunk) { |
264 /* If this chunk resets the screen, discard what preceded it. */ | 265 /* If this chunk resets the screen, discard what preceded it. */ |
265 var cgame = games[this.gname]; | 266 var cgame = games[this.gname]; |
284 this.readchunk = function () { | 285 this.readchunk = function () { |
285 if (this.reading) | 286 if (this.reading) |
286 return; | 287 return; |
287 this.reading = true; | 288 this.reading = true; |
288 var header = new Buffer(12); | 289 var header = new Buffer(12); |
289 fs.read(ss.fd, header, 0, 12, null, function (err, n, buf) { | 290 fs.read(ss.fd, header, 0, 12, ss.rpos, function (err, n, buf) { |
290 /* Stop recursion if end of file has been reached. */ | 291 /* Stop recursion if end of file has been reached. */ |
291 if (err || n < 12) { | 292 if (err || n < 12) { |
293 if (!err && n > 0) { | |
294 tslog("DGL %s: expected 12-byte header, got %d", ss.tag(), n); | |
295 } | |
292 ss.reading = false; | 296 ss.reading = false; |
293 return; | 297 return; |
294 } | 298 } |
299 ss.rpos += 12; | |
295 var datalen = buf.readUInt32LE(8); | 300 var datalen = buf.readUInt32LE(8); |
296 //tslog("Allocating %d bytes", datalen); | 301 //tslog("Allocating %d bytes", datalen); |
302 if (datalen > 16384) { | |
303 tslog("DGL %s: looking for %d bytes", ss.tag(), datalen); | |
304 } | |
297 var databuf = new Buffer(datalen); | 305 var databuf = new Buffer(datalen); |
298 fs.read(ss.fd, databuf, 0, datalen, null, function (err, n, buf) { | 306 fs.read(ss.fd, databuf, 0, datalen, ss.rpos, function (err, n, buf) { |
299 ss.reading = false; | |
300 if (err || n < datalen) { | 307 if (err || n < datalen) { |
308 /* Next time, read the header again. */ | |
309 ss.rpos -= 12; | |
310 ss.reading = false; | |
311 tslog("DGL %s: expected %d bytes, got %d", ss.tag(), datalen, n); | |
301 return; | 312 return; |
302 } | 313 } |
314 ss.rpos += n; | |
315 ss.reading = false; | |
303 /* Process the data */ | 316 /* Process the data */ |
304 ss.framepush(buf); | 317 ss.framepush(buf); |
305 ss.emit("data", buf); | 318 ss.emit("data", buf); |
306 tslog("DGL %s: %d bytes", ss.tag(), buf.length); | 319 //tslog("DGL %s: %d bytes", ss.tag(), buf.length); |
307 /* Recurse. */ | 320 /* Recurse. */ |
308 ss.readchunk(); | 321 ss.readchunk(); |
309 }); | 322 }); |
310 }); | 323 }); |
311 }; | 324 }; |