@@ -13,7 +13,7 @@ namespace System.IO.Pipes
13
13
{
14
14
public abstract partial class PipeStream : Stream
15
15
{
16
- private static readonly Task < int > ZeroTask = Task . FromResult ( 0 ) ;
16
+ private static readonly Task < int > s_zeroTask = Task . FromResult ( 0 ) ;
17
17
internal const bool CheckOperationsRequiresSetHandle = true ;
18
18
internal ThreadPoolBoundHandle _threadPoolBinding ;
19
19
@@ -296,7 +296,7 @@ public virtual PipeTransmissionMode ReadMode
296
296
// -----------------------------
297
297
298
298
[ SecurityCritical ]
299
- private unsafe Task WriteAsyncCorePrivate ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
299
+ private Task WriteAsyncCorePrivate ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
300
300
{
301
301
Debug . Assert ( _handle != null , "_handle is null" ) ;
302
302
Debug . Assert ( ! _handle . IsClosed , "_handle is closed" ) ;
@@ -306,8 +306,6 @@ private unsafe Task WriteAsyncCorePrivate(byte[] buffer, int offset, int count,
306
306
Debug . Assert ( offset >= 0 , "offset is negative" ) ;
307
307
Debug . Assert ( count >= 0 , "count is negative" ) ;
308
308
309
- // fixed doesn't work well with zero length arrays. Set the zero-byte flag in case
310
- // caller needs to do any cleanup
311
309
if ( buffer . Length == 0 )
312
310
{
313
311
return Task . CompletedTask ;
@@ -318,7 +316,11 @@ private unsafe Task WriteAsyncCorePrivate(byte[] buffer, int offset, int count,
318
316
int errorCode = 0 ;
319
317
320
318
// Queue an async WriteFile operation and pass in a packed overlapped
321
- int r = WriteFileNative ( _handle , buffer , offset , count , completionSource . Overlapped , out errorCode ) ;
319
+ int r ;
320
+ unsafe
321
+ {
322
+ r = WriteFileNative ( _handle , buffer , offset , count , completionSource . Overlapped , out errorCode ) ;
323
+ }
322
324
323
325
// WriteFile, the OS version, will return 0 on failure, but this WriteFileNative
324
326
// wrapper returns -1. This will return the following:
@@ -443,7 +445,7 @@ private unsafe int WriteFileNative(SafePipeHandle handle, byte[] buffer, int off
443
445
}
444
446
445
447
[ SecurityCritical ]
446
- private unsafe Task < int > ReadAsyncCorePrivate ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
448
+ private Task < int > ReadAsyncCorePrivate ( byte [ ] buffer , int offset , int count , CancellationToken cancellationToken )
447
449
{
448
450
Debug . Assert ( _handle != null , "_handle is null" ) ;
449
451
Debug . Assert ( ! _handle . IsClosed , "_handle is closed" ) ;
@@ -453,20 +455,22 @@ private unsafe Task<int> ReadAsyncCorePrivate(byte[] buffer, int offset, int cou
453
455
Debug . Assert ( offset >= 0 , "offset is negative" ) ;
454
456
Debug . Assert ( count >= 0 , "count is negative" ) ;
455
457
456
- // handle zero-length buffers separately; fixed keyword ReadFileNative doesn't like
457
- // 0-length buffers. Call user callback and we're done
458
458
if ( buffer . Length == 0 )
459
459
{
460
460
UpdateMessageCompletion ( false ) ;
461
- return ZeroTask ;
461
+ return s_zeroTask ;
462
462
}
463
463
else
464
464
{
465
465
var completionSource = new PipeStreamCompletionSource ( this , buffer , cancellationToken , isWrite : false ) ;
466
466
467
467
// Queue an async ReadFile operation and pass in a packed overlapped
468
468
int errorCode = 0 ;
469
- int r = ReadFileNative ( _handle , buffer , offset , count , completionSource . Overlapped , out errorCode ) ;
469
+ int r ;
470
+ unsafe
471
+ {
472
+ r = ReadFileNative ( _handle , buffer , offset , count , completionSource . Overlapped , out errorCode ) ;
473
+ }
470
474
471
475
// ReadFile, the OS version, will return 0 on failure, but this ReadFileNative wrapper
472
476
// returns -1. This will return the following:
@@ -487,13 +491,16 @@ private unsafe Task<int> ReadAsyncCorePrivate(byte[] buffer, int offset, int cou
487
491
case Interop . mincore . Errors . ERROR_PIPE_NOT_CONNECTED :
488
492
State = PipeState . Broken ;
489
493
490
- // Clear the overlapped status bit for this special case. Failure to do so looks
491
- // like we are freeing a pending overlapped.
492
- completionSource . Overlapped ->InternalLow = IntPtr . Zero ;
494
+ unsafe
495
+ {
496
+ // Clear the overlapped status bit for this special case. Failure to do so looks
497
+ // like we are freeing a pending overlapped.
498
+ completionSource . Overlapped ->InternalLow = IntPtr . Zero ;
499
+ }
500
+
493
501
completionSource . ReleaseResources ( ) ;
494
- completionSource . SetCompletedSynchronously ( ) ;
495
502
UpdateMessageCompletion ( true ) ;
496
- return ZeroTask ;
503
+ return s_zeroTask ;
497
504
498
505
case Interop . mincore . Errors . ERROR_IO_PENDING :
499
506
break ;
@@ -525,7 +532,7 @@ internal void UpdateMessageCompletion(bool completion)
525
532
{
526
533
// Set message complete to true because the pipe is broken as well.
527
534
// Need this to signal to readers to stop reading.
528
- _isMessageComplete = ( _state == PipeState . Broken || completion ) ;
535
+ _isMessageComplete = ( completion || _state == PipeState . Broken ) ;
529
536
}
530
537
531
538
/// <summary>
0 commit comments