From 0c73221699168268f4c3f5430693c0eb16e57e85 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 10 Nov 2018 21:09:42 +0100 Subject: [PATCH] tls: do not rely on 'drain' handlers in StreamWrap `'drain'` event handlers may not be invoked if the stream is currently finishing. Instead, use the fact that we know when writes are active or not, and invoke the delayed shutdown handler from our own after-write callback. PR-URL: https://github.com/nodejs/node/pull/24290 Refs: https://github.com/nodejs/node/pull/24288 Refs: https://github.com/nodejs/node/pull/24075 Reviewed-By: James M Snell Reviewed-By: Daniel Bevenius Reviewed-By: Ouyang Yadong --- lib/internal/wrap_js_stream.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/internal/wrap_js_stream.js b/lib/internal/wrap_js_stream.js index 7ca7ff8bf49d25..cf8f45aa4505ff 100644 --- a/lib/internal/wrap_js_stream.js +++ b/lib/internal/wrap_js_stream.js @@ -11,6 +11,7 @@ const { ERR_STREAM_WRAP } = require('internal/errors').codes; const kCurrentWriteRequest = Symbol('kCurrentWriteRequest'); const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest'); +const kPendingShutdownRequest = Symbol('kPendingShutdownRequest'); function isClosing() { return this[owner_symbol].isClosing(); } function onreadstart() { return this[owner_symbol].readStart(); } @@ -79,6 +80,7 @@ class JSStreamWrap extends Socket { this.stream = stream; this[kCurrentWriteRequest] = null; this[kCurrentShutdownRequest] = null; + this[kPendingShutdownRequest] = null; this.readable = stream.readable; this.writable = stream.writable; @@ -115,8 +117,10 @@ class JSStreamWrap extends Socket { // Working around that on the native side is not quite trivial (yet?), // so for now that is supported here. - if (this[kCurrentWriteRequest] !== null) - return this.once('drain', () => this.doShutdown(req)); + if (this[kCurrentWriteRequest] !== null) { + this[kPendingShutdownRequest] = req; + return 0; + } assert.strictEqual(this[kCurrentWriteRequest], null); assert.strictEqual(this[kCurrentShutdownRequest], null); this[kCurrentShutdownRequest] = req; @@ -189,6 +193,11 @@ class JSStreamWrap extends Socket { this[kCurrentWriteRequest] = null; handle.finishWrite(req, errCode); + if (this[kPendingShutdownRequest]) { + const req = this[kPendingShutdownRequest]; + this[kPendingShutdownRequest] = null; + this.doShutdown(req); + } } doClose(cb) {