Skip to content

Commit 0f1a22d

Browse files
indutnyMyles Borins
authored and
Myles Borins
committed
net: fix ambiguity in EOF handling
`end` MUST always be emitted **before** `close`. However, if a handle will invoke `uv_close_cb` immediately, or in the same JS tick - `close` may be emitted first. PR-URL: #9066 Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ilkka Myller <[email protected]>
1 parent cbfde3c commit 0f1a22d

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

lib/net.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -571,14 +571,16 @@ function onread(nread, buffer) {
571571

572572
debug('EOF');
573573

574+
// push a null to signal the end of data.
575+
// Do it before `maybeDestroy` for correct order of events:
576+
// `end` -> `close`
577+
self.push(null);
578+
574579
if (self._readableState.length === 0) {
575580
self.readable = false;
576581
maybeDestroy(self);
577582
}
578583

579-
// push a null to signal the end of data.
580-
self.push(null);
581-
582584
// internal end event so that we know that the actual socket
583585
// is no longer readable, and we can start the shutdown
584586
// procedure. No need to wait for all the data to be consumed.

test/parallel/test-net-end-close.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const net = require('net');
5+
6+
const uv = process.binding('uv');
7+
8+
const s = new net.Socket({
9+
handle: {
10+
readStart: function() {
11+
process.nextTick(() => this.onread(uv.UV_EOF, null));
12+
},
13+
close: (cb) => process.nextTick(cb)
14+
},
15+
writable: false
16+
});
17+
s.resume();
18+
19+
const events = [];
20+
21+
s.on('end', () => events.push('end'));
22+
s.on('close', () => events.push('close'));
23+
24+
process.on('exit', () => {
25+
assert.deepStrictEqual(events, [ 'end', 'close' ]);
26+
});

0 commit comments

Comments
 (0)