internal static int WaitOneNative(SafeWaitHandle waitableSafeHandle, long millisecondsTimeout) { Debug.Assert(millisecondsTimeout >= -1 && millisecondsTimeout <= int.MaxValue); waitableSafeHandle.DangerousAddRef(); try { return(LowLevelThread.WaitForSingleObject(waitableSafeHandle.DangerousGetHandle(), (int)millisecondsTimeout)); } finally { waitableSafeHandle.DangerousRelease(); } }
private static int MakeForCurrentThread() { // // Get the current thread handle. We need to use DuplicateHandle, because GetCurrentThread returns a pseudo-handle // that cannot be used outside of this thread. // IntPtr thisNativeThreadHandle; Interop.mincore.DuplicateHandle( Interop.mincore.GetCurrentProcess(), Interop.mincore.GetCurrentThread(), Interop.mincore.GetCurrentProcess(), out thisNativeThreadHandle, 0, false, (uint)Interop.Constants.DuplicateSameAccess); // // First, search for a dead thread, so we can reuse its thread ID // for (ManagedThreadId current = s_list; current != null; current = current._next) { // // Try to take the lock on this ID. If another thread already has it, just move on to the next ID. // if (Interlocked.Exchange(ref current._lock, 1) != 0) { continue; } try { // // Does the ID currently belong to a dead thread? // if (LowLevelThread.WaitForSingleObject(current._nativeThreadHandle, 0) == (uint)Interop.Constants.WaitObject0) { // // The thread is dead. We can claim this ID by swapping in our own thread handle. // Interop.mincore.CloseHandle(current._nativeThreadHandle); current._nativeThreadHandle = thisNativeThreadHandle; t_currentManagedThreadId = current._managedThreadId; return(current._managedThreadId); } } finally { // // Release the lock. // current._lock = 0; } } // // We couldn't find a dead thread, so we can't reuse a thread ID. Create a new one. // ManagedThreadId newManagedThreadId = new ManagedThreadId(Interlocked.Increment(ref s_nextThreadId)); newManagedThreadId._nativeThreadHandle = thisNativeThreadHandle; while (true) { ManagedThreadId oldList = s_list; newManagedThreadId._next = oldList; if (Interlocked.CompareExchange(ref s_list, newManagedThreadId, oldList) == oldList) { t_currentManagedThreadId = newManagedThreadId._managedThreadId; return(newManagedThreadId._managedThreadId); } } }