Skip to content

Commit 3d38bab

Browse files
addaleaxrvagg
authored andcommitted
net: use _final instead of on('finish')
Shutting down the connection is what `_final` is there for. PR-URL: #18608 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 0bef960 commit 3d38bab

File tree

4 files changed

+39
-17
lines changed

4 files changed

+39
-17
lines changed

lib/internal/streams/destroy.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ function undestroy() {
5555
this._writableState.destroyed = false;
5656
this._writableState.ended = false;
5757
this._writableState.ending = false;
58+
this._writableState.finalCalled = false;
59+
this._writableState.prefinished = false;
5860
this._writableState.finished = false;
5961
this._writableState.errorEmitted = false;
6062
}

lib/net.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ function Socket(options) {
229229
}
230230

231231
// shut down the socket when we're finished with it.
232-
this.on('finish', onSocketFinish);
233232
this.on('_socketEnd', onSocketEnd);
234233

235234
initSocketHandle(this);
@@ -273,39 +272,42 @@ Socket.prototype._unrefTimer = function _unrefTimer() {
273272

274273
function shutdownSocket(self, callback) {
275274
var req = new ShutdownWrap();
276-
req.oncomplete = callback;
275+
req.oncomplete = afterShutdown;
277276
req.handle = self._handle;
277+
req.callback = callback;
278278
return self._handle.shutdown(req);
279279
}
280280

281281
// the user has called .end(), and all the bytes have been
282282
// sent out to the other side.
283-
function onSocketFinish() {
284-
// If still connecting - defer handling 'finish' until 'connect' will happen
283+
Socket.prototype._final = function(cb) {
284+
// If still connecting - defer handling `_final` until 'connect' will happen
285285
if (this.connecting) {
286-
debug('osF: not yet connected');
287-
return this.once('connect', onSocketFinish);
286+
debug('_final: not yet connected');
287+
return this.once('connect', () => this._final(cb));
288288
}
289289

290-
debug('onSocketFinish');
291290
if (!this.readable || this._readableState.ended) {
292-
debug('oSF: ended, destroy', this._readableState);
291+
debug('_final: ended, destroy', this._readableState);
292+
cb();
293293
return this.destroy();
294294
}
295295

296-
debug('oSF: not ended, call shutdown()');
296+
debug('_final: not ended, call shutdown()');
297297

298298
// otherwise, just shutdown, or destroy() if not possible
299-
if (!this._handle || !this._handle.shutdown)
299+
if (!this._handle || !this._handle.shutdown) {
300+
cb();
300301
return this.destroy();
302+
}
301303

302304
var err = defaultTriggerAsyncIdScope(
303-
this[async_id_symbol], shutdownSocket, this, afterShutdown
305+
this[async_id_symbol], shutdownSocket, this, cb
304306
);
305307

306308
if (err)
307309
return this.destroy(errnoException(err, 'shutdown'));
308-
}
310+
};
309311

310312

311313
function afterShutdown(status, handle, req) {
@@ -314,6 +316,8 @@ function afterShutdown(status, handle, req) {
314316
debug('afterShutdown destroyed=%j', self.destroyed,
315317
self._readableState);
316318

319+
this.callback();
320+
317321
// callback may come after call to destroy.
318322
if (self.destroyed)
319323
return;

test/async-hooks/test-shutdownwrap.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ let endedConnection = false;
2424
function onconnection(c) {
2525
assert.strictEqual(hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 0);
2626
c.end();
27-
endedConnection = true;
28-
const as = hooks.activitiesOfTypes('SHUTDOWNWRAP');
29-
assert.strictEqual(as.length, 1);
30-
checkInvocations(as[0], { init: 1 }, 'after ending client connection');
31-
this.close(onserverClosed);
27+
process.nextTick(() => {
28+
endedConnection = true;
29+
const as = hooks.activitiesOfTypes('SHUTDOWNWRAP');
30+
assert.strictEqual(as.length, 1);
31+
checkInvocations(as[0], { init: 1 }, 'after ending client connection');
32+
this.close(onserverClosed);
33+
});
3234
}
3335

3436
function onconnected() {

test/parallel/test-stream-writable-destroy.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,17 @@ const { inherits } = require('util');
185185
assert.strictEqual(expected, err);
186186
}));
187187
}
188+
189+
{
190+
// Checks that `._undestroy()` restores the state so that `final` will be
191+
// called again.
192+
const write = new Writable({
193+
write: common.mustNotCall(),
194+
final: common.mustCall((cb) => cb(), 2)
195+
});
196+
197+
write.end();
198+
write.destroy();
199+
write._undestroy();
200+
write.end();
201+
}

0 commit comments

Comments
 (0)