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

Commit 59c5b6a

Browse files
committed
Merge pull request #1974 from stephentoub/named_pipes_overlapped
Remove remaining Overlapped usage from System.IO.Pipes
2 parents 5a0d58a + 29122a4 commit 59c5b6a

File tree

3 files changed

+15
-30
lines changed

3 files changed

+15
-30
lines changed

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

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,6 @@ public String GetImpersonationUserName()
159159
// ---- PAL layer ends here ----
160160
// -----------------------------
161161

162-
[SecurityCritical]
163-
private unsafe static readonly IOCompletionCallback s_WaitForConnectionCallback =
164-
new IOCompletionCallback(NamedPipeServerStream.AsyncWaitForConnectionCallback);
165-
166162
#if RunAs
167163
// This method calls a delegate while impersonating the client. Note that we will not have
168164
// access to the client's security token until it has written at least once to the pipe
@@ -263,7 +259,7 @@ private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Objec
263259
// Create and store async stream class library specific data in the
264260
// async result
265261
PipeAsyncResult asyncResult = new PipeAsyncResult();
266-
asyncResult._handle = InternalHandle;
262+
asyncResult._threadPoolBinding = _threadPoolBinding;
267263
asyncResult._userCallback = callback;
268264
asyncResult._userStateObject = state;
269265

@@ -273,16 +269,17 @@ private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Objec
273269
ManualResetEvent waitHandle = new ManualResetEvent(false);
274270
asyncResult._waitHandle = waitHandle;
275271

276-
// Create a managed overlapped class
277-
// We will set the file offsets later
278-
Overlapped overlapped = new Overlapped();
279-
overlapped.OffsetLow = 0;
280-
overlapped.OffsetHigh = 0;
281-
overlapped.AsyncResult = asyncResult;
282-
283-
// Pack the Overlapped class, and store it in the async result
284-
NativeOverlapped* intOverlapped = overlapped.Pack(s_WaitForConnectionCallback, null);
272+
NativeOverlapped* intOverlapped = _threadPoolBinding.AllocateNativeOverlapped((errorCode, numBytes, pOverlapped) =>
273+
{
274+
// Unpack overlapped, free the pinned overlapped, and complete the operation
275+
PipeAsyncResult ar = (PipeAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
276+
Debug.Assert(ar._overlapped == pOverlapped);
277+
ar._threadPoolBinding.FreeNativeOverlapped(pOverlapped);
278+
ar._overlapped = null;
279+
AsyncWaitForConnectionCallback(errorCode, numBytes, ar);
280+
}, asyncResult, null);
285281
asyncResult._overlapped = intOverlapped;
282+
286283
if (!Interop.mincore.ConnectNamedPipe(InternalHandle, intOverlapped))
287284
{
288285
int errorCode = Marshal.GetLastWin32Error();
@@ -298,7 +295,7 @@ private unsafe IAsyncResult BeginWaitForConnection(AsyncCallback callback, Objec
298295

299296
// WaitForConnectionCallback will not be called because we completed synchronously.
300297
// Either the pipe is already connected, or there was an error. Unpin and free the overlapped again.
301-
Overlapped.Free(intOverlapped);
298+
_threadPoolBinding.FreeNativeOverlapped(intOverlapped);
302299
asyncResult._overlapped = null;
303300

304301
// Did the client already connect to us?
@@ -398,19 +395,8 @@ private unsafe void EndWaitForConnection(IAsyncResult asyncResult)
398395

399396
// Callback to be called by the OS when completing the async WaitForConnection operation.
400397
[SecurityCritical]
401-
unsafe private static void AsyncWaitForConnectionCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped)
398+
unsafe private static void AsyncWaitForConnectionCallback(uint errorCode, uint numBytes, PipeAsyncResult asyncResult)
402399
{
403-
// Unpack overlapped
404-
Overlapped overlapped = Overlapped.Unpack(pOverlapped);
405-
406-
// Extract async result from overlapped
407-
PipeAsyncResult asyncResult = (PipeAsyncResult)overlapped.AsyncResult;
408-
409-
// Free the pinned overlapped:
410-
Debug.Assert(asyncResult._overlapped == pOverlapped);
411-
Overlapped.Free(pOverlapped);
412-
asyncResult._overlapped = null;
413-
414400
// Special case for when the client has already connected to us.
415401
if (errorCode == Interop.mincore.Errors.ERROR_PIPE_CONNECTED)
416402
{

src/System.IO.Pipes/src/System/IO/Pipes/PipeAsyncResult.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ namespace System.IO.Pipes
99
{
1010
internal unsafe sealed class PipeAsyncResult : IAsyncResult
1111
{
12+
internal ThreadPoolBoundHandle _threadPoolBinding;
1213
internal AsyncCallback _userCallback; // User code callback
1314
internal Object _userStateObject;
1415
internal ManualResetEvent _waitHandle;
1516
[SecurityCritical]
16-
internal SafePipeHandle _handle;
17-
[SecurityCritical]
1817
internal NativeOverlapped* _overlapped;
1918

2019
internal int _EndXxxCalled; // Whether we've called EndXxx already.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace System.IO.Pipes
1515
public abstract partial class PipeStream : Stream
1616
{
1717
internal const bool CheckOperationsRequiresSetHandle = true;
18-
private ThreadPoolBoundHandle _threadPoolBinding;
18+
internal ThreadPoolBoundHandle _threadPoolBinding;
1919

2020
internal static string GetPipePath(string serverName, string pipeName)
2121
{

0 commit comments

Comments
 (0)