Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/src/System/Threading/Overlapped.cs')
-rw-r--r--src/System.Private.CoreLib/src/System/Threading/Overlapped.cs305
1 files changed, 123 insertions, 182 deletions
diff --git a/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs
index 787436965..0a1c2ce72 100644
--- a/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs
+++ b/src/System.Private.CoreLib/src/System/Threading/Overlapped.cs
@@ -19,73 +19,63 @@
**
=============================================================================*/
+using System.Diagnostics;
using System.Runtime;
using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Runtime.Versioning;
-using System.Security;
-using System.Runtime.ConstrainedExecution;
-using System.Diagnostics;
-using System.Collections.Concurrent;
-
using Internal.Runtime.CompilerServices;
namespace System.Threading
{
#region class _IOCompletionCallback
- internal class _IOCompletionCallback
+ internal unsafe class _IOCompletionCallback
{
private IOCompletionCallback _ioCompletionCallback;
private ExecutionContext _executionContext;
private uint _errorCode; // Error code
private uint _numBytes; // No. of bytes transferred
- private unsafe NativeOverlapped* _pOVERLAP;
+ private NativeOverlapped* _pNativeOverlapped;
- internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback)
+ internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, ExecutionContext executionContext)
{
_ioCompletionCallback = ioCompletionCallback;
- _executionContext = ExecutionContext.Capture();
+ _executionContext = executionContext;
}
- private static ContextCallback s_ccb = new ContextCallback(IOCompletionCallback_Context);
-
- private static unsafe void IOCompletionCallback_Context(Object state)
+ // Context callback: same sig for SendOrPostCallback and ContextCallback
+ internal static ContextCallback s_ccb = new ContextCallback(IOCompletionCallback_Context);
+ private static void IOCompletionCallback_Context(object state)
{
_IOCompletionCallback helper = (_IOCompletionCallback)state;
Debug.Assert(helper != null, "_IOCompletionCallback cannot be null");
- helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pOVERLAP);
+ helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pNativeOverlapped);
}
- internal static unsafe void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP)
+ internal static unsafe void PerformIOCompletionCallback(uint errorCode, uint numBytes, NativeOverlapped* pNativeOverlapped)
{
- Overlapped overlapped;
- _IOCompletionCallback helper;
-
do
{
- overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
- helper = overlapped.iocbHelper;
+ OverlappedData overlapped = OverlappedData.GetOverlappedFromNative(pNativeOverlapped);
- if (helper == null || helper._executionContext == null || helper._executionContext == ExecutionContext.Default)
+ if (overlapped._callback is IOCompletionCallback iocb)
{
- // We got here because of UnsafePack (or) Pack with EC flow supressed
- IOCompletionCallback callback = overlapped.UserCallback;
- callback(errorCode, numBytes, pOVERLAP);
+ // We got here because of UnsafePack (or) Pack with EC flow suppressed
+ iocb(errorCode, numBytes, pNativeOverlapped);
}
else
{
// We got here because of Pack
+ var helper = (_IOCompletionCallback)overlapped._callback;
helper._errorCode = errorCode;
helper._numBytes = numBytes;
- helper._pOVERLAP = pOVERLAP;
+ helper._pNativeOverlapped = pNativeOverlapped;
ExecutionContext.Run(helper._executionContext, s_ccb, helper);
}
//Quickly check the VM again, to see if a packet has arrived.
//OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);
- pOVERLAP = null;
- } while (pOVERLAP != null);
+ pNativeOverlapped = null;
+ } while (pNativeOverlapped != null);
}
}
@@ -93,115 +83,100 @@ namespace System.Threading
#region class OverlappedData
- internal sealed class OverlappedData
+ internal unsafe sealed class OverlappedData
{
- // The offset of m_nativeOverlapped field from m_pEEType
- private static int s_nativeOverlappedOffset;
-
- internal IAsyncResult m_asyncResult;
- internal IOCompletionCallback m_iocb;
- internal _IOCompletionCallback m_iocbHelper;
- internal Overlapped m_overlapped;
- private Object m_userObject;
- private IntPtr m_pinSelf;
- private GCHandle[] m_pinnedData;
- internal NativeOverlapped m_nativeOverlapped;
-
- // Adding an empty default ctor for annotation purposes
- internal OverlappedData() { }
-
- ~OverlappedData()
+ internal IAsyncResult _asyncResult;
+ internal object _callback; // IOCompletionCallback or _IOCompletionCallback
+ internal Overlapped _overlapped;
+ private object _userObject;
+ private NativeOverlapped * _pNativeOverlapped;
+ private IntPtr _eventHandle;
+ private int _offsetLow;
+ private int _offsetHigh;
+ private GCHandle[] _pinnedData;
+
+ internal ref IAsyncResult AsyncResult => ref _asyncResult;
+
+ internal ref int OffsetLow => ref (_pNativeOverlapped != null) ? ref _pNativeOverlapped->OffsetLow : ref _offsetLow;
+ internal ref int OffsetHigh => ref (_pNativeOverlapped != null) ? ref _pNativeOverlapped->OffsetHigh : ref _offsetHigh;
+ internal ref IntPtr EventHandle => ref (_pNativeOverlapped != null) ? ref _pNativeOverlapped->EventHandle : ref _eventHandle;
+
+ internal unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, object userData)
{
- if (m_pinnedData != null)
+ if (_pNativeOverlapped != null)
{
- for (int i = 0; i < m_pinnedData.Length; i++)
- {
- if (m_pinnedData[i].IsAllocated)
- {
- m_pinnedData[i].Free();
- }
- }
+ throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
}
- }
-
- internal void ReInitialize()
- {
- m_asyncResult = null;
- m_iocb = null;
- m_iocbHelper = null;
- m_overlapped = null;
- m_userObject = null;
- Debug.Assert(m_pinSelf == IntPtr.Zero, "OverlappedData has not been freed: m_pinSelf");
- m_pinSelf = IntPtr.Zero;
- // Reuse m_pinnedData array
- m_nativeOverlapped = default(NativeOverlapped);
- }
- internal unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData)
- {
- if (m_pinSelf != IntPtr.Zero)
+ if (iocb != null)
{
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
+ ExecutionContext ec = ExecutionContext.Capture();
+ _callback = (ec != null && !ec.IsDefault) ? new _IOCompletionCallback(iocb, ec) : (object)iocb;
}
- m_iocb = iocb;
- m_iocbHelper = (iocb != null) ? new _IOCompletionCallback(iocb) : null;
- m_userObject = userData;
+ else
+ {
+ _callback = null;
+ }
+ _userObject = userData;
return AllocateNativeOverlapped();
}
- internal unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData)
+ internal unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData)
{
- if (m_pinSelf != IntPtr.Zero)
+ if (_pNativeOverlapped != null)
{
throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
}
- m_iocb = iocb;
- m_iocbHelper = null;
- m_userObject = userData;
+ _userObject = userData;
+ _callback = iocb;
return AllocateNativeOverlapped();
}
- internal IntPtr UserHandle
- {
- get { return m_nativeOverlapped.EventHandle; }
- set { m_nativeOverlapped.EventHandle = value; }
- }
-
private unsafe NativeOverlapped* AllocateNativeOverlapped()
{
- if (m_userObject != null)
+ Debug.Assert(_pinnedData == null);
+
+ bool success = false;
+ try
{
- if (m_userObject.GetType() == typeof(Object[]))
+ if (_userObject != null)
{
- Object[] objArray = (Object[])m_userObject;
- if (m_pinnedData == null || m_pinnedData.Length < objArray.Length)
- Array.Resize(ref m_pinnedData, objArray.Length);
+ if (_userObject.GetType() == typeof(object[]))
+ {
+ object[] objArray = (object[])_userObject;
- for (int i = 0; i < objArray.Length; i++)
+ _pinnedData = new GCHandle[objArray.Length];
+ for (int i = 0; i < objArray.Length; i++)
+ {
+ _pinnedData[i] = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
+ }
+ }
+ else
{
- if (!m_pinnedData[i].IsAllocated)
- m_pinnedData[i] = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
- else
- m_pinnedData[i].Target = objArray[i];
+ _pinnedData = new GCHandle[1];
+ _pinnedData[0] = GCHandle.Alloc(_userObject, GCHandleType.Pinned);
}
}
- else
- {
- if (m_pinnedData == null || m_pinnedData.Length < 1)
- m_pinnedData = new GCHandle[1];
- if (!m_pinnedData[0].IsAllocated)
- m_pinnedData[0] = GCHandle.Alloc(m_userObject, GCHandleType.Pinned);
- else
- m_pinnedData[0].Target = m_userObject;
- }
- }
+ NativeOverlapped* pNativeOverlapped = (NativeOverlapped*)Interop.MemAlloc((UIntPtr)(sizeof(NativeOverlapped) + sizeof(GCHandle)));
+ *(GCHandle*)(pNativeOverlapped + 1) = default(GCHandle);
+ _pNativeOverlapped = pNativeOverlapped;
+
+ _pNativeOverlapped->InternalLow = default;
+ _pNativeOverlapped->InternalHigh = default;
+ _pNativeOverlapped->OffsetLow = _offsetLow;
+ _pNativeOverlapped->OffsetHigh = _offsetHigh;
+ _pNativeOverlapped->EventHandle = _eventHandle;
- m_pinSelf = RuntimeImports.RhHandleAlloc(this, GCHandleType.Pinned);
+ *(GCHandle*)(_pNativeOverlapped + 1) = GCHandle.Alloc(this);
- fixed (NativeOverlapped* pNativeOverlapped = &m_nativeOverlapped)
+ success = true;
+ return _pNativeOverlapped;
+ }
+ finally
{
- return pNativeOverlapped;
+ if (!success)
+ FreeNativeOverlapped();
}
}
@@ -213,47 +188,33 @@ namespace System.Threading
private void FreeNativeOverlapped()
{
- IntPtr pinSelf = m_pinSelf;
- if (pinSelf != IntPtr.Zero)
+ if (_pinnedData != null)
{
- if (Interlocked.CompareExchange(ref m_pinSelf, IntPtr.Zero, pinSelf) == pinSelf)
+ for (int i = 0; i < _pinnedData.Length; i++)
{
- if (m_pinnedData != null)
+ if (_pinnedData[i].IsAllocated)
{
- for (int i = 0; i < m_pinnedData.Length; i++)
- {
- if (m_pinnedData[i].IsAllocated && (m_pinnedData[i].Target != null))
- {
- m_pinnedData[i].Target = null;
- }
- }
+ _pinnedData[i].Free();
}
-
- RuntimeImports.RhHandleFree(pinSelf);
}
+ _pinnedData = null;
}
- }
- internal static unsafe OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr)
- {
- if (s_nativeOverlappedOffset == 0)
+ if (_pNativeOverlapped != null)
{
- CalculateNativeOverlappedOffset();
- }
+ GCHandle handle = *(GCHandle*)(_pNativeOverlapped + 1);
+ if (handle.IsAllocated)
+ handle.Free();
- void* pOverlappedData = (byte*)nativeOverlappedPtr - s_nativeOverlappedOffset;
- return Unsafe.Read<OverlappedData>(&pOverlappedData);
+ Interop.MemFree((IntPtr)_pNativeOverlapped);
+ _pNativeOverlapped = null;
+ }
}
- private static unsafe void CalculateNativeOverlappedOffset()
+ internal static unsafe OverlappedData GetOverlappedFromNative(NativeOverlapped* pNativeOverlapped)
{
- OverlappedData overlappedData = new OverlappedData();
-
- fixed (IntPtr* pEETypePtr = &overlappedData.m_pEEType)
- fixed (NativeOverlapped* pNativeOverlapped = &overlappedData.m_nativeOverlapped)
- {
- s_nativeOverlappedOffset = (int)((byte*)pNativeOverlapped - (byte*)pEETypePtr);
- }
+ GCHandle handle = *(GCHandle*)(pNativeOverlapped + 1);
+ return (OverlappedData)handle.Target;
}
}
@@ -263,24 +224,20 @@ namespace System.Threading
public class Overlapped
{
- private static PinnableBufferCache s_overlappedDataCache = new PinnableBufferCache("System.Threading.OverlappedData", () => new OverlappedData());
-
- private OverlappedData m_overlappedData;
+ private OverlappedData _overlappedData;
public Overlapped()
{
- m_overlappedData = (OverlappedData)s_overlappedDataCache.Allocate();
- m_overlappedData.m_overlapped = this;
+ _overlappedData = new OverlappedData();
+ _overlappedData._overlapped = this;
}
- public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar)
+ public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar) : this()
{
- m_overlappedData = (OverlappedData)s_overlappedDataCache.Allocate();
- m_overlappedData.m_overlapped = this;
- m_overlappedData.m_nativeOverlapped.OffsetLow = offsetLo;
- m_overlappedData.m_nativeOverlapped.OffsetHigh = offsetHi;
- m_overlappedData.UserHandle = hEvent;
- m_overlappedData.m_asyncResult = ar;
+ _overlappedData.OffsetLow = offsetLo;
+ _overlappedData.OffsetHigh = offsetHi;
+ _overlappedData.EventHandle = hEvent;
+ _overlappedData.AsyncResult = ar;
}
[Obsolete("This constructor is not 64-bit compatible. Use the constructor that takes an IntPtr for the event handle. http://go.microsoft.com/fwlink/?linkid=14202")]
@@ -290,43 +247,33 @@ namespace System.Threading
public IAsyncResult AsyncResult
{
- get { return m_overlappedData.m_asyncResult; }
- set { m_overlappedData.m_asyncResult = value; }
+ get { return _overlappedData.AsyncResult; }
+ set { _overlappedData.AsyncResult = value; }
}
public int OffsetLow
{
- get { return m_overlappedData.m_nativeOverlapped.OffsetLow; }
- set { m_overlappedData.m_nativeOverlapped.OffsetLow = value; }
+ get { return _overlappedData.OffsetLow; }
+ set { _overlappedData.OffsetLow = value; }
}
public int OffsetHigh
{
- get { return m_overlappedData.m_nativeOverlapped.OffsetHigh; }
- set { m_overlappedData.m_nativeOverlapped.OffsetHigh = value; }
+ get { return _overlappedData.OffsetHigh; }
+ set { _overlappedData.OffsetHigh = value; }
}
[Obsolete("This property is not 64-bit compatible. Use EventHandleIntPtr instead. http://go.microsoft.com/fwlink/?linkid=14202")]
public int EventHandle
{
- get { return m_overlappedData.UserHandle.ToInt32(); }
- set { m_overlappedData.UserHandle = new IntPtr(value); }
+ get { return EventHandleIntPtr.ToInt32(); }
+ set { EventHandleIntPtr = new IntPtr(value); }
}
public IntPtr EventHandleIntPtr
{
- get { return m_overlappedData.UserHandle; }
- set { m_overlappedData.UserHandle = value; }
- }
-
- internal _IOCompletionCallback iocbHelper
- {
- get { return m_overlappedData.m_iocbHelper; }
- }
-
- internal IOCompletionCallback UserCallback
- {
- get { return m_overlappedData.m_iocb; }
+ get { return _overlappedData.EventHandle; }
+ set { _overlappedData.EventHandle = value; }
}
/*====================================================================
@@ -342,9 +289,9 @@ namespace System.Threading
}
[CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData)
+ public unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, object userData)
{
- return m_overlappedData.Pack(iocb, userData);
+ return _overlappedData.Pack(iocb, userData);
}
[Obsolete("This method is not safe. Use UnsafePack (iocb, userData) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
@@ -355,9 +302,9 @@ namespace System.Threading
}
[CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData)
+ public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData)
{
- return m_overlappedData.UnsafePack(iocb, userData);
+ return _overlappedData.UnsafePack(iocb, userData);
}
/*====================================================================
@@ -370,9 +317,7 @@ namespace System.Threading
if (nativeOverlappedPtr == null)
throw new ArgumentNullException(nameof(nativeOverlappedPtr));
- Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;
-
- return overlapped;
+ return OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped;
}
[CLSCompliant(false)]
@@ -381,14 +326,10 @@ namespace System.Threading
if (nativeOverlappedPtr == null)
throw new ArgumentNullException(nameof(nativeOverlappedPtr));
- Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;
+ OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped._overlappedData = null;
OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
- OverlappedData overlappedData = overlapped.m_overlappedData;
- overlapped.m_overlappedData = null;
- overlappedData.ReInitialize();
- s_overlappedDataCache.Free(overlappedData);
}
}
#endregion class Overlapped
-} // namespace
+}