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: https://github.com/nodejs/node/pull/9066 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
This commit is contained in:
Родитель
0ed6338016
Коммит
31196eaa93
|
@ -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.
|
||||
|
|
|
@ -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' ]);
|
||||
});
|
Загрузка…
Ссылка в новой задаче