From cbbf64e40e6a544f14f1d2888c41464e3a5acfab 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 7ca7ff8bf49..cf8f45aa450 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) {