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")]