Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit fdc9d83

Browse files
committed
Address PR feedback
1 parent ddc7fdf commit fdc9d83

File tree

3 files changed

+26
-23
lines changed

3 files changed

+26
-23
lines changed

src/System.IO.Pipes/src/System.IO.Pipes.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@
131131
<Compile Include="System\IO\Pipes\ConnectionCompletionSource.cs" />
132132
<Compile Include="System\IO\Pipes\NamedPipeClientStream.Windows.cs" />
133133
<Compile Include="System\IO\Pipes\NamedPipeServerStream.Windows.cs" />
134+
<Compile Include="System\IO\Pipes\PipeIOCompletionSource.cs" />
134135
<Compile Include="System\IO\Pipes\PipeStream.Windows.cs" />
135-
<Compile Include="System\IO\Pipes\PipeStreamCompletionSource.cs" />
136136
</ItemGroup>
137137
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' ">
138138
<Compile Include="Microsoft\Win32\SafeHandles\SafePipeHandle.Unix.cs" />

src/System.IO.Pipes/src/System/IO/Pipes/PipeStreamCompletionSource.cs renamed to src/System.IO.Pipes/src/System/IO/Pipes/PipeIOCompletionSource.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace System.IO.Pipes
1111
{
12-
// TODO: consolidate logic between PipeStreamCompletionSource and ConnectionCompletionSource
12+
// TODO: consolidate logic between PipeIOCompletionSource and ConnectionCompletionSource
1313
internal sealed unsafe class PipeStreamCompletionSource : TaskCompletionSource<int>
1414
{
1515
private const int NoResult = 0;
@@ -18,12 +18,12 @@ internal sealed unsafe class PipeStreamCompletionSource : TaskCompletionSource<i
1818
private const int RegisteringCancellation = 4;
1919
private const int CompletedCallback = 8;
2020

21+
private readonly CancellationToken _cancellationToken;
2122
private readonly bool _isWrite;
2223
private readonly PipeStream _pipeStream;
2324
private readonly ThreadPoolBoundHandle _threadPoolBinding;
2425

2526
private CancellationTokenRegistration _cancellationRegistration;
26-
private CancellationToken _cancellationToken;
2727
private int _errorCode;
2828
private bool _isMessageComplete;
2929
private int _numBytes; // number of buffer read OR written
@@ -134,7 +134,6 @@ private void AsyncCallback(uint errorCode, uint numBytes)
134134
case Interop.mincore.Errors.ERROR_PIPE_NOT_CONNECTED:
135135
case Interop.mincore.Errors.ERROR_NO_DATA:
136136
errorCode = 0;
137-
numBytes = 0;
138137
break;
139138
}
140139
}
@@ -170,12 +169,9 @@ private void AsyncCallback(uint errorCode, uint numBytes)
170169

171170
private void Cancel()
172171
{
173-
// Storing to locals to avoid data races
174172
SafeHandle handle = _threadPoolBinding.Handle;
175173
NativeOverlapped* overlapped = Overlapped;
176174

177-
Debug.Assert(overlapped != null && !Task.IsCompleted, "IO should not have completed yet");
178-
179175
// If the handle is still valid, attempt to cancel the IO
180176
if (!handle.IsInvalid)
181177
{

src/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace System.IO.Pipes
1313
{
1414
public abstract partial class PipeStream : Stream
1515
{
16-
private static readonly Task<int> ZeroTask = Task.FromResult(0);
16+
private static readonly Task<int> s_zeroTask = Task.FromResult(0);
1717
internal const bool CheckOperationsRequiresSetHandle = true;
1818
internal ThreadPoolBoundHandle _threadPoolBinding;
1919

@@ -296,7 +296,7 @@ public virtual PipeTransmissionMode ReadMode
296296
// -----------------------------
297297

298298
[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)
300300
{
301301
Debug.Assert(_handle != null, "_handle is null");
302302
Debug.Assert(!_handle.IsClosed, "_handle is closed");
@@ -306,8 +306,6 @@ private unsafe Task WriteAsyncCorePrivate(byte[] buffer, int offset, int count,
306306
Debug.Assert(offset >= 0, "offset is negative");
307307
Debug.Assert(count >= 0, "count is negative");
308308

309-
// fixed doesn't work well with zero length arrays. Set the zero-byte flag in case
310-
// caller needs to do any cleanup
311309
if (buffer.Length == 0)
312310
{
313311
return Task.CompletedTask;
@@ -318,7 +316,11 @@ private unsafe Task WriteAsyncCorePrivate(byte[] buffer, int offset, int count,
318316
int errorCode = 0;
319317

320318
// 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+
}
322324

323325
// WriteFile, the OS version, will return 0 on failure, but this WriteFileNative
324326
// wrapper returns -1. This will return the following:
@@ -443,7 +445,7 @@ private unsafe int WriteFileNative(SafePipeHandle handle, byte[] buffer, int off
443445
}
444446

445447
[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)
447449
{
448450
Debug.Assert(_handle != null, "_handle is null");
449451
Debug.Assert(!_handle.IsClosed, "_handle is closed");
@@ -453,20 +455,22 @@ private unsafe Task<int> ReadAsyncCorePrivate(byte[] buffer, int offset, int cou
453455
Debug.Assert(offset >= 0, "offset is negative");
454456
Debug.Assert(count >= 0, "count is negative");
455457

456-
// handle zero-length buffers separately; fixed keyword ReadFileNative doesn't like
457-
// 0-length buffers. Call user callback and we're done
458458
if (buffer.Length == 0)
459459
{
460460
UpdateMessageCompletion(false);
461-
return ZeroTask;
461+
return s_zeroTask;
462462
}
463463
else
464464
{
465465
var completionSource = new PipeStreamCompletionSource(this, buffer, cancellationToken, isWrite: false);
466466

467467
// Queue an async ReadFile operation and pass in a packed overlapped
468468
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+
}
470474

471475
// ReadFile, the OS version, will return 0 on failure, but this ReadFileNative wrapper
472476
// returns -1. This will return the following:
@@ -487,13 +491,16 @@ private unsafe Task<int> ReadAsyncCorePrivate(byte[] buffer, int offset, int cou
487491
case Interop.mincore.Errors.ERROR_PIPE_NOT_CONNECTED:
488492
State = PipeState.Broken;
489493

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+
493501
completionSource.ReleaseResources();
494-
completionSource.SetCompletedSynchronously();
495502
UpdateMessageCompletion(true);
496-
return ZeroTask;
503+
return s_zeroTask;
497504

498505
case Interop.mincore.Errors.ERROR_IO_PENDING:
499506
break;
@@ -525,7 +532,7 @@ internal void UpdateMessageCompletion(bool completion)
525532
{
526533
// Set message complete to true because the pipe is broken as well.
527534
// Need this to signal to readers to stop reading.
528-
_isMessageComplete = (_state == PipeState.Broken || completion);
535+
_isMessageComplete = (completion || _state == PipeState.Broken);
529536
}
530537

531538
/// <summary>

0 commit comments

Comments
 (0)