0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-30 07:27:22 +01:00
nodejs/test/common/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

50 lines
1.2 KiB
JavaScript

/* eslint-disable node-core/require-common-first, node-core/required-modules */
'use strict';
const { Duplex } = require('stream');
const assert = require('assert');
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) {
assert.notStrictEqual(this[kOtherSide], null);
assert.strictEqual(this[kOtherSide][kCallback], null);
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);
}
}
function makeDuplexPair() {
const clientSide = new DuplexSocket();
const serverSide = new DuplexSocket();
clientSide[kOtherSide] = serverSide;
serverSide[kOtherSide] = clientSide;
return { clientSide, serverSide };
}
module.exports = makeDuplexPair;