@@ -673,15 +673,23 @@ function submitShutdown(options) {
673
673
}
674
674
675
675
function finishSessionDestroy ( socket ) {
676
+ const state = this [ kState ] ;
677
+ if ( state . destroyed )
678
+ return ;
679
+
676
680
if ( ! socket . destroyed )
677
681
socket . destroy ( ) ;
678
682
683
+ state . destroying = false ;
684
+ state . destroyed = true ;
685
+
679
686
// Destroy the handle
680
687
const handle = this [ kHandle ] ;
681
688
if ( handle !== undefined ) {
682
- handle . destroy ( ) ;
689
+ handle . destroy ( state . skipUnconsume ) ;
683
690
debug ( `[${ sessionName ( this [ kType ] ) } ] nghttp2session handle destroyed` ) ;
684
691
}
692
+ this [ kHandle ] = undefined ;
685
693
686
694
process . nextTick ( emit . bind ( this , 'close' ) ) ;
687
695
debug ( `[${ sessionName ( this [ kType ] ) } ] nghttp2session destroyed` ) ;
@@ -825,7 +833,7 @@ class Http2Session extends EventEmitter {
825
833
826
834
// Submits a SETTINGS frame to be sent to the remote peer.
827
835
settings ( settings ) {
828
- if ( this [ kState ] . destroyed )
836
+ if ( this [ kState ] . destroyed || this [ kState ] . destroying )
829
837
throw new errors . Error ( 'ERR_HTTP2_INVALID_SESSION' ) ;
830
838
831
839
// Validate the input first
@@ -871,7 +879,7 @@ class Http2Session extends EventEmitter {
871
879
872
880
// Submits a PRIORITY frame to be sent to the remote peer.
873
881
priority ( stream , options ) {
874
- if ( this [ kState ] . destroyed )
882
+ if ( this [ kState ] . destroyed || this [ kState ] . destroying )
875
883
throw new errors . Error ( 'ERR_HTTP2_INVALID_SESSION' ) ;
876
884
877
885
if ( ! ( stream instanceof Http2Stream ) ) {
@@ -905,6 +913,8 @@ class Http2Session extends EventEmitter {
905
913
// Submits an RST-STREAM frame to be sent to the remote peer. This will
906
914
// cause the stream to be closed.
907
915
rstStream ( stream , code = NGHTTP2_NO_ERROR ) {
916
+ // Do not check destroying here, as the rstStream may be sent while
917
+ // the session is in the middle of being destroyed.
908
918
if ( this [ kState ] . destroyed )
909
919
throw new errors . Error ( 'ERR_HTTP2_INVALID_SESSION' ) ;
910
920
@@ -946,7 +956,6 @@ class Http2Session extends EventEmitter {
946
956
const state = this [ kState ] ;
947
957
if ( state . destroyed || state . destroying )
948
958
return ;
949
-
950
959
debug ( `[${ sessionName ( this [ kType ] ) } ] destroying nghttp2session` ) ;
951
960
state . destroying = true ;
952
961
@@ -963,8 +972,8 @@ class Http2Session extends EventEmitter {
963
972
delete this [ kSocket ] ;
964
973
delete this [ kServer ] ;
965
974
966
- state . destroyed = true ;
967
- state . destroying = false ;
975
+ state . destroyed = false ;
976
+ state . destroying = true ;
968
977
969
978
if ( this [ kHandle ] !== undefined )
970
979
this [ kHandle ] . destroying ( ) ;
@@ -975,7 +984,7 @@ class Http2Session extends EventEmitter {
975
984
// Graceful or immediate shutdown of the Http2Session. Graceful shutdown
976
985
// is only supported on the server-side
977
986
shutdown ( options , callback ) {
978
- if ( this [ kState ] . destroyed )
987
+ if ( this [ kState ] . destroyed || this [ kState ] . destroying )
979
988
throw new errors . Error ( 'ERR_HTTP2_INVALID_SESSION' ) ;
980
989
981
990
if ( this [ kState ] . shutdown || this [ kState ] . shuttingDown )
@@ -1037,7 +1046,7 @@ class Http2Session extends EventEmitter {
1037
1046
}
1038
1047
1039
1048
_onTimeout ( ) {
1040
- this . emit ( 'timeout' ) ;
1049
+ process . nextTick ( emit . bind ( this , 'timeout' ) ) ;
1041
1050
}
1042
1051
}
1043
1052
@@ -1061,7 +1070,7 @@ class ClientHttp2Session extends Http2Session {
1061
1070
// Submits a new HTTP2 request to the connected peer. Returns the
1062
1071
// associated Http2Stream instance.
1063
1072
request ( headers , options ) {
1064
- if ( this [ kState ] . destroyed )
1073
+ if ( this [ kState ] . destroyed || this [ kState ] . destroying )
1065
1074
throw new errors . Error ( 'ERR_HTTP2_INVALID_SESSION' ) ;
1066
1075
debug ( `[${ sessionName ( this [ kType ] ) } ] initiating request` ) ;
1067
1076
_unrefActive ( this ) ;
@@ -1317,7 +1326,7 @@ class Http2Stream extends Duplex {
1317
1326
}
1318
1327
1319
1328
_onTimeout ( ) {
1320
- this . emit ( 'timeout' ) ;
1329
+ process . nextTick ( emit . bind ( this , 'timeout' ) ) ;
1321
1330
}
1322
1331
1323
1332
// true if the Http2Stream was aborted abornomally.
@@ -2104,7 +2113,7 @@ const onTimeout = {
2104
2113
configurable : false ,
2105
2114
enumerable : false ,
2106
2115
value : function ( ) {
2107
- this . emit ( 'timeout' ) ;
2116
+ process . nextTick ( emit . bind ( this , 'timeout' ) ) ;
2108
2117
}
2109
2118
} ;
2110
2119
@@ -2191,20 +2200,22 @@ function socketOnError(error) {
2191
2200
// of the session.
2192
2201
function socketOnTimeout ( ) {
2193
2202
debug ( 'socket timeout' ) ;
2194
- const server = this [ kServer ] ;
2195
- const session = this [ kSession ] ;
2196
- // If server or session are undefined, then we're already in the process of
2197
- // shutting down, do nothing.
2198
- if ( server === undefined || session === undefined )
2199
- return ;
2200
- if ( ! server . emit ( 'timeout' , session , this ) ) {
2201
- session . shutdown (
2202
- {
2203
- graceful : true ,
2204
- errorCode : NGHTTP2_NO_ERROR
2205
- } ,
2206
- this . destroy . bind ( this ) ) ;
2207
- }
2203
+ process . nextTick ( ( ) => {
2204
+ const server = this [ kServer ] ;
2205
+ const session = this [ kSession ] ;
2206
+ // If server or session are undefined, then we're already in the process of
2207
+ // shutting down, do nothing.
2208
+ if ( server === undefined || session === undefined )
2209
+ return ;
2210
+ if ( ! server . emit ( 'timeout' , session , this ) ) {
2211
+ session . shutdown (
2212
+ {
2213
+ graceful : true ,
2214
+ errorCode : NGHTTP2_NO_ERROR
2215
+ } ,
2216
+ this . destroy . bind ( this ) ) ;
2217
+ }
2218
+ } ) ;
2208
2219
}
2209
2220
2210
2221
// Handles the on('stream') event for a session and forwards
@@ -2346,6 +2357,8 @@ function setupCompat(ev) {
2346
2357
function socketOnClose ( hadError ) {
2347
2358
const session = this [ kSession ] ;
2348
2359
if ( session !== undefined && ! session . destroyed ) {
2360
+ // Skip unconsume because the socket is destroyed.
2361
+ session [ kState ] . skipUnconsume = true ;
2349
2362
session . destroy ( ) ;
2350
2363
}
2351
2364
}
0 commit comments