예제 #1
0
파일: WaitHandle.cs 프로젝트: wffy/corert
        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();
            }
        }
예제 #2
0
        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);
                }
            }
        }