Skip to content

Commit f5c11a1

Browse files
committed
stream: don't emit finish after close
Writable stream could emit 'finish' after 'close'. PR-URL: #32933 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 9f14584 commit f5c11a1

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

lib/_stream_writable.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ function WritableState(options, stream, isDuplex) {
175175

176176
// Indicates whether the stream has finished destroying.
177177
this.closed = false;
178+
179+
// True if close has been emitted or would have been emitted
180+
// depending on emitClose.
181+
this.closeEmitted = false;
178182
}
179183

180184
function resetBuffer(state) {
@@ -650,11 +654,10 @@ function finishMaybe(stream, state, sync) {
650654

651655
function finish(stream, state) {
652656
state.pendingcb--;
653-
if (state.errorEmitted)
657+
// TODO (ronag): Unify with needFinish.
658+
if (state.errorEmitted || state.closeEmitted)
654659
return;
655660

656-
// TODO(ronag): This could occur after 'close' is emitted.
657-
658661
state.finished = true;
659662
stream.emit('finish');
660663

lib/internal/streams/destroy.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ function emitCloseNT(self) {
7373
const r = self._readableState;
7474
const w = self._writableState;
7575

76+
if (w) {
77+
w.closeEmitted = true;
78+
}
79+
7680
if ((w && w.emitClose) || (r && r.emitClose)) {
7781
self.emit('close');
7882
}
@@ -111,15 +115,16 @@ function undestroy() {
111115
}
112116

113117
if (w) {
114-
w.closed = false;
115118
w.destroyed = false;
119+
w.closed = false;
120+
w.closeEmitted = false;
116121
w.errored = false;
122+
w.errorEmitted = false;
117123
w.ended = false;
118124
w.ending = false;
119125
w.finalCalled = false;
120126
w.prefinished = false;
121127
w.finished = false;
122-
w.errorEmitted = false;
123128
}
124129
}
125130

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const { Writable } = require('stream');
5+
6+
{
7+
const w = new Writable({
8+
write: common.mustCall((chunk, encoding, cb) => {
9+
w.on('close', common.mustCall(() => {
10+
cb();
11+
}));
12+
})
13+
});
14+
15+
w.on('finish', common.mustNotCall());
16+
w.end('asd');
17+
w.destroy();
18+
}
19+
20+
{
21+
const w = new Writable({
22+
write: common.mustCall((chunk, encoding, cb) => {
23+
w.on('close', common.mustCall(() => {
24+
cb();
25+
w.end();
26+
}));
27+
})
28+
});
29+
30+
w.on('finish', common.mustNotCall());
31+
w.write('asd');
32+
w.destroy();
33+
}

0 commit comments

Comments
 (0)