Skip to content

Commit f6adcb7

Browse files
committed
Revise implementation of IValueTaskSources
Better match implementation in RandomAccess
1 parent b024fb8 commit f6adcb7

File tree

7 files changed

+269
-445
lines changed

7 files changed

+269
-445
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@
102102
<Compile Include="System\IO\Pipes\PipeAuditRule.cs" />
103103
<Compile Include="System\IO\Pipes\PipesAclExtensions.cs" />
104104
<Compile Include="System\IO\Pipes\PipeSecurity.cs" />
105-
<Compile Include="System\IO\Pipes\PipeStream.ConnectionValueTaskSource.cs" />
106-
<Compile Include="System\IO\Pipes\PipeStream.ReadWriteValueTaskSource.cs" />
107105
<Compile Include="System\IO\Pipes\PipeStream.ValueTaskSource.cs" />
108106
<Compile Include="System\IO\Pipes\PipeStream.Windows.cs" />
109107
</ItemGroup>

src/libraries/System.IO.Pipes/src/System/IO/Pipes/NamedPipeServerStream.Windows.cs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5-
using System.Diagnostics.CodeAnalysis;
6-
using System.Runtime.CompilerServices;
5+
using System.Runtime.ExceptionServices;
76
using System.Runtime.InteropServices;
87
using System.Security.AccessControl;
98
using System.Security.Principal;
@@ -55,7 +54,7 @@ protected override void Dispose(bool disposing)
5554
}
5655
}
5756

58-
internal override void TryToReuse<TResult>(PipeValueTaskSource<TResult> source)
57+
internal override void TryToReuse(PipeValueTaskSource source)
5958
{
6059
base.TryToReuse(source);
6160

@@ -324,53 +323,49 @@ internal ExecuteHelper(PipeStreamImpersonationWorker userCode, SafePipeHandle? h
324323
private unsafe ValueTask WaitForConnectionCoreAsync(CancellationToken cancellationToken)
325324
{
326325
CheckConnectOperationsServerWithHandle();
326+
Debug.Assert(IsAsync);
327327

328-
if (!IsAsync)
329-
{
330-
throw new InvalidOperationException(SR.InvalidOperation_PipeNotAsync);
331-
}
332-
333-
var valueTaskSource = Interlocked.Exchange(ref _reusableConnectionValueTaskSource, null) ?? new ConnectionValueTaskSource(this);
328+
ConnectionValueTaskSource? vts = Interlocked.Exchange(ref _reusableConnectionValueTaskSource, null) ?? new ConnectionValueTaskSource(this);
334329
try
335330
{
336-
valueTaskSource.PrepareForOperation();
337-
if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, valueTaskSource.Overlapped))
331+
vts.PrepareForOperation();
332+
if (!Interop.Kernel32.ConnectNamedPipe(InternalHandle!, vts._overlapped))
338333
{
339334
int errorCode = Marshal.GetLastPInvokeError();
340-
341335
switch (errorCode)
342336
{
343337
case Interop.Errors.ERROR_IO_PENDING:
344-
valueTaskSource.RegisterForCancellation(cancellationToken);
338+
// Common case: IO was initiated, completion will be handled by callback.
339+
// Register for cancellation now that the operation has been initiated.
340+
vts.RegisterForCancellation(cancellationToken);
345341
break;
346342

347-
// If we are here then the pipe is already connected, or there was an error
348-
// so we should unpin and free the overlapped.
349343
case Interop.Errors.ERROR_PIPE_CONNECTED:
344+
// If we are here then the pipe is already connected.
350345
// IOCompletitionCallback will not be called because we completed synchronously.
351-
valueTaskSource.Dispose();
346+
vts.Dispose();
352347
if (State == PipeState.Connected)
353348
{
354-
throw new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected);
349+
return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(new InvalidOperationException(SR.InvalidOperation_PipeAlreadyConnected)));
355350
}
356-
valueTaskSource.SetCompletedSynchronously();
357-
358-
// We return a cached task instead of TaskCompletionSource's Task allowing the GC to collect it.
351+
State = PipeState.Connected;
359352
return ValueTask.CompletedTask;
360353

361354
default:
362-
valueTaskSource.Dispose();
363-
return ValueTask.FromException(Win32Marshal.GetExceptionForWin32Error(errorCode));
355+
vts.Dispose();
356+
return ValueTask.FromException(ExceptionDispatchInfo.SetCurrentStackTrace(Win32Marshal.GetExceptionForWin32Error(errorCode)));
364357
}
365358
}
366359
}
367360
catch
368361
{
369-
valueTaskSource.Dispose();
362+
vts.Dispose();
370363
throw;
371364
}
372365

373-
return new ValueTask(valueTaskSource, valueTaskSource.Version);
366+
// Completion handled by callback.
367+
vts.FinishedScheduling();
368+
return new ValueTask(vts, vts.Version);
374369
}
375370

376371
private void CheckConnectOperationsServerWithHandle()

src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.ConnectionValueTaskSource.cs

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.ReadWriteValueTaskSource.cs

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)