You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Added asserts to send buffer helper
* Postpone confirming the last RECEIVE event until the data are read
* Removed lock
* Debug tests
* ReadsClosed test fixed, and some better logging
* Final task keep alive, abort order, timeout for graceful write-side shutdown in dispose, named constants
* Tests
* Always wait for SEND_COMPLETE
* Exclude BigPayload on platforms where it can OOM
* Removed unintended code changes
* Reverted postponing reading FIN, if data have chance to get buffered with FIN, we will do that.
* Clean ups
* Fixed waiting for SEND_COMPLETE
* Hold back setting FinalTaskSource and overwrite result if no waiter is there
* Cancellation and completion
* Comments, fixed FinalTaskSource
* Fix assert
* Test reseting control stream made more resilient
* Attempt to fix still running write while disposing the stream in case of a cancellation
* Attempt to fix stress build
* Sync Dispose in H3Stream waits for read and write as well
privateTask?_sendRequestTask;// Set with SendContentAsync, must be awaited before QuicStream.DisposeAsync();
35
+
privateTask?_readResponseTask;// Set with ReadResponseAsync, must be awaited before QuicStream.DisposeAsync();
34
36
35
37
// Allocated when we receive a :status header.
36
38
privateHttpResponseMessage?_response;
@@ -88,9 +90,25 @@ public void Dispose()
88
90
{
89
91
_disposed=true;
90
92
AbortStream();
93
+
// We aborted both sides, thus both task should unblock and should be finished before disposing the QuicStream.
94
+
WaitUnfinished(_sendRequestTask);
95
+
WaitUnfinished(_readResponseTask);
91
96
_stream.Dispose();
92
97
DisposeSyncHelper();
93
98
}
99
+
100
+
staticvoidWaitUnfinished(Task?task)
101
+
{
102
+
if(taskis not null&&!task.IsCompleted)
103
+
{
104
+
try
105
+
{
106
+
task.GetAwaiter().GetResult();
107
+
}
108
+
catch// Exceptions from both tasks are logged via _connection.LogException() in case they're not awaited in SendAsync, so the exception can be ignored here.
109
+
{}
110
+
}
111
+
}
94
112
}
95
113
96
114
privatevoidRemoveFromConnectionIfDone()
@@ -107,9 +125,25 @@ public async ValueTask DisposeAsync()
107
125
{
108
126
_disposed=true;
109
127
AbortStream();
128
+
// We aborted both sides, thus both task should unblock and should be finished before disposing the QuicStream.
catch// Exceptions from both tasks are logged via _connection.LogException() in case they're not awaited in SendAsync, so the exception can be ignored here.
144
+
{}
145
+
}
146
+
}
113
147
}
114
148
115
149
privatevoidDisposeSyncHelper()
@@ -158,52 +192,51 @@ public async Task<HttpResponseMessage> SendAsync(CancellationToken cancellationT
0 commit comments