Skip to content

Commit f11c61f

Browse files
committed
stream: fix deadlock when pipeing to full sink
When piping a paused Readable to a full Writable we didn't register a drain listener which cause the src to never resume. Refs: #48666
1 parent 8244e6c commit f11c61f

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

lib/internal/streams/readable.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -822,9 +822,7 @@ Readable.prototype.pipe = function(dest, pipeOpts) {
822822
// Start the flow if it hasn't been started already.
823823

824824
if (dest.writableNeedDrain === true) {
825-
if (state.flowing) {
826-
pause();
827-
}
825+
pause();
828826
} else if (!state.flowing) {
829827
debug('pipe resume');
830828
src.resume();
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"use strict";
2+
3+
const common = require('../common');
4+
const { Readable, Writable } = require('stream');
5+
6+
// https://github.com/nodejs/node/issues/48666
7+
(async () => {
8+
// Prepare src that is internally ended, with buffered data pending
9+
const src = new Readable({ read() {} });
10+
src.push(Buffer.alloc(100));
11+
src.push(null);
12+
src.pause();
13+
14+
// Give it time to settle
15+
await new Promise((resolve) => setImmediate(resolve));
16+
17+
const dst = new Writable({
18+
highWaterMark: 1000,
19+
write(buf, enc, cb) {
20+
process.nextTick(cb);
21+
}
22+
});
23+
24+
dst.write(Buffer.alloc(1000)); // Fill write buffer
25+
dst.on('finish', common.mustCall());
26+
src.pipe(dst);
27+
})();

0 commit comments

Comments
 (0)