@@ -43,6 +43,11 @@ typedef union QUIC_CONNECTION_STATE {
4343 BOOLEAN Partitioned : 1 ; // The connection cannot move across partitions.
4444 BOOLEAN CloseAsync : 1 ; // The connection will close without waiting for callbacks.
4545
46+ //
47+ // The connection's ref count has hit zero, but needs to be cleaned up on a worker.
48+ //
49+ BOOLEAN CleanupStarted : 1 ;
50+
4651 //
4752 // Indicates whether packet number encryption is enabled or not for the
4853 // connection.
@@ -1088,7 +1093,15 @@ QuicConnAddRef(
10881093 UNREFERENCED_PARAMETER (Ref );
10891094#endif
10901095
1091- CxPlatRefIncrement (& Connection -> RefCount );
1096+ if (!Connection -> State .CleanupStarted ) {
1097+ CxPlatRefIncrement (& Connection -> RefCount );
1098+ } else {
1099+ //
1100+ // When the connection is in the cleanup state, the only caller allowed
1101+ // to touch it is a worker thread.
1102+ //
1103+ CXPLAT_DBG_ASSERT (Ref == QUIC_CONN_REF_WORKER );
1104+ }
10921105}
10931106
10941107//
@@ -1113,24 +1126,19 @@ QuicConnRelease(
11131126 UNREFERENCED_PARAMETER (Ref );
11141127#endif
11151128
1116- CXPLAT_DBG_ASSERT (Connection -> RefCount > 0 );
1117- if (CxPlatRefDecrement (& Connection -> RefCount )) {
1129+ if (Connection -> State .CleanupStarted || CxPlatRefDecrement (& Connection -> RefCount )) {
11181130#if DEBUG
11191131 for (uint32_t i = 0 ; i < QUIC_CONN_REF_COUNT ; i ++ ) {
11201132 CXPLAT_TEL_ASSERT (Connection -> RefTypeBiasedCount [i ] == 1 );
11211133 }
11221134#endif
11231135 if (Ref == QUIC_CONN_REF_LOOKUP_RESULT ) {
1124- //
1125- // The ref count has hit zero and we need to reset to 1 to avoid
1126- // hitting an assert when the next reference is taken.
1127- //
1128- CxPlatRefInitialize (& Connection -> RefCount );
11291136 //
11301137 // Lookup results cannot be the last ref, as they can result in the
11311138 // datapath binding being deleted on a callback. Instead, queue the
11321139 // connection to be released by the worker.
11331140 //
1141+ Connection -> State .CleanupStarted = TRUE;
11341142 CXPLAT_DBG_ASSERT (Connection -> Worker != NULL );
11351143 QuicWorkerQueueConnection (Connection -> Worker , Connection );
11361144 } else {
0 commit comments