Skip to content

Commit

Permalink
net: fix ambiguity in EOF handling
Browse files Browse the repository at this point in the history
`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.
  • Loading branch information
indutny committed Oct 12, 2016
1 parent 47d1588 commit 6e38e76
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -574,14 +574,16 @@ function onread(nread, buffer) {

debug('EOF');

// push a null to signal the end of data.
// Do it before `maybeDestroy` for correct order of events:
// `end` -> `close`
self.push(null);

if (self._readableState.length === 0) {
self.readable = false;
maybeDestroy(self);
}

// push a null to signal the end of data.
self.push(null);

// internal end event so that we know that the actual socket
// is no longer readable, and we can start the shutdown
// procedure. No need to wait for all the data to be consumed.
Expand Down
26 changes: 26 additions & 0 deletions test/parallel/test-net-end-close.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';
require('../common');
const assert = require('assert');
const net = require('net');

const uv = process.binding('uv');

const s = new net.Socket({
handle: {
readStart: function() {
process.nextTick(() => this.onread(uv.UV_EOF, null));
},
close: (cb) => process.nextTick(cb)
},
writable: false
});
s.resume();

const events = [];

s.on('end', () => events.push('end'));
s.on('close', () => events.push('close'));

process.on('exit', () => {
assert.deepStrictEqual(events, [ 'end', 'close' ]);
});

0 comments on commit 6e38e76

Please sign in to comment.