@@ -13,15 +13,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.NamedPipes.Internal;
13
13
14
14
internal sealed class NamedPipeConnection : TransportConnection , IConnectionNamedPipeFeature
15
15
{
16
+ private static readonly ConnectionAbortedException SendGracefullyCompletedException = new ConnectionAbortedException ( "The named pipe transport's send loop completed gracefully." ) ;
16
17
private const int MinAllocBufferSize = 4096 ;
17
-
18
+ private readonly NamedPipeConnectionListener _connectionListener ;
18
19
private readonly NamedPipeServerStream _stream ;
19
20
private readonly ILogger _log ;
20
21
private readonly IDuplexPipe _originalTransport ;
21
22
22
23
private readonly CancellationTokenSource _connectionClosedTokenSource = new CancellationTokenSource ( ) ;
23
24
private bool _connectionClosed ;
24
- private bool _connectionDisposed ;
25
+ private bool _connectionShutdown ;
26
+ private bool _streamDisconnected ;
25
27
private Exception ? _shutdownReason ;
26
28
private readonly object _shutdownLock = new object ( ) ;
27
29
@@ -30,13 +32,15 @@ internal sealed class NamedPipeConnection : TransportConnection, IConnectionName
30
32
internal Task _sendingTask = Task . CompletedTask ;
31
33
32
34
public NamedPipeConnection (
35
+ NamedPipeConnectionListener connectionListener ,
33
36
NamedPipeServerStream stream ,
34
37
NamedPipeEndPoint endPoint ,
35
38
ILogger logger ,
36
39
MemoryPool < byte > memoryPool ,
37
40
PipeOptions inputOptions ,
38
41
PipeOptions outputOptions )
39
42
{
43
+ _connectionListener = connectionListener ;
40
44
_stream = stream ;
41
45
_log = logger ;
42
46
MemoryPool = memoryPool ;
@@ -120,7 +124,7 @@ private async Task DoReceiveAsync()
120
124
// This exception should always be ignored because _shutdownReason should be set.
121
125
error = ex ;
122
126
123
- if ( ! _connectionDisposed )
127
+ if ( ! _connectionShutdown )
124
128
{
125
129
// This is unexpected if the socket hasn't been disposed yet.
126
130
NamedPipeLog . ConnectionError ( _log , this , error ) ;
@@ -206,33 +210,32 @@ private void Shutdown(Exception? shutdownReason)
206
210
{
207
211
lock ( _shutdownLock )
208
212
{
209
- if ( _connectionDisposed )
213
+ if ( _connectionShutdown )
210
214
{
211
215
return ;
212
216
}
213
217
214
218
// Make sure to close the connection only after the _aborted flag is set.
215
219
// Without this, the RequestsCanBeAbortedMidRead test will sometimes fail when
216
220
// a BadHttpRequestException is thrown instead of a TaskCanceledException.
217
- _connectionDisposed = true ;
221
+ _connectionShutdown = true ;
218
222
219
223
// shutdownReason should only be null if the output was completed gracefully, so no one should ever
220
224
// ever observe the nondescript ConnectionAbortedException except for connection middleware attempting
221
225
// to half close the connection which is currently unsupported.
222
- _shutdownReason = shutdownReason ?? new ConnectionAbortedException ( "The Socket transport's send loop completed gracefully." ) ;
226
+ _shutdownReason = shutdownReason ?? SendGracefullyCompletedException ;
223
227
NamedPipeLog . ConnectionDisconnect ( _log , this , _shutdownReason . Message ) ;
224
228
225
229
try
226
230
{
227
231
// Try to gracefully close the socket even for aborts to match libuv behavior.
228
232
_stream . Disconnect ( ) ;
233
+ _streamDisconnected = true ;
229
234
}
230
235
catch
231
236
{
232
237
// Ignore any errors from NamedPipeStream.Disconnect() since we're tearing down the connection anyway.
233
238
}
234
-
235
- _stream . Dispose ( ) ;
236
239
}
237
240
}
238
241
@@ -287,8 +290,13 @@ public override async ValueTask DisposeAsync()
287
290
catch ( Exception ex )
288
291
{
289
292
_log . LogError ( 0 , ex , $ "Unexpected exception in { nameof ( NamedPipeConnection ) } .{ nameof ( Start ) } .") ;
293
+ _stream . Dispose ( ) ;
294
+ return ;
295
+ }
296
+
297
+ if ( ! _streamDisconnected || ! _connectionListener . TryCacheStream ( _stream ) )
298
+ {
299
+ _stream . Dispose ( ) ;
290
300
}
291
-
292
- await _stream . DisposeAsync ( ) ;
293
301
}
294
302
}
0 commit comments