Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
stream: call write cb before finish event
Browse files Browse the repository at this point in the history
Since 049903e, an end callback could be called before a write
callback if end() is called before the write is done. This patch
resolves the issue.

In collaboration with @gne

Fixes node-formidable/formidable#209
Fixes #5215
  • Loading branch information
isaacs authored and indutny committed Apr 8, 2013
1 parent e4b716e commit c93af86
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
21 changes: 15 additions & 6 deletions lib/_stream_writable.js
Expand Up @@ -240,7 +240,8 @@ function onwrite(stream, er) {
if (er)
onwriteError(stream, state, sync, er, cb);
else {
var finished = finishMaybe(stream, state);
// Check if we're actually ready to finish, but don't emit yet
var finished = needFinish(stream, state);

if (!finished && !state.bufferProcessing && state.buffer.length)
clearBuffer(stream, state);
Expand All @@ -259,6 +260,8 @@ function afterWrite(stream, state, finished, cb) {
if (!finished)
onwriteDrain(stream, state);
cb();
if (finished)
finishMaybe(stream, state);
}

// Must force callback to be called on nextTick, so that we don't
Expand Down Expand Up @@ -326,15 +329,21 @@ Writable.prototype.end = function(chunk, encoding, cb) {
endWritable(this, state, cb);
};


function needFinish(stream, state) {
return (state.ending &&
state.length === 0 &&
!state.finished &&
!state.writing);
}

function finishMaybe(stream, state) {
if (state.ending &&
state.length === 0 &&
!state.finished &&
!state.writing) {
var need = needFinish(stream, state);
if (need) {
state.finished = true;
stream.emit('finish');
}
return state.finished;
return need;
}

function endWritable(stream, state, cb) {
Expand Down
29 changes: 29 additions & 0 deletions test/simple/test-stream2-writable.js
Expand Up @@ -275,6 +275,18 @@ test('end callback after .write() call', function (t) {
});
});

test('end callback called after write callback', function (t) {
var tw = new TestWriter();
var writeCalledback = false;
tw.write(new Buffer('hello world'), function() {
writeCalledback = true;
});
tw.end(function () {
t.equal(writeCalledback, true);
t.end();
});
});

test('encoding should be ignored for buffers', function(t) {
var tw = new W();
var hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb';
Expand Down Expand Up @@ -346,3 +358,20 @@ test('dont end while writing', function(t) {
w.write(Buffer(0));
w.end();
});

test('finish does not come before write cb', function(t) {
var w = new W();
var writeCb = false;
w._write = function(chunk, e, cb) {
setTimeout(function() {
writeCb = true;
cb();
}, 10);
};
w.on('finish', function() {
assert(writeCb);
t.end();
});
w.write(Buffer(0));
w.end();
});

0 comments on commit c93af86

Please sign in to comment.