Skip to content

Commit

Permalink
quic: fixup kEndpointClose
Browse files Browse the repository at this point in the history
Ensure that the QuicSocket is properly destroyed if the QuicEndpoint
is destroyed directly rather than through QuicSocket destroy

PR-URL: #34283
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information
jasnell committed Jul 16, 2020
1 parent 9f552df commit e5d963e
Showing 1 changed file with 19 additions and 18 deletions.
37 changes: 19 additions & 18 deletions lib/internal/quic/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,6 @@ class QuicSocket extends EventEmitter {
});
}

// Called when a QuicEndpoint closes
[kEndpointClose](endpoint, error) {
const state = this[kInternalState];
state.endpoints.delete(endpoint);
Expand All @@ -1064,26 +1063,15 @@ class QuicSocket extends EventEmitter {
}
});

// If there are no more QuicEndpoints, the QuicSocket is no
// longer usable.
// If there aren't any more endpoints, the QuicSession
// is no longer usable and needs to be destroyed.
if (state.endpoints.size === 0) {
for (const session of state.sessions)
session.destroy(error);

if (error) process.nextTick(emit.bind(this, 'error', error));
process.nextTick(emit.bind(this, 'close'));
if (!this.destroyed)
return this.destroy(error);
this[kDestroy](error);
}
}

// kDestroy is called to actually free the QuicSocket resources and
// cause the error and close events to be emitted.
[kDestroy](error) {
// The QuicSocket will be destroyed once all QuicEndpoints
// are destroyed. See [kEndpointClose].
for (const endpoint of this[kInternalState].endpoints)
endpoint.destroy(error);
}

// kMaybeDestroy is called one or more times after the close() method
// is called. The QuicSocket will be destroyed if there are no remaining
// open sessions.
Expand Down Expand Up @@ -1463,7 +1451,20 @@ class QuicSocket extends EventEmitter {
for (const session of state.sessions)
session.destroy(error);

this[kDestroy](error);
// If there aren't any QuicEndpoints to clean up, skip
// directly to the end to emit the error and close events.
if (state.endpoints.size === 0)
return this[kDestroy](error);

// Otherwise, the QuicSocket will be destroyed once all
// QuicEndpoints are destroyed. See [kEndpointClose].
for (const endpoint of state.endpoints)
endpoint.destroy(error);
}

[kDestroy](error) {
if (error) process.nextTick(emit.bind(this, 'error', error));
process.nextTick(emit.bind(this, 'close'));
}

ref() {
Expand Down

0 comments on commit e5d963e

Please sign in to comment.