diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs index 8fe80e7286858..25fc6ff09ad2a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/LowLevelLifoSemaphore.Unix.cs @@ -31,7 +31,7 @@ public bool WaitCore(int timeoutMs) return waitResult == WaitHandle.WaitSuccess; } - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_CorWaitOnePrioritizedNative")] + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitOnePrioritized")] private static partial int WaitNative(SafeWaitHandle handle, int timeoutMs); private void ReleaseCore(int count) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs index f1bfe33e8c8bc..a9fc4d8b2a045 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/WaitHandle.CoreCLR.cs @@ -8,23 +8,18 @@ namespace System.Threading { public abstract partial class WaitHandle { - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int WaitOneCore(IntPtr waitHandle, int millisecondsTimeout, bool useTrivialWaits); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitOneCore")] + private static partial int WaitOneCore(IntPtr waitHandle, int millisecondsTimeout, [MarshalAs(UnmanagedType.Bool)] bool useTrivialWaits); private static unsafe int WaitMultipleIgnoringSyncContextCore(ReadOnlySpan waitHandles, bool waitAll, int millisecondsTimeout) - { - fixed (IntPtr* pWaitHandles = &MemoryMarshal.GetReference(waitHandles)) - { - return WaitMultipleIgnoringSyncContext(pWaitHandles, waitHandles.Length, waitAll, millisecondsTimeout); - } - } + => WaitMultipleIgnoringSyncContext(waitHandles, waitHandles.Length, waitAll, millisecondsTimeout); - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern unsafe int WaitMultipleIgnoringSyncContext(IntPtr* waitHandles, int numHandles, bool waitAll, int millisecondsTimeout); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_WaitMultipleIgnoringSyncContext")] + private static partial int WaitMultipleIgnoringSyncContext(ReadOnlySpan waitHandles, int numHandles, [MarshalAs(UnmanagedType.Bool)] bool waitAll, int millisecondsTimeout); private static int SignalAndWaitCore(IntPtr waitHandleToSignal, IntPtr waitHandleToWaitOn, int millisecondsTimeout) { - int ret = SignalAndWaitNative(waitHandleToSignal, waitHandleToWaitOn, millisecondsTimeout); + int ret = SignalAndWait(waitHandleToSignal, waitHandleToWaitOn, millisecondsTimeout); if (ret == Interop.Errors.ERROR_TOO_MANY_POSTS) { @@ -34,7 +29,7 @@ private static int SignalAndWaitCore(IntPtr waitHandleToSignal, IntPtr waitHandl return ret; } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern int SignalAndWaitNative(IntPtr waitHandleToSignal, IntPtr waitHandleToWaitOn, int millisecondsTimeout); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "WaitHandle_SignalAndWait")] + private static partial int SignalAndWait(IntPtr waitHandleToSignal, IntPtr waitHandleToWaitOn, int millisecondsTimeout); } } diff --git a/src/coreclr/vm/comwaithandle.cpp b/src/coreclr/vm/comwaithandle.cpp index b43e255068bb5..e80675cc03feb 100644 --- a/src/coreclr/vm/comwaithandle.cpp +++ b/src/coreclr/vm/comwaithandle.cpp @@ -11,106 +11,93 @@ ** ===========================================================*/ #include "common.h" -#include "object.h" -#include "field.h" -#include "excep.h" #include "comwaithandle.h" -FCIMPL3(INT32, WaitHandleNative::CorWaitOneNative, HANDLE handle, INT32 timeout, FC_BOOL_ARG useTrivialWaits) +extern "C" INT32 QCALLTYPE WaitHandle_WaitOneCore(HANDLE handle, INT32 timeout, BOOL useTrivialWaits) { - FCALL_CONTRACT; + QCALL_CONTRACT; INT32 retVal = 0; - HELPER_METHOD_FRAME_BEGIN_RET_0(); + + BEGIN_QCALL; _ASSERTE(handle != 0); _ASSERTE(handle != INVALID_HANDLE_VALUE); Thread* pThread = GET_THREAD(); - - WaitMode waitMode = (WaitMode)((!FC_ACCESS_BOOL(useTrivialWaits) ? WaitMode_Alertable : WaitMode_None) | WaitMode_IgnoreSyncCtx); + WaitMode waitMode = (WaitMode)((!useTrivialWaits ? WaitMode_Alertable : WaitMode_None) | WaitMode_IgnoreSyncCtx); retVal = pThread->DoAppropriateWait(1, &handle, TRUE, timeout, waitMode); - HELPER_METHOD_FRAME_END(); + END_QCALL; return retVal; } -FCIMPLEND -#ifdef TARGET_UNIX -extern "C" INT32 QCALLTYPE WaitHandle_CorWaitOnePrioritizedNative(HANDLE handle, INT32 timeoutMs) +extern "C" INT32 QCALLTYPE WaitHandle_WaitMultipleIgnoringSyncContext(HANDLE *handleArray, INT32 numHandles, BOOL waitForAll, INT32 timeout) { QCALL_CONTRACT; - DWORD result = WAIT_FAILED; - - BEGIN_QCALL; - - _ASSERTE(handle != NULL); - _ASSERTE(handle != INVALID_HANDLE_VALUE); - - result = PAL_WaitForSingleObjectPrioritized(handle, timeoutMs); - - END_QCALL; - return (INT32)result; -} -#endif - -FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, HANDLE *handleArray, INT32 numHandles, FC_BOOL_ARG waitForAll, INT32 timeout) -{ - FCALL_CONTRACT; - INT32 ret = 0; - HELPER_METHOD_FRAME_BEGIN_RET_0(); + BEGIN_QCALL; Thread * pThread = GET_THREAD(); #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT // There are some issues with wait-all from an STA thread // - https://github.com/dotnet/runtime/issues/10243#issuecomment-385117537 - if (FC_ACCESS_BOOL(waitForAll) && numHandles > 1 && pThread->GetApartment() == Thread::AS_InSTA) + if (waitForAll && numHandles > 1 && pThread->GetApartment() == Thread::AS_InSTA) { COMPlusThrow(kNotSupportedException, W("NotSupported_WaitAllSTAThread")); } #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - ret = pThread->DoAppropriateWait(numHandles, handleArray, FC_ACCESS_BOOL(waitForAll), timeout, (WaitMode)(WaitMode_Alertable | WaitMode_IgnoreSyncCtx)); + ret = pThread->DoAppropriateWait(numHandles, handleArray, waitForAll, timeout, (WaitMode)(WaitMode_Alertable | WaitMode_IgnoreSyncCtx)); - HELPER_METHOD_FRAME_END(); + END_QCALL; return ret; } -FCIMPLEND -FCIMPL3(INT32, WaitHandleNative::CorSignalAndWaitOneNative, HANDLE waitHandleSignalUNSAFE, HANDLE waitHandleWaitUNSAFE, INT32 timeout) +extern "C" INT32 QCALLTYPE WaitHandle_SignalAndWait(HANDLE waitHandleSignal, HANDLE waitHandleWait, INT32 timeout) { - FCALL_CONTRACT; + QCALL_CONTRACT; - INT32 retVal = 0; + INT32 retVal = (DWORD)-1; - HELPER_METHOD_FRAME_BEGIN_RET_0(); + BEGIN_QCALL; - _ASSERTE(waitHandleSignalUNSAFE != 0); - _ASSERTE(waitHandleWaitUNSAFE != 0); + _ASSERTE(waitHandleSignal != 0); + _ASSERTE(waitHandleWait != 0); Thread* pThread = GET_THREAD(); -#ifdef FEATURE_COMINTEROP - if (pThread->GetApartment() == Thread::AS_InSTA) { - COMPlusThrow(kNotSupportedException, W("NotSupported_SignalAndWaitSTAThread")); // Change this message - } -#endif - - DWORD res = (DWORD) -1; - - HANDLE handles[2]; - handles[0] = waitHandleSignalUNSAFE; - handles[1] = waitHandleWaitUNSAFE; +#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT + if (pThread->GetApartment() == Thread::AS_InSTA) { - res = pThread->DoSignalAndWait(handles, timeout, TRUE /*alertable*/); + COMPlusThrow(kNotSupportedException, W("NotSupported_SignalAndWaitSTAThread")); } +#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - retVal = res; + HANDLE handles[] = { waitHandleSignal, waitHandleWait }; + retVal = pThread->DoSignalAndWait(handles, timeout, TRUE /*alertable*/); - HELPER_METHOD_FRAME_END(); + END_QCALL; return retVal; } -FCIMPLEND + +#ifdef TARGET_UNIX +extern "C" INT32 QCALLTYPE WaitHandle_WaitOnePrioritized(HANDLE handle, INT32 timeoutMs) +{ + QCALL_CONTRACT; + + DWORD result = WAIT_FAILED; + + BEGIN_QCALL; + + _ASSERTE(handle != NULL); + _ASSERTE(handle != INVALID_HANDLE_VALUE); + + result = PAL_WaitForSingleObjectPrioritized(handle, timeoutMs); + + END_QCALL; + return (INT32)result; +} +#endif // TARGET_UNIX diff --git a/src/coreclr/vm/comwaithandle.h b/src/coreclr/vm/comwaithandle.h index d0af3076bf1c4..ac60538912913 100644 --- a/src/coreclr/vm/comwaithandle.h +++ b/src/coreclr/vm/comwaithandle.h @@ -14,15 +14,12 @@ #ifndef _COM_WAITABLE_HANDLE_H #define _COM_WAITABLE_HANDLE_H +extern "C" INT32 QCALLTYPE WaitHandle_WaitOneCore(HANDLE handle, INT32 timeout, BOOL useTrivialWaits); +extern "C" INT32 QCALLTYPE WaitHandle_WaitMultipleIgnoringSyncContext(HANDLE *handleArray, INT32 numHandles, BOOL waitForAll, INT32 timeout); +extern "C" INT32 QCALLTYPE WaitHandle_SignalAndWait(HANDLE waitHandleSignal, HANDLE waitHandleWait, INT32 timeout); -class WaitHandleNative -{ -public: - static FCDECL3(INT32, CorWaitOneNative, HANDLE handle, INT32 timeout, FC_BOOL_ARG useTrivialWaits); - static FCDECL4(INT32, CorWaitMultipleNative, HANDLE *handleArray, INT32 numHandles, FC_BOOL_ARG waitForAll, INT32 timeout); - static FCDECL3(INT32, CorSignalAndWaitOneNative, HANDLE waitHandleSignalUNSAFE, HANDLE waitHandleWaitUNSAFE, INT32 timeout); -}; #ifdef TARGET_UNIX -extern "C" INT32 QCALLTYPE WaitHandle_CorWaitOnePrioritizedNative(HANDLE handle, INT32 timeoutMs); -#endif -#endif +extern "C" INT32 QCALLTYPE WaitHandle_WaitOnePrioritized(HANDLE handle, INT32 timeoutMs); +#endif // TARGET_UNIX + +#endif // _COM_WAITABLE_HANDLE_H diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 2b065fd338034..7611cb93c5d42 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -313,12 +313,6 @@ FCFuncStart(gThreadPoolFuncs) FCFuncElement("GetNextConfigUInt32Value", ThreadPoolNative::GetNextConfigUInt32Value) FCFuncEnd() -FCFuncStart(gWaitHandleFuncs) - FCFuncElement("WaitOneCore", WaitHandleNative::CorWaitOneNative) - FCFuncElement("WaitMultipleIgnoringSyncContext", WaitHandleNative::CorWaitMultipleNative) - FCFuncElement("SignalAndWaitNative", WaitHandleNative::CorSignalAndWaitOneNative) -FCFuncEnd() - FCFuncStart(gCastHelpers) FCFuncElement("IsInstanceOfAny_NoCacheLookup", ::IsInstanceOfAny_NoCacheLookup) FCFuncElement("ChkCastAny_NoCacheLookup", ::ChkCastAny_NoCacheLookup) @@ -493,7 +487,6 @@ FCClassElement("Thread", "System.Threading", gThreadFuncs) FCClassElement("ThreadPool", "System.Threading", gThreadPoolFuncs) FCClassElement("Type", "System", gSystem_Type) FCClassElement("TypedReference", "System", gTypedReferenceFuncs) -FCClassElement("WaitHandle", "System.Threading", gWaitHandleFuncs) #undef FCFuncElement #undef FCFuncElementSig diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 2d2345ca214c1..2eb5681e75563 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -252,9 +252,12 @@ static const Entry s_QCall[] = #ifdef FEATURE_COMINTEROP DllImportEntry(ThreadNative_DisableComObjectEagerCleanup) #endif // FEATURE_COMINTEROP + DllImportEntry(WaitHandle_WaitOneCore) + DllImportEntry(WaitHandle_WaitMultipleIgnoringSyncContext) + DllImportEntry(WaitHandle_SignalAndWait) #ifdef TARGET_UNIX - DllImportEntry(WaitHandle_CorWaitOnePrioritizedNative) -#endif + DllImportEntry(WaitHandle_WaitOnePrioritized) +#endif // TARGET_UNIX DllImportEntry(ClrConfig_GetConfigBoolValue) DllImportEntry(Buffer_Clear) DllImportEntry(Buffer_MemMove) diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index f9fbfec9bc661..99a366e9a2f13 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -3116,14 +3116,14 @@ DWORD MsgWaitHelper(int numWaiters, HANDLE* phEvent, BOOL bWaitAll, DWORD millis // want true WAIT_ALL, we need to fire up a different thread in the MTA and wait // on its result. This isn't implemented yet. // - // A change was added to WaitHandleNative::CorWaitMultipleNative to disable WaitAll + // A change was added to WaitHandle_WaitMultipleIgnoringSyncContext to disable WaitAll // in an STA with more than one handle. if (bWaitAll) { if (numWaiters == 1) bWaitAll = FALSE; - // The check that's supposed to prevent this condition from occurring, in WaitHandleNative::CorWaitMultipleNative, + // The check that's supposed to prevent this condition from occurring, in WaitHandle_WaitMultipleIgnoringSyncContext, // is unfortunately behind FEATURE_COMINTEROP instead of FEATURE_COMINTEROP_APARTMENT_SUPPORT. // So on CoreCLR (where FEATURE_COMINTEROP is not currently defined) we can actually reach this point. // We can't fix this, because it's a breaking change, so we just won't assert here.