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 authored and cjihrig committed Jul 22, 2020
1 parent 4eb0b3f commit 8864a64
Showing 1 changed file with 19 additions and 18 deletions.
37 changes: 19 additions & 18 deletions lib/internal/quic/core.js
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 8864a64

Please sign in to comment.