diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
index 8f27f79fc5cc67..95a1f9ddb8b47e 100644
--- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -1,4 +1,4 @@
-
+
false
@@ -237,7 +237,6 @@
-
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Overlapped.cs
deleted file mode 100644
index 141aa3a7290791..00000000000000
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Overlapped.cs
+++ /dev/null
@@ -1,204 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-//
-
-/*
- * This files defines the following types:
- * - _IOCompletionCallback
- * - OverlappedData
- * - Overlapped
- */
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Class for converting information to and from the native
-** overlapped structure used in asynchronous file i/o
-**
-**
-=============================================================================*/
-
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-
-namespace System.Threading
-{
- #region class OverlappedData
-
- internal sealed unsafe class OverlappedData
- {
- // ! If you make any change to the layout here, you need to make matching change
- // ! to OverlappedDataObject in vm\nativeoverlapped.h
- internal IAsyncResult? _asyncResult;
- internal object? _callback; // IOCompletionCallback or _IOCompletionCallback
- internal readonly Overlapped _overlapped;
- private object? _userObject;
- private readonly NativeOverlapped* _pNativeOverlapped;
- private IntPtr _eventHandle;
- private int _offsetLow;
- private int _offsetHigh;
-
- internal OverlappedData(Overlapped overlapped) => _overlapped = overlapped;
-
- 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 NativeOverlapped* Pack(IOCompletionCallback? iocb, object? userData)
- {
- if (_pNativeOverlapped != null)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
- }
-
- if (iocb != null)
- {
- ExecutionContext? ec = ExecutionContext.Capture();
- _callback = (ec != null && !ec.IsDefault) ? new _IOCompletionCallback(iocb, ec) : (object)iocb;
- }
- else
- {
- _callback = null;
- }
- _userObject = userData;
- return AllocateNativeOverlapped();
- }
-
- internal NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData)
- {
- if (_pNativeOverlapped != null)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
- }
- _userObject = userData;
- _callback = iocb;
- return AllocateNativeOverlapped();
- }
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- private extern NativeOverlapped* AllocateNativeOverlapped();
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr);
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr);
- }
-
- #endregion class OverlappedData
-
- #region class Overlapped
-
- public class Overlapped
- {
- private OverlappedData? _overlappedData;
-
- public Overlapped()
- {
- // The split between Overlapped and OverlappedData should not be needed. It is required by the implementation of
- // async GC handles currently. It expects OverlappedData to be a sealed type.
- _overlappedData = new OverlappedData(this);
- }
-
- public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult? ar) : this()
- {
- Debug.Assert(_overlappedData != null, "Initialized in delegated ctor");
- _overlappedData.OffsetLow = offsetLo;
- _overlappedData.OffsetHigh = offsetHi;
- _overlappedData.EventHandle = hEvent;
- _overlappedData._asyncResult = ar;
- }
-
- [Obsolete("This constructor is not 64-bit compatible and has been deprecated. Use the constructor that accepts an IntPtr for the event handle instead.")]
- public Overlapped(int offsetLo, int offsetHi, int hEvent, IAsyncResult? ar) : this(offsetLo, offsetHi, new IntPtr(hEvent), ar)
- {
- }
-
- public IAsyncResult? AsyncResult
- {
- get => _overlappedData!._asyncResult;
- set => _overlappedData!._asyncResult = value;
- }
-
- public int OffsetLow
- {
- get => _overlappedData!.OffsetLow;
- set => _overlappedData!.OffsetLow = value;
- }
-
- public int OffsetHigh
- {
- get => _overlappedData!.OffsetHigh;
- set => _overlappedData!.OffsetHigh = value;
- }
-
- [Obsolete("Overlapped.EventHandle is not 64-bit compatible and has been deprecated. Use EventHandleIntPtr instead.")]
- public int EventHandle
- {
- get => EventHandleIntPtr.ToInt32();
- set => EventHandleIntPtr = new IntPtr(value);
- }
-
- public IntPtr EventHandleIntPtr
- {
- get => _overlappedData!.EventHandle;
- set => _overlappedData!.EventHandle = value;
- }
-
- /*====================================================================
- * Packs a managed overlapped class into native Overlapped struct.
- * Roots the iocb and stores it in the ReservedCOR field of native Overlapped
- * Pins the native Overlapped struct and returns the pinned index.
- ====================================================================*/
- [Obsolete("This overload is not safe and has been deprecated. Use Pack(IOCompletionCallback?, object?) instead.")]
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb)
- {
- return Pack(iocb, null);
- }
-
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb, object? userData)
- {
- return _overlappedData!.Pack(iocb, userData);
- }
-
- [Obsolete("This overload is not safe and has been deprecated. Use UnsafePack(IOCompletionCallback?, object?) instead.")]
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb)
- {
- return UnsafePack(iocb, null);
- }
-
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData)
- {
- return _overlappedData!.UnsafePack(iocb, userData);
- }
-
- /*====================================================================
- * Unpacks an unmanaged native Overlapped struct.
- * Unpins the native Overlapped struct
- ====================================================================*/
- [CLSCompliant(false)]
- public static unsafe Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr)
- {
- ArgumentNullException.ThrowIfNull(nativeOverlappedPtr);
-
- return OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped;
- }
-
- [CLSCompliant(false)]
- public static unsafe void Free(NativeOverlapped* nativeOverlappedPtr)
- {
- ArgumentNullException.ThrowIfNull(nativeOverlappedPtr);
-
- OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped._overlappedData = null;
- OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
- }
- }
-
- #endregion class Overlapped
-}
diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc
index e91bb09807bbdb..dfcf88ce40cdd9 100644
--- a/src/coreclr/dlls/mscorrc/mscorrc.rc
+++ b/src/coreclr/dlls/mscorrc/mscorrc.rc
@@ -405,7 +405,6 @@ BEGIN
IDS_EE_CANNOTCASTSAME "[A]%1 cannot be cast to [B]%2. %3. %4."
IDS_EE_CANNOTCAST_HELPER_PATH "Type %s originates from '%s' in the context '%s' at location '%s'"
IDS_EE_CANNOTCAST_HELPER_BYTE "Type %s originates from '%s' in the context '%s' in a byte array"
- IDS_EE_NOTISOMORPHIC "Object contains references."
IDS_EE_INVALID_VT_FOR_CUSTOM_MARHALER "Type of the VARIANT specified for a parameter with a custom marshaler is not supported by the custom marshaler."
IDS_EE_BAD_COMEXTENDS_CLASS "Types extending from COM objects should override all methods of an interface implemented by the base COM class."
IDS_EE_INTERFACE_NOT_DISPATCH_BASED "The interface does not support late bound calls since it does not derive from IDispatch."
diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h
index 3245329339c91f..ce94e4db354acf 100644
--- a/src/coreclr/dlls/mscorrc/resource.h
+++ b/src/coreclr/dlls/mscorrc/resource.h
@@ -197,7 +197,6 @@
#define IDS_EE_COM_OBJECT_NO_LONGER_HAS_WRAPPER 0x17d9
#define IDS_EE_NDIRECT_BADNATL_CALLCONV 0x17df
#define IDS_EE_CANNOTCAST 0x17e0
-#define IDS_EE_NOTISOMORPHIC 0x17e1
#define IDS_EE_NOCUSTOMMARSHALER 0x17e7
#define IDS_EE_SIZECONTROLOUTOFRANGE 0x17e8
diff --git a/src/coreclr/gc/gcee.cpp b/src/coreclr/gc/gcee.cpp
index 090ca285e572af..a941acb74efab9 100644
--- a/src/coreclr/gc/gcee.cpp
+++ b/src/coreclr/gc/gcee.cpp
@@ -105,12 +105,10 @@ void GCHeap::UpdatePostGCCounters()
size_t promoted_finalization_mem = 0;
size_t total_num_pinned_objects = gc_heap::get_total_pinned_objects();
-#ifndef FEATURE_NATIVEAOT
// if a max gen garbage collection was performed, resync the GC Handle counter;
// if threads are currently suspended, we do not need to obtain a lock on each handle table
if (condemned_gen == max_generation)
total_num_gc_handles = HndCountAllHandles(!IsGCInProgress());
-#endif //FEATURE_NATIVEAOT
// per generation calculation.
for (int gen_index = 0; gen_index < total_generation_count; gen_index++)
diff --git a/src/coreclr/gc/handletable.cpp b/src/coreclr/gc/handletable.cpp
index 04c41616487042..a5cfa3be7ab635 100644
--- a/src/coreclr/gc/handletable.cpp
+++ b/src/coreclr/gc/handletable.cpp
@@ -521,6 +521,7 @@ void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)
FIRE_EVENT(SetGCHandle, (void *)handle, (void *)value, hndType, generation);
FIRE_EVENT(PrvSetGCHandle, (void *) handle, (void *)value, hndType, generation);
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
// Also fire the things pinned by Async pinned handles
if (hndType == HNDTYPE_ASYNCPINNED)
{
@@ -531,6 +532,7 @@ void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)
FIRE_EVENT(SetGCHandle, (void *)overlapped, (void *)to, HNDTYPE_PINNED, generation);
});
}
+#endif
}
#else
UNREFERENCED_PARAMETER(handle);
@@ -578,12 +580,14 @@ void HndWriteBarrierWorker(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value)
int generation = g_theGCHeap->WhichGeneration(value);
uint32_t uType = HandleFetchType(handle);
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
//OverlappedData need special treatment: because all user data pointed by it needs to be reported by this handle,
//its age is consider to be min age of the user data, to be simple, we just make it 0
if (uType == HNDTYPE_ASYNCPINNED)
{
generation = 0;
}
+#endif
if (uType == HNDTYPE_DEPENDENT)
{
diff --git a/src/coreclr/gc/handletablepriv.h b/src/coreclr/gc/handletablepriv.h
index c8951e81db71ed..335fdd99167d6f 100644
--- a/src/coreclr/gc/handletablepriv.h
+++ b/src/coreclr/gc/handletablepriv.h
@@ -14,6 +14,13 @@
#include "handletable.h"
+
+ // Build support for async pinned handles into standalone GC to make it usable with older runtimes
+#if defined(BUILD_AS_STANDALONE) && !defined(FEATURE_NATIVEAOT)
+#define FEATURE_ASYNC_PINNED_HANDLES
+#endif
+
+
/*--------------------------------------------------------------------------*/
//@TODO: find a home for this in a project-level header file
diff --git a/src/coreclr/gc/handletablescan.cpp b/src/coreclr/gc/handletablescan.cpp
index 0a75dd9c2c505b..7d81e40b409138 100644
--- a/src/coreclr/gc/handletablescan.cpp
+++ b/src/coreclr/gc/handletablescan.cpp
@@ -815,6 +815,7 @@ void BlockResetAgeMapForBlocksWorker(uint32_t *pdwGen, uint32_t dwClumpMask, Sca
if (minAge > thisAge)
minAge = thisAge;
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
GCToEEInterface::WalkAsyncPinned(*pValue, &minAge,
[](Object*, Object* to, void* ctx)
{
@@ -825,6 +826,7 @@ void BlockResetAgeMapForBlocksWorker(uint32_t *pdwGen, uint32_t dwClumpMask, Sca
*minAge = generation;
}
});
+#endif
}
}
_ASSERTE(FitsInU1(minAge));
@@ -966,12 +968,15 @@ void BlockVerifyAgeMapForBlocksWorker(uint32_t *pdwGen, uint32_t dwClumpMask, Sc
if (!HndIsNullOrDestroyedHandle(*pValue))
{
VerifyObjectAndAge((*pValue), (*pValue), minAge);
+
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
GCToEEInterface::WalkAsyncPinned(*pValue, &minAge,
[](Object* from, Object* object, void* age)
{
uint8_t* minAge = reinterpret_cast(age);
VerifyObjectAndAge(from, object, *minAge);
});
+#endif
if (uType == HNDTYPE_DEPENDENT)
{
diff --git a/src/coreclr/gc/objecthandle.cpp b/src/coreclr/gc/objecthandle.cpp
index 2ccf88972da7af..52b25b88adf51f 100644
--- a/src/coreclr/gc/objecthandle.cpp
+++ b/src/coreclr/gc/objecthandle.cpp
@@ -1010,7 +1010,13 @@ void Ref_TracePinningRoots(uint32_t condemned, uint32_t maxgen, ScanContext* sc,
LOG((LF_GC, LL_INFO10000, "Pinning referents of pinned handles in generation %u\n", condemned));
// pin objects pointed to by pinning handles
- uint32_t types[2] = {HNDTYPE_PINNED, HNDTYPE_ASYNCPINNED};
+ uint32_t types[] =
+ {
+ HNDTYPE_PINNED,
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
+ HNDTYPE_ASYNCPINNED,
+#endif
+ };
uint32_t flags = sc->concurrent ? HNDGCF_ASYNC : HNDGCF_NORMAL;
HandleTableMap *walk = &g_HandleTableMap;
@@ -1025,7 +1031,9 @@ void Ref_TracePinningRoots(uint32_t condemned, uint32_t maxgen, ScanContext* sc,
// handles may require a callback into the EE in order to fully trace an async pinned
// object's object graph.
HndScanHandlesForGC(hTable, PinObject, uintptr_t(sc), uintptr_t(fn), &types[0], 1, condemned, maxgen, flags);
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
HndScanHandlesForGC(hTable, AsyncPinObject, uintptr_t(sc), uintptr_t(fn), &types[1], 1, condemned, maxgen, flags);
+#endif
}
}
walk = walk->pNext;
@@ -1489,7 +1497,9 @@ void Ref_ScanHandlesForProfilerAndETW(uint32_t maxgen, uintptr_t lp1, handle_sca
#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
HNDTYPE_PINNED,
// HNDTYPE_VARIABLE,
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
HNDTYPE_ASYNCPINNED,
+#endif
HNDTYPE_SIZEDREF,
};
@@ -1554,7 +1564,9 @@ void Ref_ScanPointers(uint32_t condemned, uint32_t maxgen, ScanContext* sc, Ref_
HNDTYPE_REFCOUNTED,
#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS || FEATURE_OBJCMARSHAL || FEATURE_NATIVEAOT
HNDTYPE_PINNED,
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
HNDTYPE_ASYNCPINNED,
+#endif
HNDTYPE_SIZEDREF,
};
@@ -1591,7 +1603,13 @@ void Ref_UpdatePinnedPointers(uint32_t condemned, uint32_t maxgen, ScanContext*
LOG((LF_GC, LL_INFO10000, "Updating pointers to referents of pinning handles in generation %u\n", condemned));
// these are the handle types that need their pointers updated
- uint32_t types[2] = {HNDTYPE_PINNED, HNDTYPE_ASYNCPINNED};
+ uint32_t types[] =
+ {
+ HNDTYPE_PINNED,
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
+ HNDTYPE_ASYNCPINNED,
+#endif
+ };
uint32_t flags = (sc->concurrent) ? HNDGCF_ASYNC : HNDGCF_NORMAL;
HandleTableMap *walk = &g_HandleTableMap;
@@ -1633,7 +1651,9 @@ void Ref_AgeHandles(uint32_t condemned, uint32_t maxgen, uintptr_t lp1)
#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
HNDTYPE_WEAK_NATIVE_COM,
#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
HNDTYPE_ASYNCPINNED,
+#endif
HNDTYPE_SIZEDREF,
};
@@ -1676,7 +1696,9 @@ void Ref_RejuvenateHandles(uint32_t condemned, uint32_t maxgen, uintptr_t lp1)
#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
HNDTYPE_WEAK_NATIVE_COM,
#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
HNDTYPE_ASYNCPINNED,
+#endif
HNDTYPE_SIZEDREF,
};
@@ -1718,7 +1740,9 @@ void Ref_VerifyHandleTable(uint32_t condemned, uint32_t maxgen, ScanContext* sc)
#if defined(FEATURE_COMINTEROP) || defined(FEATURE_COMWRAPPERS)
HNDTYPE_WEAK_NATIVE_COM,
#endif // FEATURE_COMINTEROP || FEATURE_COMWRAPPERS
+#ifdef FEATURE_ASYNC_PINNED_HANDLES
HNDTYPE_ASYNCPINNED,
+#endif
HNDTYPE_SIZEDREF,
HNDTYPE_DEPENDENT,
};
diff --git a/src/coreclr/inc/dacvars.h b/src/coreclr/inc/dacvars.h
index e7a1e8b5e82457..13642fe1ab6c98 100644
--- a/src/coreclr/inc/dacvars.h
+++ b/src/coreclr/inc/dacvars.h
@@ -156,7 +156,6 @@ DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pExecutionEngineExceptionClass, ::g_p
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pDelegateClass, ::g_pDelegateClass)
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pMulticastDelegateClass, ::g_pMulticastDelegateClass)
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pFreeObjectMethodTable, ::g_pFreeObjectMethodTable)
-DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pOverlappedDataClass, ::g_pOverlappedDataClass)
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pValueTypeClass, ::g_pValueTypeClass)
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pEnumClass, ::g_pEnumClass)
DEFINE_DACVAR(UNKNOWN_POINTER_TYPE, dac__g_pThreadClass, ::g_pThreadClass)
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
index e84f5ed4947036..16d10f56413292 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj
@@ -235,7 +235,6 @@
-
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Overlapped.cs
deleted file mode 100644
index e1417c4847782a..00000000000000
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Overlapped.cs
+++ /dev/null
@@ -1,279 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-/*
- * This files defines the following types:
- * - _IOCompletionCallback
- * - OverlappedData
- * - Overlapped
- */
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Class for converting information to and from the native
-** overlapped structure used in asynchronous file i/o
-**
-**
-=============================================================================*/
-
-using System.Diagnostics;
-using System.Runtime;
-using System.Runtime.InteropServices;
-using Internal.Runtime.CompilerServices;
-
-namespace System.Threading
-{
- #region class OverlappedData
-
- internal sealed unsafe class 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 (_pNativeOverlapped != null)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
- }
-
- if (iocb != null)
- {
- ExecutionContext? ec = ExecutionContext.Capture();
- _callback = (ec != null && !ec.IsDefault) ? new _IOCompletionCallback(iocb, ec) : (object)iocb;
- }
- else
- {
- _callback = null;
- }
- _userObject = userData;
- return AllocateNativeOverlapped();
- }
-
- internal unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData)
- {
- if (_pNativeOverlapped != null)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
- }
- _userObject = userData;
- _callback = iocb;
- return AllocateNativeOverlapped();
- }
-
- private unsafe NativeOverlapped* AllocateNativeOverlapped()
- {
- Debug.Assert(_pinnedData == null);
-
- bool success = false;
- try
- {
- if (_userObject != null)
- {
- if (_userObject.GetType() == typeof(object[]))
- {
- object[] objArray = (object[])_userObject;
-
- _pinnedData = new GCHandle[objArray.Length];
- for (int i = 0; i < objArray.Length; i++)
- {
- _pinnedData[i] = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
- }
- }
- else
- {
- _pinnedData = new GCHandle[1];
- _pinnedData[0] = GCHandle.Alloc(_userObject, GCHandleType.Pinned);
- }
- }
-
- NativeOverlapped* pNativeOverlapped = (NativeOverlapped*)NativeMemory.Alloc((nuint)(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;
-
- *(GCHandle*)(_pNativeOverlapped + 1) = GCHandle.Alloc(this);
-
- success = true;
- return _pNativeOverlapped;
- }
- finally
- {
- if (!success)
- FreeNativeOverlapped();
- }
- }
-
- internal static unsafe void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr)
- {
- OverlappedData overlappedData = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr);
- overlappedData.FreeNativeOverlapped();
- }
-
- private void FreeNativeOverlapped()
- {
- if (_pinnedData != null)
- {
- for (int i = 0; i < _pinnedData.Length; i++)
- {
- if (_pinnedData[i].IsAllocated)
- {
- _pinnedData[i].Free();
- }
- }
- _pinnedData = null;
- }
-
- if (_pNativeOverlapped != null)
- {
- GCHandle handle = *(GCHandle*)(_pNativeOverlapped + 1);
- if (handle.IsAllocated)
- handle.Free();
-
- NativeMemory.Free(_pNativeOverlapped);
- _pNativeOverlapped = null;
- }
- }
-
- internal static unsafe OverlappedData GetOverlappedFromNative(NativeOverlapped* pNativeOverlapped)
- {
- GCHandle handle = *(GCHandle*)(pNativeOverlapped + 1);
- return (OverlappedData)handle.Target!;
- }
- }
-
- #endregion class OverlappedData
-
- #region class Overlapped
-
- public class Overlapped
- {
- private OverlappedData _overlappedData;
-
- public Overlapped()
- {
- _overlappedData = new OverlappedData();
- _overlappedData._overlapped = this;
- }
-
- public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar) : this()
- {
- _overlappedData.OffsetLow = offsetLo;
- _overlappedData.OffsetHigh = offsetHi;
- _overlappedData.EventHandle = hEvent;
- _overlappedData.AsyncResult = ar;
- }
-
- [Obsolete("This constructor is not 64-bit compatible and has been deprecated. Use the constructor that accepts an IntPtr for the event handle instead.")]
- public Overlapped(int offsetLo, int offsetHi, int hEvent, IAsyncResult ar) : this(offsetLo, offsetHi, new IntPtr(hEvent), ar)
- {
- }
-
- public IAsyncResult AsyncResult
- {
- get { return _overlappedData.AsyncResult; }
- set { _overlappedData.AsyncResult = value; }
- }
-
- public int OffsetLow
- {
- get { return _overlappedData.OffsetLow; }
- set { _overlappedData.OffsetLow = value; }
- }
-
- public int OffsetHigh
- {
- get { return _overlappedData.OffsetHigh; }
- set { _overlappedData.OffsetHigh = value; }
- }
-
- [Obsolete("Overlapped.EventHandle is not 64-bit compatible and has been deprecated. Use EventHandleIntPtr instead.")]
- public int EventHandle
- {
- get { return EventHandleIntPtr.ToInt32(); }
- set { EventHandleIntPtr = new IntPtr(value); }
- }
-
- public IntPtr EventHandleIntPtr
- {
- get { return _overlappedData.EventHandle; }
- set { _overlappedData.EventHandle = value; }
- }
-
- /*====================================================================
- * Packs a managed overlapped class into native Overlapped struct.
- * Roots the iocb and stores it in the ReservedCOR field of native Overlapped
- * Pins the native Overlapped struct and returns the pinned index.
- ====================================================================*/
- [Obsolete("This overload is not safe and has been deprecated. Use Pack(IOCompletionCallback?, object?) instead.")]
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback iocb)
- {
- return Pack(iocb, null);
- }
-
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback iocb, object userData)
- {
- return _overlappedData.Pack(iocb, userData);
- }
-
- [Obsolete("This overload is not safe and has been deprecated. Use UnsafePack(IOCompletionCallback?, object?) instead.")]
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb)
- {
- return UnsafePack(iocb, null);
- }
-
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback iocb, object userData)
- {
- return _overlappedData.UnsafePack(iocb, userData);
- }
-
- /*====================================================================
- * Unpacks an unmanaged native Overlapped struct.
- * Unpins the native Overlapped struct
- ====================================================================*/
- [CLSCompliant(false)]
- public static unsafe Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr)
- {
- if (nativeOverlappedPtr == null)
- throw new ArgumentNullException(nameof(nativeOverlappedPtr));
-
- return OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped;
- }
-
- [CLSCompliant(false)]
- public static unsafe void Free(NativeOverlapped* nativeOverlappedPtr)
- {
- if (nativeOverlappedPtr == null)
- throw new ArgumentNullException(nameof(nativeOverlappedPtr));
-
- OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped._overlappedData = null;
- OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
- }
- }
-
- #endregion class Overlapped
-}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs
index 13bb51c78bd3c6..150dcdd92523e2 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs
@@ -415,7 +415,7 @@ private static RegisteredWaitHandle RegisterWaitForSingleObject(
}
private static unsafe void NativeOverlappedCallback(nint overlappedPtr) =>
- _IOCompletionCallback.PerformSingleIOCompletionCallback(0, 0, (NativeOverlapped*)overlappedPtr);
+ IOCompletionCallbackHelper.PerformSingleIOCompletionCallback(0, 0, (NativeOverlapped*)overlappedPtr);
[CLSCompliant(false)]
[SupportedOSPlatform("windows")]
diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt
index c59090a44f4405..cbf94be0f95564 100644
--- a/src/coreclr/vm/CMakeLists.txt
+++ b/src/coreclr/vm/CMakeLists.txt
@@ -341,7 +341,6 @@ set(VM_SOURCES_WKS
multicorejit.cpp # Condition="'$(FeatureMulticoreJIT)' == 'true'
multicorejitplayer.cpp # Condition="'$(FeatureMulticoreJIT)' == 'true'
nativeeventsource.cpp
- nativeoverlapped.cpp
nativelibrary.cpp
nativelibrarynative.cpp
objectlist.cpp
@@ -444,8 +443,6 @@ set(VM_HEADERS_WKS
multicorejit.h
multicorejitimpl.h
nativeeventsource.h
- nativeoverlapped.h
- nativelibrarynative.h
objectlist.h
olevariant.h
pendingload.h
diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp
index aef966dfee8dbf..61141e71160a91 100644
--- a/src/coreclr/vm/appdomain.cpp
+++ b/src/coreclr/vm/appdomain.cpp
@@ -52,8 +52,6 @@
#include "appdomain.inl"
#include "typeparse.h"
-#include "nativeoverlapped.h"
-
#ifndef TARGET_UNIX
#include "dwreport.h"
#endif // !TARGET_UNIX
diff --git a/src/coreclr/vm/binder.cpp b/src/coreclr/vm/binder.cpp
index 1678077fcaa95e..23b14a34ee43b6 100644
--- a/src/coreclr/vm/binder.cpp
+++ b/src/coreclr/vm/binder.cpp
@@ -17,7 +17,6 @@
#include "customattribute.h"
#include "debugdebugger.h"
#include "dllimport.h"
-#include "nativeoverlapped.h"
#include "clrvarargs.h"
#include "sigbuilder.h"
#include "olevariant.h"
diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp
index 54bb5177cae530..b6ae49b2a1d1ca 100644
--- a/src/coreclr/vm/corelib.cpp
+++ b/src/coreclr/vm/corelib.cpp
@@ -35,7 +35,6 @@
#include "assemblynative.hpp"
#include "comthreadpool.h"
#include "comwaithandle.h"
-#include "nativeoverlapped.h"
#include "proftoeeinterfaceimpl.h"
diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h
index 62cb4d8a634c12..1a7d26e42dc51f 100644
--- a/src/coreclr/vm/corelib.h
+++ b/src/coreclr/vm/corelib.h
@@ -612,20 +612,6 @@ END_ILLINK_FEATURE_SWITCH()
DEFINE_CLASS(MONITOR, Threading, Monitor)
DEFINE_METHOD(MONITOR, ENTER, Enter, SM_Obj_RetVoid)
-DEFINE_CLASS_U(Threading, OverlappedData, OverlappedDataObject)
-DEFINE_FIELD_U(_asyncResult, OverlappedDataObject, m_asyncResult)
-DEFINE_FIELD_U(_callback, OverlappedDataObject, m_callback)
-DEFINE_FIELD_U(_overlapped, OverlappedDataObject, m_overlapped)
-DEFINE_FIELD_U(_userObject, OverlappedDataObject, m_userObject)
-DEFINE_FIELD_U(_pNativeOverlapped, OverlappedDataObject, m_pNativeOverlapped)
-DEFINE_FIELD_U(_offsetLow, OverlappedDataObject, m_offsetLow)
-DEFINE_FIELD_U(_offsetHigh, OverlappedDataObject, m_offsetHigh)
-DEFINE_FIELD_U(_eventHandle, OverlappedDataObject, m_eventHandle)
-DEFINE_CLASS(OVERLAPPEDDATA, Threading, OverlappedData)
-
-DEFINE_CLASS(NATIVEOVERLAPPED, Threading, NativeOverlapped)
-
-
DEFINE_CLASS(VOLATILE, Threading, Volatile)
#define DEFINE_VOLATILE_METHODS(methodType, paramType) \
diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h
index bf3c849f318642..e000939d2c5a7c 100644
--- a/src/coreclr/vm/ecalllist.h
+++ b/src/coreclr/vm/ecalllist.h
@@ -549,12 +549,6 @@ FCFuncStart(gMonitorFuncs)
FCFuncElement("IsEnteredNative", ObjectNative::IsLockHeld)
FCFuncEnd()
-FCFuncStart(gOverlappedFuncs)
- FCFuncElement("AllocateNativeOverlapped", AllocateNativeOverlapped)
- FCFuncElement("FreeNativeOverlapped", FreeNativeOverlapped)
- FCFuncElement("GetOverlappedFromNative", GetOverlappedFromNative)
-FCFuncEnd()
-
FCFuncStart(gRuntimeHelpers)
FCFuncElement("GetObjectValue", ObjectNative::GetObjectValue)
FCFuncElement("InitializeArray", ArrayNative::InitializeArray)
@@ -770,7 +764,6 @@ FCClassElement("Object", "System", gObjectFuncs)
#ifdef FEATURE_COMINTEROP
FCClassElement("ObjectMarshaler", "System.StubHelpers", gObjectMarshalerFuncs)
#endif
-FCClassElement("OverlappedData", "System.Threading", gOverlappedFuncs)
FCClassElement("RuntimeAssembly", "System.Reflection", gRuntimeAssemblyFuncs)
FCClassElement("RuntimeFieldHandle", "System", gCOMFieldHandleNewFuncs)
diff --git a/src/coreclr/vm/gcenv.ee.cpp b/src/coreclr/vm/gcenv.ee.cpp
index 364a08c4bd5407..8b289e9c744256 100644
--- a/src/coreclr/vm/gcenv.ee.cpp
+++ b/src/coreclr/vm/gcenv.ee.cpp
@@ -1531,36 +1531,8 @@ void GCToEEInterface::WalkAsyncPinnedForPromotion(Object* object, ScanContext* s
assert(object != nullptr);
assert(sc != nullptr);
assert(callback != nullptr);
- if (object->GetGCSafeMethodTable() != g_pOverlappedDataClass)
- {
- // not an overlapped data object - nothing to do.
- return;
- }
- // reporting the pinned user objects
- OverlappedDataObject *pOverlapped = (OverlappedDataObject *)object;
- if (pOverlapped->m_userObject != NULL)
- {
- if (pOverlapped->m_userObject->GetGCSafeMethodTable() == g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT].AsMethodTable())
- {
- // OverlappedDataObject is very special. An async pin handle keeps it alive.
- // During GC, we also make sure
- // 1. m_userObject itself does not move if m_userObject is not array
- // 2. Every object pointed by m_userObject does not move if m_userObject is array
- // We do not want to pin m_userObject if it is array.
- ArrayBase* pUserObject = (ArrayBase*)OBJECTREFToObject(pOverlapped->m_userObject);
- Object **ppObj = (Object**)pUserObject->GetDataPtr(TRUE);
- size_t num = pUserObject->GetNumComponents();
- for (size_t i = 0; i < num; i++)
- {
- callback(ppObj + i, sc, GC_CALL_PINNED);
- }
- }
- else
- {
- callback(&OBJECTREF_TO_UNCHECKED_OBJECTREF(pOverlapped->m_userObject), (ScanContext *)sc, GC_CALL_PINNED);
- }
- }
+ // Unused
}
void GCToEEInterface::WalkAsyncPinned(Object* object, void* context, void (*callback)(Object*, Object*, void*))
@@ -1570,27 +1542,7 @@ void GCToEEInterface::WalkAsyncPinned(Object* object, void* context, void (*call
assert(object != nullptr);
assert(callback != nullptr);
- if (object->GetGCSafeMethodTable() != g_pOverlappedDataClass)
- {
- return;
- }
-
- OverlappedDataObject *pOverlapped = (OverlappedDataObject *)(object);
- if (pOverlapped->m_userObject != NULL)
- {
- Object * pUserObject = OBJECTREFToObject(pOverlapped->m_userObject);
- callback(object, pUserObject, context);
- if (pOverlapped->m_userObject->GetGCSafeMethodTable() == g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT].AsMethodTable())
- {
- ArrayBase* pUserArrayObject = (ArrayBase*)pUserObject;
- Object **pObj = (Object**)pUserArrayObject->GetDataPtr(TRUE);
- size_t num = pUserArrayObject->GetNumComponents();
- for (size_t i = 0; i < num; i ++)
- {
- callback(pUserObject, pObj[i], context);
- }
- }
- }
+ // Unused
}
IGCToCLREventSink* GCToEEInterface::EventSink()
diff --git a/src/coreclr/vm/gcenv.ee.standalone.cpp b/src/coreclr/vm/gcenv.ee.standalone.cpp
index f9f2adaa6ce09b..9ad0c4c380e7ad 100644
--- a/src/coreclr/vm/gcenv.ee.standalone.cpp
+++ b/src/coreclr/vm/gcenv.ee.standalone.cpp
@@ -5,7 +5,6 @@
#include "gcenv.h"
#include "gcenv.ee.h"
#include "threadsuspend.h"
-#include "nativeoverlapped.h"
#include "interoplibinterface.h"
#ifdef FEATURE_COMINTEROP
diff --git a/src/coreclr/vm/gcenv.ee.static.cpp b/src/coreclr/vm/gcenv.ee.static.cpp
index acabba90dec0f6..ab8a3f22f8cb8d 100644
--- a/src/coreclr/vm/gcenv.ee.static.cpp
+++ b/src/coreclr/vm/gcenv.ee.static.cpp
@@ -5,7 +5,6 @@
#include "gcenv.h"
#include "../gc/env/gcenv.ee.h"
#include "threadsuspend.h"
-#include "nativeoverlapped.h"
#include "interoplibinterface.h"
#ifdef FEATURE_COMINTEROP
diff --git a/src/coreclr/vm/marshalnative.cpp b/src/coreclr/vm/marshalnative.cpp
index d7acb946a47c7f..2e245082e6629c 100644
--- a/src/coreclr/vm/marshalnative.cpp
+++ b/src/coreclr/vm/marshalnative.cpp
@@ -443,23 +443,6 @@ FCIMPLEND
* Support for the GCHandle class.
*/
- // Check that the supplied object is valid to put in a pinned handle.
-// Throw an exception if not.
-void ValidatePinnedObject(OBJECTREF obj)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- // Identical logic exists in managed code for Marshal.IsPinnable()
- if (obj != NULL && obj->GetMethodTable()->ContainsPointers())
- COMPlusThrow(kArgumentException, IDS_EE_NOTISOMORPHIC);
-}
-
NOINLINE static OBJECTHANDLE FCDiagCreateHandle(OBJECTREF objRef, int type)
{
OBJECTHANDLE hnd = NULL;
diff --git a/src/coreclr/vm/marshalnative.h b/src/coreclr/vm/marshalnative.h
index 034ea1f4acf154..f49481bf95b949 100644
--- a/src/coreclr/vm/marshalnative.h
+++ b/src/coreclr/vm/marshalnative.h
@@ -132,10 +132,6 @@ class MarshalNative
#endif // FEATURE_COMINTEROP
};
-// Check that the supplied object is valid to put in a pinned handle,
-// throwing an exception if not.
-void ValidatePinnedObject(OBJECTREF obj);
-
extern "C" VOID QCALLTYPE MarshalNative_Prelink(MethodDesc * pMD);
extern "C" BOOL QCALLTYPE MarshalNative_IsBuiltInComSupported();
diff --git a/src/coreclr/vm/nativeoverlapped.cpp b/src/coreclr/vm/nativeoverlapped.cpp
deleted file mode 100644
index 4a9edb5ff780be..00000000000000
--- a/src/coreclr/vm/nativeoverlapped.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-
-/*============================================================
-**
-** Header: COMNativeOverlapped.h
-**
-** Purpose: Native methods for allocating and freeing NativeOverlapped
-**
-
-**
-===========================================================*/
-#include "common.h"
-#include "fcall.h"
-#include "nativeoverlapped.h"
-#include "corhost.h"
-#include "comsynchronizable.h"
-#include "comthreadpool.h"
-#include "marshalnative.h"
-
-FCIMPL1(LPOVERLAPPED, AllocateNativeOverlapped, OverlappedDataObject* overlappedUNSAFE)
-{
- FCALL_CONTRACT;
-
- LPOVERLAPPED lpOverlapped = NULL;
- OVERLAPPEDDATAREF overlapped = ObjectToOVERLAPPEDDATAREF(overlappedUNSAFE);
- OBJECTREF userObject = overlapped->m_userObject;
-
- HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_NONE, overlapped, userObject);
-
- if (g_pOverlappedDataClass == NULL)
- {
- g_pOverlappedDataClass = CoreLibBinder::GetClass(CLASS__OVERLAPPEDDATA);
- // We have optimization to avoid creating event if IO is in default domain. This depends on default domain
- // can not be unloaded.
- }
-
- CONSISTENCY_CHECK(overlapped->GetMethodTable() == g_pOverlappedDataClass);
-
- if (userObject != NULL)
- {
- if (userObject->GetMethodTable() == g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT].AsMethodTable())
- {
- BASEARRAYREF asArray = (BASEARRAYREF) userObject;
- OBJECTREF *pObj = (OBJECTREF*)(asArray->GetDataPtr());
- SIZE_T num = asArray->GetNumComponents();
- SIZE_T i;
- for (i = 0; i < num; i ++)
- {
- ValidatePinnedObject(pObj[i]);
- }
- }
- else
- {
- ValidatePinnedObject(userObject);
- }
- }
-
- NewHolder overlappedHolder(new NATIVEOVERLAPPED_AND_HANDLE());
- overlappedHolder->m_handle = GetAppDomain()->CreateTypedHandle(overlapped, HNDTYPE_ASYNCPINNED);
- lpOverlapped = &(overlappedHolder.Extract()->m_overlapped);
-
- lpOverlapped->Internal = 0;
- lpOverlapped->InternalHigh = 0;
- lpOverlapped->Offset = overlapped->m_offsetLow;
- lpOverlapped->OffsetHigh = overlapped->m_offsetHigh;
- lpOverlapped->hEvent = (HANDLE)overlapped->m_eventHandle;
-
- overlapped->m_pNativeOverlapped = lpOverlapped;
-
- HELPER_METHOD_FRAME_END();
- LOG((LF_INTEROP, LL_INFO10000, "In AllocNativeOperlapped thread 0x%x\n", GetThread()));
-
- if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context, ThreadPoolIODequeue))
- FireEtwThreadPoolIOPack(lpOverlapped, overlappedUNSAFE, GetClrInstanceId());
-
- return lpOverlapped;
-}
-FCIMPLEND
-
-FCIMPL1(void, FreeNativeOverlapped, LPOVERLAPPED lpOverlapped)
-{
- FCALL_CONTRACT;
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- CONSISTENCY_CHECK(g_pOverlappedDataClass && (OverlappedDataObject::GetOverlapped(lpOverlapped)->GetMethodTable() == g_pOverlappedDataClass));
-
- DestroyAsyncPinningHandle(((NATIVEOVERLAPPED_AND_HANDLE*)lpOverlapped)->m_handle);
- delete lpOverlapped;
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL1(OverlappedDataObject*, GetOverlappedFromNative, LPOVERLAPPED lpOverlapped)
-{
- FCALL_CONTRACT;
-
- CONSISTENCY_CHECK(g_pOverlappedDataClass && (OverlappedDataObject::GetOverlapped(lpOverlapped)->GetMethodTable() == g_pOverlappedDataClass));
-
- return OverlappedDataObject::GetOverlapped(lpOverlapped);
-}
-FCIMPLEND
diff --git a/src/coreclr/vm/nativeoverlapped.h b/src/coreclr/vm/nativeoverlapped.h
deleted file mode 100644
index 771f9fbf483270..00000000000000
--- a/src/coreclr/vm/nativeoverlapped.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-
-/*============================================================
-**
-** Header: COMNativeOverlapped.h
-**
-** Purpose: Native methods for allocating and freeing NativeOverlapped
-**
-
-**
-===========================================================*/
-
-#ifndef _OVERLAPPED_H
-#define _OVERLAPPED_H
-
-struct NATIVEOVERLAPPED_AND_HANDLE
-{
- OVERLAPPED m_overlapped;
- OBJECTHANDLE m_handle;
-};
-
-// This should match the managed OverlappedData object.
-// If you make any change here, you need to change the managed part OverlappedData.
-class OverlappedDataObject : public Object
-{
-public:
- // OverlappedDataObject is very special. An async pin handle keeps it alive.
- // During GC, we also make sure
- // 1. m_userObject itself does not move if m_userObject is not array
- // 2. Every object pointed by m_userObject does not move if m_userObject is array
- OBJECTREF m_asyncResult;
- OBJECTREF m_callback;
- OBJECTREF m_overlapped;
- OBJECTREF m_userObject;
- LPOVERLAPPED m_pNativeOverlapped;
- ULONG_PTR m_eventHandle;
- int m_offsetLow;
- int m_offsetHigh;
-
-#ifndef DACCESS_COMPILE
- static OverlappedDataObject* GetOverlapped(LPOVERLAPPED nativeOverlapped)
- {
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE (nativeOverlapped != NULL);
- return (OverlappedDataObject*)OBJECTREFToObject(ObjectFromHandle(((NATIVEOVERLAPPED_AND_HANDLE*)nativeOverlapped)->m_handle));
- }
-
- // Return the raw OverlappedDataObject* without going into cooperative mode for tracing
- static OverlappedDataObject* GetOverlappedForTracing(LPOVERLAPPED nativeOverlapped)
- {
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE(nativeOverlapped != NULL);
- return *(OverlappedDataObject**)(((NATIVEOVERLAPPED_AND_HANDLE*)nativeOverlapped)->m_handle);
- }
-#endif // DACCESS_COMPILE
-};
-
-#ifdef USE_CHECKED_OBJECTREFS
-
-typedef REF OVERLAPPEDDATAREF;
-#define ObjectToOVERLAPPEDDATAREF(obj) (OVERLAPPEDDATAREF(obj))
-#define OVERLAPPEDDATAREFToObject(objref) (OBJECTREFToObject (objref))
-
-#else
-
-typedef OverlappedDataObject* OVERLAPPEDDATAREF;
-#define ObjectToOVERLAPPEDDATAREF(obj) ((OverlappedDataObject*) (obj))
-#define OVERLAPPEDDATAREFToObject(objref) ((OverlappedDataObject*) (objref))
-
-#endif
-
-FCDECL1(LPOVERLAPPED, AllocateNativeOverlapped, OverlappedDataObject* overlapped);
-FCDECL1(void, FreeNativeOverlapped, LPOVERLAPPED lpOverlapped);
-FCDECL1(OverlappedDataObject*, GetOverlappedFromNative, LPOVERLAPPED lpOverlapped);
-
-#endif
diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp
index a7cfdbc3dca33a..9a7518fe1b97ac 100644
--- a/src/coreclr/vm/qcallentrypoints.cpp
+++ b/src/coreclr/vm/qcallentrypoints.cpp
@@ -30,7 +30,6 @@
#include "assemblynative.hpp"
#include "comthreadpool.h"
#include "comwaithandle.h"
-#include "nativeoverlapped.h"
#include "proftoeeinterfaceimpl.h"
diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp
index e1bc975673db28..00b25257d0068a 100644
--- a/src/coreclr/vm/threads.cpp
+++ b/src/coreclr/vm/threads.cpp
@@ -28,8 +28,6 @@
#include "wrappers.h"
-#include "nativeoverlapped.h"
-
#include "appdomain.inl"
#include "vmholder.h"
#include "exceptmacros.h"
diff --git a/src/coreclr/vm/vars.cpp b/src/coreclr/vm/vars.cpp
index d725b6f4c4f063..edeff0074da907 100644
--- a/src/coreclr/vm/vars.cpp
+++ b/src/coreclr/vm/vars.cpp
@@ -68,7 +68,6 @@ GPTR_IMPL(MethodTable, g_pValueTypeClass);
GPTR_IMPL(MethodTable, g_pEnumClass);
GPTR_IMPL(MethodTable, g_pThreadClass);
GPTR_IMPL(MethodTable, g_pFreeObjectMethodTable);
-GPTR_IMPL(MethodTable, g_pOverlappedDataClass);
GPTR_IMPL(MethodTable, g_TypedReferenceMT);
diff --git a/src/coreclr/vm/vars.hpp b/src/coreclr/vm/vars.hpp
index 4698d840a84c12..ca46259c8181e5 100644
--- a/src/coreclr/vm/vars.hpp
+++ b/src/coreclr/vm/vars.hpp
@@ -375,7 +375,6 @@ GPTR_DECL(MethodTable, g_pFreeObjectMethodTable);
GPTR_DECL(MethodTable, g_pValueTypeClass);
GPTR_DECL(MethodTable, g_pEnumClass);
GPTR_DECL(MethodTable, g_pThreadClass);
-GPTR_DECL(MethodTable, g_pOverlappedDataClass);
GPTR_DECL(MethodTable, g_TypedReferenceMT);
diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
index 6f3a16e6136363..25db56b2879a71 100644
--- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
+++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems
@@ -1080,6 +1080,7 @@
+
@@ -1093,7 +1094,7 @@
-
+
@@ -2456,4 +2457,4 @@
-
\ No newline at end of file
+
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped._IOCompletionCallback.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/IOCompletionCallbackHelper.cs
similarity index 77%
rename from src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped._IOCompletionCallback.cs
rename to src/libraries/System.Private.CoreLib/src/System/Threading/IOCompletionCallbackHelper.cs
index dd4ba13c085aa3..6d1da459c9cc55 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped._IOCompletionCallback.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/IOCompletionCallbackHelper.cs
@@ -6,7 +6,7 @@
namespace System.Threading
{
- internal sealed unsafe partial class _IOCompletionCallback
+ internal sealed unsafe partial class IOCompletionCallbackHelper
{
private readonly IOCompletionCallback _ioCompletionCallback;
private readonly ExecutionContext _executionContext;
@@ -14,7 +14,7 @@ internal sealed unsafe partial class _IOCompletionCallback
private uint _numBytes; // No. of bytes transferred
private NativeOverlapped* _pNativeOverlapped;
- public _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, ExecutionContext executionContext)
+ public IOCompletionCallbackHelper(IOCompletionCallback ioCompletionCallback, ExecutionContext executionContext)
{
_ioCompletionCallback = ioCompletionCallback;
_executionContext = executionContext;
@@ -24,8 +24,8 @@ public _IOCompletionCallback(IOCompletionCallback ioCompletionCallback, Executio
private static readonly ContextCallback IOCompletionCallback_Context_Delegate = IOCompletionCallback_Context;
private static void IOCompletionCallback_Context(object? state)
{
- _IOCompletionCallback helper = (_IOCompletionCallback)state!;
- Debug.Assert(helper != null, "_IOCompletionCallback cannot be null");
+ IOCompletionCallbackHelper helper = (IOCompletionCallbackHelper)state!;
+ Debug.Assert(helper != null, "IOCompletionCallbackHelper cannot be null");
helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pNativeOverlapped);
}
@@ -33,7 +33,7 @@ public static void PerformSingleIOCompletionCallback(uint errorCode, uint numByt
{
Debug.Assert(pNativeOverlapped != null);
- OverlappedData overlapped = OverlappedData.GetOverlappedFromNative(pNativeOverlapped);
+ Overlapped overlapped = Overlapped.GetOverlappedFromNative(pNativeOverlapped);
object? callback = overlapped._callback;
if (callback is IOCompletionCallback iocb)
{
@@ -49,8 +49,8 @@ public static void PerformSingleIOCompletionCallback(uint errorCode, uint numByt
}
// We got here because of Pack
- Debug.Assert(callback is _IOCompletionCallback);
- var helper = (_IOCompletionCallback)callback;
+ Debug.Assert(callback is IOCompletionCallbackHelper);
+ var helper = (IOCompletionCallbackHelper)callback;
helper._errorCode = errorCode;
helper._numBytes = numBytes;
helper._pNativeOverlapped = pNativeOverlapped;
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs
index 5e02261105388a..76e67f5da79fdb 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.cs
@@ -170,7 +170,7 @@ public unsafe void ThreadPoolIOEnqueue(NativeOverlapped* nativeOverlapped)
{
ThreadPoolIOEnqueue(
(IntPtr)nativeOverlapped,
- (IntPtr)OverlappedData.GetOverlappedFromNative(nativeOverlapped).GetHashCode(),
+ (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(),
false);
}
}
@@ -204,7 +204,7 @@ public unsafe void ThreadPoolIODequeue(NativeOverlapped* nativeOverlapped)
{
ThreadPoolIODequeue(
(IntPtr)nativeOverlapped,
- (IntPtr)OverlappedData.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
+ (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
}
}
@@ -238,7 +238,7 @@ public unsafe void ThreadPoolIOPack(NativeOverlapped* nativeOverlapped)
{
ThreadPoolIOPack(
(IntPtr)nativeOverlapped,
- (IntPtr)OverlappedData.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
+ (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.cs
index 49d239428af3f8..04e48db29d8a3d 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/NativeRuntimeEventSource.PortableThreadPool.cs
@@ -269,7 +269,7 @@ public unsafe void ThreadPoolIOEnqueue(NativeOverlapped* nativeOverlapped)
{
ThreadPoolIOEnqueue(
(IntPtr)nativeOverlapped,
- (IntPtr)OverlappedData.GetOverlappedFromNative(nativeOverlapped).GetHashCode(),
+ (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode(),
false);
}
}
@@ -315,7 +315,7 @@ public unsafe void ThreadPoolIODequeue(NativeOverlapped* nativeOverlapped)
{
ThreadPoolIODequeue(
(IntPtr)nativeOverlapped,
- (IntPtr)OverlappedData.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
+ (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
}
}
@@ -358,7 +358,7 @@ public unsafe void ThreadPoolIOPack(NativeOverlapped* nativeOverlapped)
{
ThreadPoolIOPack(
(IntPtr)nativeOverlapped,
- (IntPtr)OverlappedData.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
+ (IntPtr)Overlapped.GetOverlappedFromNative(nativeOverlapped).GetHashCode());
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs
new file mode 100644
index 00000000000000..0f130cdc53aa82
--- /dev/null
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Overlapped.cs
@@ -0,0 +1,237 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics;
+using System.Diagnostics.Tracing;
+using System.Runtime.InteropServices;
+
+namespace System.Threading
+{
+ public unsafe class Overlapped
+ {
+ private IAsyncResult? _asyncResult;
+ internal object? _callback; // IOCompletionCallback or IOCompletionCallbackHelper
+ private NativeOverlapped* _pNativeOverlapped;
+ private IntPtr _eventHandle;
+ private int _offsetLow;
+ private int _offsetHigh;
+
+ public Overlapped()
+ {
+ }
+
+ public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult? ar)
+ {
+ _offsetLow = offsetLo;
+ _offsetHigh = offsetHi;
+ _eventHandle = hEvent;
+ _asyncResult = ar;
+ }
+
+ [Obsolete("This constructor is not 64-bit compatible and has been deprecated. Use the constructor that accepts an IntPtr for the event handle instead.")]
+ public Overlapped(int offsetLo, int offsetHi, int hEvent, IAsyncResult? ar)
+ : this(offsetLo, offsetHi, new IntPtr(hEvent), ar)
+ {
+ }
+
+ public IAsyncResult AsyncResult
+ {
+ get => _asyncResult!;
+ set => _asyncResult = value;
+ }
+
+ public int OffsetLow
+ {
+ get => (_pNativeOverlapped != null) ? _pNativeOverlapped->OffsetLow : _offsetLow;
+ set => ((_pNativeOverlapped != null) ? ref _pNativeOverlapped->OffsetLow : ref _offsetLow) = value;
+ }
+
+ public int OffsetHigh
+ {
+ get => (_pNativeOverlapped != null) ? _pNativeOverlapped->OffsetHigh : _offsetHigh;
+ set => ((_pNativeOverlapped != null) ? ref _pNativeOverlapped->OffsetHigh : ref _offsetHigh) = value;
+ }
+
+ [Obsolete("Overlapped.EventHandle is not 64-bit compatible and has been deprecated. Use EventHandleIntPtr instead.")]
+ public int EventHandle
+ {
+ get => EventHandleIntPtr.ToInt32();
+ set => EventHandleIntPtr = new IntPtr(value);
+ }
+
+ public IntPtr EventHandleIntPtr
+ {
+ get => (_pNativeOverlapped != null) ? _pNativeOverlapped->EventHandle : _eventHandle;
+ set => ((_pNativeOverlapped != null) ? ref _pNativeOverlapped->EventHandle : ref _eventHandle) = value;
+ }
+
+ [Obsolete("This overload is not safe and has been deprecated. Use Pack(IOCompletionCallback?, object?) instead.")]
+ [CLSCompliant(false)]
+ public NativeOverlapped* Pack(IOCompletionCallback? iocb)
+ => Pack(iocb, null);
+
+ [CLSCompliant(false)]
+ public NativeOverlapped* Pack(IOCompletionCallback? iocb, object? userData)
+ {
+ if (_pNativeOverlapped != null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
+ }
+
+ if (iocb != null)
+ {
+ ExecutionContext? ec = ExecutionContext.Capture();
+ _callback = (ec != null && !ec.IsDefault) ? new IOCompletionCallbackHelper(iocb, ec) : (object)iocb;
+ }
+ else
+ {
+ _callback = null;
+ }
+ return AllocateNativeOverlapped(userData);
+ }
+
+ [Obsolete("This overload is not safe and has been deprecated. Use UnsafePack(IOCompletionCallback?, object?) instead.")]
+ [CLSCompliant(false)]
+ public NativeOverlapped* UnsafePack(IOCompletionCallback? iocb)
+ => UnsafePack(iocb, null);
+
+ [CLSCompliant(false)]
+ public NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData)
+ {
+ if (_pNativeOverlapped != null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
+ }
+ _callback = iocb;
+ return AllocateNativeOverlapped(userData);
+ }
+
+ /*====================================================================
+ * Unpacks an unmanaged native Overlapped struct.
+ * Unpins the native Overlapped struct
+ ====================================================================*/
+ [CLSCompliant(false)]
+ public static Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr)
+ {
+ ArgumentNullException.ThrowIfNull(nativeOverlappedPtr);
+
+ return GetOverlappedFromNative(nativeOverlappedPtr);
+ }
+
+ [CLSCompliant(false)]
+ public static void Free(NativeOverlapped* nativeOverlappedPtr)
+ {
+ ArgumentNullException.ThrowIfNull(nativeOverlappedPtr);
+
+ GetOverlappedFromNative(nativeOverlappedPtr)._pNativeOverlapped = null;
+ FreeNativeOverlapped(nativeOverlappedPtr);
+ }
+
+ private NativeOverlapped* AllocateNativeOverlapped(object? userData)
+ {
+ NativeOverlapped* pNativeOverlapped = null;
+ try
+ {
+ nuint handleCount = 1;
+
+ if (userData != null)
+ {
+ if (userData.GetType() == typeof(object[]))
+ {
+ handleCount += (nuint)((object[])userData).Length;
+ }
+ else
+ {
+ handleCount++;
+ }
+ }
+
+ pNativeOverlapped = (NativeOverlapped*)NativeMemory.Alloc(
+ (nuint)(sizeof(NativeOverlapped) + sizeof(nuint)) + handleCount * (nuint)sizeof(GCHandle));
+
+ GCHandleCountRef(pNativeOverlapped) = 0;
+
+ pNativeOverlapped->InternalLow = default;
+ pNativeOverlapped->InternalHigh = default;
+ pNativeOverlapped->OffsetLow = _offsetLow;
+ pNativeOverlapped->OffsetHigh = _offsetHigh;
+ pNativeOverlapped->EventHandle = _eventHandle;
+
+ GCHandleRef(pNativeOverlapped, 0) = GCHandle.Alloc(this);
+ GCHandleCountRef(pNativeOverlapped)++;
+
+ if (userData != null)
+ {
+ if (userData.GetType() == typeof(object[]))
+ {
+ object[] objArray = (object[])userData;
+ for (int i = 0; i < objArray.Length; i++)
+ {
+ GCHandleRef(pNativeOverlapped, (nuint)(i + 1)) = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
+ GCHandleCountRef(pNativeOverlapped)++;
+ }
+ }
+ else
+ {
+ GCHandleRef(pNativeOverlapped, 1) = GCHandle.Alloc(userData, GCHandleType.Pinned);
+ GCHandleCountRef(pNativeOverlapped)++;
+ }
+ }
+
+ Debug.Assert(GCHandleCountRef(pNativeOverlapped) == handleCount);
+
+ // Tracing needs _pNativeOverlapped to be initialized
+ _pNativeOverlapped = pNativeOverlapped;
+
+#if FEATURE_PERFTRACING
+#if !(TARGET_BROWSER && !FEATURE_WASM_THREADS)
+ if (NativeRuntimeEventSource.Log.IsEnabled())
+ NativeRuntimeEventSource.Log.ThreadPoolIOPack(pNativeOverlapped);
+#endif
+#endif
+
+ NativeOverlapped* pRet = pNativeOverlapped;
+ pNativeOverlapped = null;
+ return pRet;
+ }
+ finally
+ {
+ if (pNativeOverlapped != null)
+ {
+ _pNativeOverlapped = null;
+ FreeNativeOverlapped(pNativeOverlapped);
+ }
+ }
+ }
+
+ internal static void FreeNativeOverlapped(NativeOverlapped* pNativeOverlapped)
+ {
+ nuint handleCount = GCHandleCountRef(pNativeOverlapped);
+
+ for (nuint i = 0; i < handleCount; i++)
+ GCHandleRef(pNativeOverlapped, i).Free();
+
+ NativeMemory.Free(pNativeOverlapped);
+ }
+
+ //
+ // The NativeOverlapped structure is followed by GC handle count and inline array of GC handles
+ //
+ private static ref nuint GCHandleCountRef(NativeOverlapped* pNativeOverlapped)
+ => ref *(nuint*)(pNativeOverlapped + 1);
+
+ private static ref GCHandle GCHandleRef(NativeOverlapped* pNativeOverlapped, nuint index)
+ => ref *((GCHandle*)((nuint*)(pNativeOverlapped + 1) + 1) + index);
+
+ internal static Overlapped GetOverlappedFromNative(NativeOverlapped* pNativeOverlapped)
+ {
+ object? target = GCHandleRef(pNativeOverlapped, 0).Target;
+ Debug.Assert(target is Overlapped);
+
+ Overlapped overlapped = (Overlapped)target;
+ Debug.Assert(overlapped._pNativeOverlapped == pNativeOverlapped);
+
+ return overlapped;
+ }
+ }
+}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.IO.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.IO.Windows.cs
index 2d1a37ca13108f..a8bc0330c7a68b 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.IO.Windows.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.IO.Windows.cs
@@ -241,7 +241,7 @@ private void PollAndInlineCallbacks()
NativeRuntimeEventSource.Log.ThreadPoolIODequeue(nativeOverlapped);
}
- _IOCompletionCallback.PerformSingleIOCompletionCallback(errorCode, bytesTransferred, nativeOverlapped);
+ IOCompletionCallbackHelper.PerformSingleIOCompletionCallback(errorCode, bytesTransferred, nativeOverlapped);
}
}
@@ -262,7 +262,7 @@ public static void Invoke(Event e)
errorCode = Interop.NtDll.RtlNtStatusToDosError((int)ntStatus);
}
- _IOCompletionCallback.PerformSingleIOCompletionCallback(errorCode, e.bytesTransferred, e.nativeOverlapped);
+ IOCompletionCallbackHelper.PerformSingleIOCompletionCallback(errorCode, e.bytesTransferred, e.nativeOverlapped);
}
}
diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
index 7eb9314c1ce629..0c078da40064a0 100644
--- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -1,4 +1,4 @@
-
+
false
true
@@ -278,7 +278,6 @@
-
diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/Overlapped.cs b/src/mono/System.Private.CoreLib/src/System/Threading/Overlapped.cs
deleted file mode 100644
index 708c6d04f200b7..00000000000000
--- a/src/mono/System.Private.CoreLib/src/System/Threading/Overlapped.cs
+++ /dev/null
@@ -1,266 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics;
-using System.Diagnostics.Tracing;
-using System.Runtime.InteropServices;
-
-namespace System.Threading
-{
- #region class OverlappedData
-
- internal sealed unsafe class 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 (_pNativeOverlapped != null)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
- }
-
- if (iocb != null)
- {
- ExecutionContext? ec = ExecutionContext.Capture();
- _callback = (ec != null && !ec.IsDefault) ? new _IOCompletionCallback(iocb, ec) : (object)iocb;
- }
- else
- {
- _callback = null;
- }
- _userObject = userData;
- return AllocateNativeOverlapped();
- }
-
- internal unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData)
- {
- if (_pNativeOverlapped != null)
- {
- throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
- }
- _userObject = userData;
- _callback = iocb;
- return AllocateNativeOverlapped();
- }
-
- private unsafe NativeOverlapped* AllocateNativeOverlapped()
- {
- Debug.Assert(_pinnedData == null);
-
- bool success = false;
- try
- {
- if (_userObject != null)
- {
- if (_userObject.GetType() == typeof(object[]))
- {
- object[] objArray = (object[])_userObject;
-
- _pinnedData = new GCHandle[objArray.Length];
- for (int i = 0; i < objArray.Length; i++)
- {
- _pinnedData[i] = GCHandle.Alloc(objArray[i], GCHandleType.Pinned);
- }
- }
- else
- {
- _pinnedData = new GCHandle[1];
- _pinnedData[0] = GCHandle.Alloc(_userObject, GCHandleType.Pinned);
- }
- }
-
- NativeOverlapped* pNativeOverlapped = (NativeOverlapped*)NativeMemory.Alloc((nuint)(sizeof(NativeOverlapped) + sizeof(GCHandle)));
-
- *(GCHandle*)(pNativeOverlapped + 1) = default;
- _pNativeOverlapped = pNativeOverlapped;
-
- _pNativeOverlapped->InternalLow = default;
- _pNativeOverlapped->InternalHigh = default;
- _pNativeOverlapped->OffsetLow = _offsetLow;
- _pNativeOverlapped->OffsetHigh = _offsetHigh;
- _pNativeOverlapped->EventHandle = _eventHandle;
-
- *(GCHandle*)(_pNativeOverlapped + 1) = GCHandle.Alloc(this);
-
- success = true;
-#if FEATURE_PERFTRACING
-#if !(TARGET_BROWSER && !FEATURE_WASM_THREADS)
- if (NativeRuntimeEventSource.Log.IsEnabled())
- NativeRuntimeEventSource.Log.ThreadPoolIOPack(pNativeOverlapped);
-#endif
-#endif
- return _pNativeOverlapped;
- }
- finally
- {
- if (!success)
- FreeNativeOverlapped();
- }
- }
-
- internal static unsafe void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr)
- {
- OverlappedData overlappedData = GetOverlappedFromNative(nativeOverlappedPtr);
- overlappedData.FreeNativeOverlapped();
- }
-
- private void FreeNativeOverlapped()
- {
- if (_pinnedData != null)
- {
- for (int i = 0; i < _pinnedData.Length; i++)
- {
- if (_pinnedData[i].IsAllocated)
- {
- _pinnedData[i].Free();
- }
- }
- _pinnedData = null;
- }
-
- if (_pNativeOverlapped != null)
- {
- GCHandle handle = *(GCHandle*)(_pNativeOverlapped + 1);
- if (handle.IsAllocated)
- handle.Free();
-
- NativeMemory.Free(_pNativeOverlapped);
- _pNativeOverlapped = null;
- }
- }
-
- internal static unsafe OverlappedData GetOverlappedFromNative(NativeOverlapped* pNativeOverlapped)
- {
- GCHandle handle = *(GCHandle*)(pNativeOverlapped + 1);
- return (OverlappedData)handle.Target!;
- }
- }
-
- #endregion class OverlappedData
-
- #region class Overlapped
-
- public class Overlapped
- {
- private OverlappedData _overlappedData;
-
- public Overlapped()
- {
- _overlappedData = new OverlappedData();
- _overlappedData._overlapped = this;
- }
-
- public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult? ar) : this()
- {
- _overlappedData.OffsetLow = offsetLo;
- _overlappedData.OffsetHigh = offsetHi;
- _overlappedData.EventHandle = hEvent;
- _overlappedData.AsyncResult = ar;
- }
-
- [Obsolete("This constructor is not 64-bit compatible and has been deprecated. Use the constructor that accepts an IntPtr for the event handle instead.")]
- public Overlapped(int offsetLo, int offsetHi, int hEvent, IAsyncResult? ar) : this(offsetLo, offsetHi, new IntPtr(hEvent), ar)
- {
- }
-
- public IAsyncResult? AsyncResult
- {
- get { return _overlappedData.AsyncResult; }
- set { _overlappedData.AsyncResult = value; }
- }
-
- public int OffsetLow
- {
- get { return _overlappedData.OffsetLow; }
- set { _overlappedData.OffsetLow = value; }
- }
-
- public int OffsetHigh
- {
- get { return _overlappedData.OffsetHigh; }
- set { _overlappedData.OffsetHigh = value; }
- }
-
- [Obsolete("Overlapped.EventHandle is not 64-bit compatible and has been deprecated. Use EventHandleIntPtr instead.")]
- public int EventHandle
- {
- get { return EventHandleIntPtr.ToInt32(); }
- set { EventHandleIntPtr = new IntPtr(value); }
- }
-
- public IntPtr EventHandleIntPtr
- {
- get { return _overlappedData.EventHandle; }
- set { _overlappedData.EventHandle = value; }
- }
-
- /*====================================================================
- * Packs a managed overlapped class into native Overlapped struct.
- * Roots the iocb and stores it in the ReservedCOR field of native Overlapped
- * Pins the native Overlapped struct and returns the pinned index.
- ====================================================================*/
- [Obsolete("This overload is not safe and has been deprecated. Use Pack(IOCompletionCallback?, object?) instead.")]
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb)
- {
- return Pack(iocb, null);
- }
-
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* Pack(IOCompletionCallback? iocb, object? userData)
- {
- return _overlappedData.Pack(iocb, userData);
- }
-
- [Obsolete("This overload is not safe and has been deprecated. Use UnsafePack(IOCompletionCallback?, object?) instead.")]
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb)
- {
- return UnsafePack(iocb, null);
- }
-
- [CLSCompliant(false)]
- public unsafe NativeOverlapped* UnsafePack(IOCompletionCallback? iocb, object? userData)
- {
- return _overlappedData.UnsafePack(iocb, userData);
- }
-
- /*====================================================================
- * Unpacks an unmanaged native Overlapped struct.
- * Unpins the native Overlapped struct
- ====================================================================*/
- [CLSCompliant(false)]
- public static unsafe Overlapped Unpack(NativeOverlapped* nativeOverlappedPtr)
- {
- ArgumentNullException.ThrowIfNull(nativeOverlappedPtr);
-
- return OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped!;
- }
-
- [CLSCompliant(false)]
- public static unsafe void Free(NativeOverlapped* nativeOverlappedPtr)
- {
- ArgumentNullException.ThrowIfNull(nativeOverlappedPtr);
-
- OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr)._overlapped!._overlappedData = null!;
- OverlappedData.FreeNativeOverlapped(nativeOverlappedPtr);
- }
- }
-
- #endregion class Overlapped
-}
diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Mono.cs
index 29e2eb99d1c6e5..e9d27a6c3987dc 100644
--- a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Mono.cs
+++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.Mono.cs
@@ -120,7 +120,7 @@ private static void Callback()
}
private static unsafe void NativeOverlappedCallback(nint overlappedPtr) =>
- _IOCompletionCallback.PerformSingleIOCompletionCallback(0, 0, (NativeOverlapped*)overlappedPtr);
+ IOCompletionCallbackHelper.PerformSingleIOCompletionCallback(0, 0, (NativeOverlapped*)overlappedPtr);
[CLSCompliant(false)]
[SupportedOSPlatform("windows")]