Skip to content

Commit

Permalink
stream: don't emit finish after destroy
Browse files Browse the repository at this point in the history
  • Loading branch information
ronag committed Nov 18, 2021
1 parent 415726b commit e256132
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 12 deletions.
16 changes: 12 additions & 4 deletions lib/internal/streams/writable.js
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ Writable.prototype.end = function(chunk, encoding, cb) {

function needFinish(state) {
return (state.ending &&
!state.destroyed &&
state.constructed &&
state.length === 0 &&
!state.errored &&
Expand Down Expand Up @@ -732,11 +733,18 @@ function prefinish(stream, state) {
function finishMaybe(stream, state, sync) {
if (needFinish(state)) {
prefinish(stream, state);
if (state.pendingcb === 0 && needFinish(state)) {
state.pendingcb++;
if (state.pendingcb === 0) {
if (sync) {
process.nextTick(finish, stream, state);
} else {
state.pendingcb++;
process.nextTick((stream, state) => {
if (needFinish(state)) {
finish(stream, state);
} else {
state.pendingcb--;
}
}, stream, state);
} else if (needFinish(state)) {
state.pendingcb++;
finish(stream, state);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-stream-duplex-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ const assert = require('assert');
duplex.removeListener('end', fail);
duplex.removeListener('finish', fail);
duplex.on('end', common.mustNotCall());
duplex.on('finish', common.mustCall());
duplex.on('finish', common.mustNotCall());
assert.strictEqual(duplex.destroyed, true);
}

Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-stream-transform-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ const assert = require('assert');
transform.removeListener('end', fail);
transform.removeListener('finish', fail);
transform.on('end', common.mustCall());
transform.on('finish', common.mustCall());
transform.on('finish', common.mustNotCall());
}

{
Expand Down
2 changes: 0 additions & 2 deletions test/parallel/test-stream-writable-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ const assert = require('assert');

write.destroy();

write.removeListener('finish', fail);
write.on('finish', common.mustCall());
assert.strictEqual(write.destroyed, true);
}

Expand Down
10 changes: 10 additions & 0 deletions test/parallel/test-stream-writable-finish-destroyed.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,13 @@ const { Writable } = require('stream');
w.write('asd');
w.destroy();
}

{
const w = new Writable({
write() {
}
});
w.on('finish', common.mustNotCall());
w.end();
w.destroy();
}
4 changes: 0 additions & 4 deletions test/parallel/test-stream-write-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,5 @@ for (const withPendingData of [ false, true ]) {
assert.strictEqual(chunksWritten, useEnd && !withPendingData ? 1 : 2);
assert.strictEqual(callbacks.length, 0);
assert.strictEqual(drains, 1);

// When we used `.end()`, we see the 'finished' event if and only if
// we actually finished processing the write queue.
assert.strictEqual(finished, !withPendingData && useEnd);
}
}

0 comments on commit e256132

Please sign in to comment.