diff options
Diffstat (limited to 'src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs')
-rw-r--r-- | src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs b/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs new file mode 100644 index 0000000000..1aea2a294b --- /dev/null +++ b/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Threading +{ + /// <summary> + /// Overlapped subclass adding data needed by ThreadPoolBoundHandle. + /// </summary> + internal sealed class ThreadPoolBoundHandleOverlapped : Overlapped + { + private static readonly unsafe IOCompletionCallback s_completionCallback = CompletionCallback; + + private readonly IOCompletionCallback _userCallback; + internal readonly object _userState; + internal PreAllocatedOverlapped _preAllocated; + internal unsafe NativeOverlapped* _nativeOverlapped; + internal ThreadPoolBoundHandle _boundHandle; + internal bool _completed; + + public unsafe ThreadPoolBoundHandleOverlapped(IOCompletionCallback callback, object state, object pinData, PreAllocatedOverlapped preAllocated) + { + _userCallback = callback; + _userState = state; + _preAllocated = preAllocated; + + _nativeOverlapped = Pack(s_completionCallback, pinData); + _nativeOverlapped->OffsetLow = 0; // CLR reuses NativeOverlapped instances and does not reset these + _nativeOverlapped->OffsetHigh = 0; + } + + private unsafe static void CompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped) + { + ThreadPoolBoundHandleOverlapped overlapped = (ThreadPoolBoundHandleOverlapped)Overlapped.Unpack(nativeOverlapped); + + // + // The Win32 thread pool implementation of ThreadPoolBoundHandle does not permit reuse of NativeOverlapped + // pointers without freeing them and allocating new a new one. We need to ensure that code using the CLR + // ThreadPool implementation follows those rules. + // + if (overlapped._completed) + throw new InvalidOperationException(SR.InvalidOperation_NativeOverlappedReused); + + overlapped._completed = true; + + if (overlapped._boundHandle == null) + throw new InvalidOperationException(SR.Argument_NativeOverlappedAlreadyFree); + + overlapped._userCallback(errorCode, numBytes, nativeOverlapped); + } + } +} |