Пример #1
0
        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
 /*========================================================================
 ** Waits for signal from all the objects.
 ** timeout indicates how long to wait before the method returns.
 ** This method will return either when all the object have been pulsed
 ** or timeout milliseonds have elapsed.
 ** ========================================================================*/
 private static int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool WaitAll)
 {
     IntPtr[] handles = new IntPtr[waitHandles.Length];
     for (int i = 0; i < handles.Length; i++)
     {
         waitHandles[i].waitHandle.DangerousAddRef();
         handles[i] = waitHandles[i].waitHandle.DangerousGetHandle();
     }
     try
     {
         return(LowLevelThread.WaitForMultipleObjects(handles, WaitAll, millisecondsTimeout));
     }
     finally
     {
         for (int i = 0; i < handles.Length; i++)
         {
             waitHandles[i].waitHandle.DangerousRelease();
         }
     }
 }
Пример #3
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);
                }
            }
        }