stream: avoid writeAfterEnd() while ending

Calling `writable.end()` will probably synchronously call
`writable.write()`, in such a situation the `state.ended`
is false and `writable.write()` doesn't trigger `writeAfterEnd()`.

PR-URL: https://github.com/nodejs/node/pull/18170
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
陈刚 2018-01-16 12:17:58 +08:00 committed by Matteo Collina
parent 49b3798f81
commit c7ca07ab50
2 changed files with 25 additions and 1 deletions

View File

@ -273,7 +273,7 @@ Writable.prototype.write = function(chunk, encoding, cb) {
if (typeof cb !== 'function') if (typeof cb !== 'function')
cb = nop; cb = nop;
if (state.ended) if (state.ending)
writeAfterEnd(this, cb); writeAfterEnd(this, cb);
else if (isBuf || validChunk(this, state, chunk, cb)) { else if (isBuf || validChunk(this, state, chunk, cb)) {
state.pendingcb++; state.pendingcb++;

View File

@ -154,3 +154,27 @@ const stream = require('stream');
}; };
rs.pipe(ws); rs.pipe(ws);
} }
{
const w = new stream.Writable();
w._write = (chunk, encoding, cb) => {
process.nextTick(cb);
};
w.on('error', common.mustCall());
w.on('prefinish', () => {
w.write("shouldn't write in prefinish listener");
});
w.end();
}
{
const w = new stream.Writable();
w._write = (chunk, encoding, cb) => {
process.nextTick(cb);
};
w.on('error', common.mustCall());
w.on('finish', () => {
w.write("should't write in finish listener");
});
w.end();
}