diff --git a/rlgwebd.js b/rlgwebd.js index 8bfe779..3f24d74 100755 --- a/rlgwebd.js +++ b/rlgwebd.js @@ -205,6 +205,9 @@ function DglSession(filename) { this.pname = basename.slice(0, firstsep); var fname = basename.slice(firstsep + 1); this.ttyrec = path.join("/dgldir/ttyrec", this.pname, this.gname, fname); + /* Flag to prevent multiple handlers from reading simultaneously and + * getting into a race. */ + this.reading = false; this.framebuf = new Buffer(1024); this.frameoff = 0; this.framepush = function(chunk) { @@ -229,17 +232,24 @@ function DglSession(filename) { this.frameoff += chunk.length; }; this.readchunk = function () { + if (this.reading) + return; + this.reading = true; var header = new Buffer(12); fs.read(ss.fd, header, 0, 12, null, function (err, n, buf) { /* Stop recursion if end of file has been reached. */ - if (err || n < 12) + if (err || n < 12) { + ss.reading = false; return; + } var datalen = buf.readUInt32LE(8); //tslog("Allocating %d bytes", datalen); var databuf = new Buffer(datalen); fs.read(ss.fd, databuf, 0, datalen, null, function (err, n, buf) { - if (err || n < datalen) + ss.reading = false; + if (err || n < datalen) { return; + } /* Process the data */ ss.framepush(buf); ss.emit("data", buf); @@ -278,6 +288,8 @@ function DglSession(filename) { }; this.close = function () { this.watcher.close() + /* Ensure all data is handled before quitting. */ + this.readchunk(); fs.close(this.fd); this.emit("close"); tslog("DGL %s: closed", ss.tag());