Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 1afd207

Browse filesBrowse files
oyydMylesBorins
authored andcommitted
tls: make StreamWrap work correctly in "drain" callback
When an instance of StreamWrap is shutting down and a "drain" event is emitted, the instance will abort as its `this[kCurrentShutdownRequest]` is already set. The following test will fail before this commit. PR-URL: #23294 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
1 parent 2564abf commit 1afd207
Copy full SHA for 1afd207

File tree

Expand file treeCollapse file tree

2 files changed

+51
-4
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+51
-4
lines changed
Open diff view settings
Collapse file

‎lib/internal/wrap_js_stream.js‎

Copy file name to clipboardExpand all lines: lib/internal/wrap_js_stream.js
+3-4Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,6 @@ class JSStreamWrap extends Socket {
100100
}
101101

102102
doShutdown(req) {
103-
assert.strictEqual(this[kCurrentShutdownRequest], null);
104-
this[kCurrentShutdownRequest] = req;
105-
106103
// TODO(addaleax): It might be nice if we could get into a state where
107104
// DoShutdown() is not called on streams while a write is still pending.
108105
//
@@ -113,8 +110,10 @@ class JSStreamWrap extends Socket {
113110
// so for now that is supported here.
114111

115112
if (this[kCurrentWriteRequest] !== null)
116-
return this.on('drain', () => this.doShutdown(req));
113+
return this.once('drain', () => this.doShutdown(req));
117114
assert.strictEqual(this[kCurrentWriteRequest], null);
115+
assert.strictEqual(this[kCurrentShutdownRequest], null);
116+
this[kCurrentShutdownRequest] = req;
118117

119118
const handle = this._handle;
120119

Collapse file
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { StreamWrap } = require('_stream_wrap');
5+
const { Duplex } = require('stream');
6+
const { ShutdownWrap } = process.binding('stream_wrap');
7+
8+
// This test makes sure that when an instance of JSStreamWrap is waiting for
9+
// a "drain" event to `doShutdown`, the instance will work correctly when a
10+
// "drain" event emitted.
11+
{
12+
let resolve = null;
13+
14+
class TestDuplex extends Duplex {
15+
_write(chunk, encoding, callback) {
16+
// We will resolve the write later.
17+
resolve = () => {
18+
callback();
19+
};
20+
}
21+
22+
_read() {}
23+
}
24+
25+
const testDuplex = new TestDuplex();
26+
const socket = new StreamWrap(testDuplex);
27+
28+
socket.write(
29+
// Make the buffer long enough so that the `Writable` will emit "drain".
30+
Buffer.allocUnsafe(socket.writableHighWaterMark * 2),
31+
common.mustCall()
32+
);
33+
34+
// Make sure that the 'drain' events will be emitted.
35+
testDuplex.on('drain', common.mustCall(() => {
36+
console.log('testDuplex drain');
37+
}));
38+
39+
assert.strictEqual(typeof resolve, 'function');
40+
41+
const req = new ShutdownWrap();
42+
req.oncomplete = common.mustCall();
43+
req.handle = socket._handle;
44+
// Should not throw.
45+
socket._handle.shutdown(req);
46+
47+
resolve();
48+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.