@@ -41,7 +41,6 @@ public void Initialize(Http2StreamContext context)
41
41
{
42
42
base . Initialize ( context ) ;
43
43
44
- CanReuse = false ;
45
44
_decrementCalled = false ;
46
45
_completionState = StreamCompletionFlags . None ;
47
46
InputRemaining = null ;
@@ -107,7 +106,16 @@ public bool ReceivedEmptyRequestBody
107
106
}
108
107
}
109
108
110
- public bool CanReuse { get ; private set ; }
109
+ // We only want to reuse a stream that was not aborted and has completely finished writing.
110
+ // This ensures Http2OutputProducer.ProcessDataWrites is in the correct state to be reused.
111
+
112
+ // CanReuse must be evaluated on the main frame-processing looping after the stream is removed
113
+ // from the connection's active streams collection. This is required because a RST_STREAM
114
+ // frame could arrive after the END_STREAM flag is received. Only once the stream is removed
115
+ // from the connection's active stream collection can no longer be reset, and is safe to
116
+ // evaluate for pooling.
117
+
118
+ public bool CanReuse => ! _connectionAborted && HasResponseCompleted ;
111
119
112
120
protected override void OnReset ( )
113
121
{
@@ -164,9 +172,6 @@ public void CompleteStream(bool errored)
164
172
// connection's flow-control window.
165
173
_inputFlowControl . Abort ( ) ;
166
174
167
- // We only want to reuse a stream that was not aborted and has completely finished writing.
168
- // This ensures Http2OutputProducer.ProcessDataWrites is in the correct state to be reused.
169
- CanReuse = ! _connectionAborted && HasResponseCompleted ;
170
175
}
171
176
finally
172
177
{
0 commit comments