Skip to content

Commit 9a192a9

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 4de7a6e commit 9a192a9

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
@@ -560,14 +560,16 @@ function onread(nread, buffer) {
560560

561561
debug('EOF');
562562

563+
// push a null to signal the end of data.
564+
// Do it before `maybeDestroy` for correct order of events:
565+
// `end` -> `close`
566+
self.push(null);
567+
563568
if (self._readableState.length === 0) {
564569
self.readable = false;
565570
maybeDestroy(self);
566571
}
567572

568-
// push a null to signal the end of data.
569-
self.push(null);
570-
571573
// internal end event so that we know that the actual socket
572574
// is no longer readable, and we can start the shutdown
573575
// 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)