node/lib/internal/streams/duplexpair.js
Robert Nagy f58e8eb103 stream: do not deadlock duplexpair
If nothing is buffered then _read will not be called and the
callback will not be invoked, effectivly deadlocking.

Fixes: https://github.com/nodejs/node/issues/29758

PR-URL: https://github.com/nodejs/node/pull/29836
Refs: https://github.com/nodejs/node/pull/29649
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
2019-10-05 17:43:21 -07:00

47 lines
938 B
JavaScript

'use strict';
const { Duplex } = require('stream');
const kCallback = Symbol('Callback');
const kOtherSide = Symbol('Other');
class DuplexSocket extends Duplex {
constructor() {
super();
this[kCallback] = null;
this[kOtherSide] = null;
}
_read() {
const callback = this[kCallback];
if (callback) {
this[kCallback] = null;
callback();
}
}
_write(chunk, encoding, callback) {
if (chunk.length === 0) {
process.nextTick(callback);
} else {
this[kOtherSide].push(chunk);
this[kOtherSide][kCallback] = callback;
}
}
_final(callback) {
this[kOtherSide].on('end', callback);
this[kOtherSide].push(null);
}
}
class DuplexPair {
constructor() {
this.socket1 = new DuplexSocket();
this.socket2 = new DuplexSocket();
this.socket1[kOtherSide] = this.socket2;
this.socket2[kOtherSide] = this.socket1;
}
}
module.exports = DuplexPair;