Exemple #1
0
        private Thread()
        {
            _managedThreadId = System.Threading.ManagedThreadId.GetCurrentThreadId();

            PlatformSpecificInitialize();
            RegisterThreadExitCallback();
        }
Exemple #2
0
        private static int MakeForCurrentThread()
        {
            if (s_idDispenser == null)
            {
                Interlocked.CompareExchange(ref s_idDispenser, ImmutableIdDispenser.Empty, null);
            }

            int id;

            var priorIdDispenser = Volatile.Read(ref s_idDispenser);

            for (;;)
            {
                var updatedIdDispenser = priorIdDispenser.AllocateId(out id);
                var interlockedResult  = Interlocked.CompareExchange(ref s_idDispenser, updatedIdDispenser, priorIdDispenser);
                if (Object.ReferenceEquals(priorIdDispenser, interlockedResult))
                {
                    break;
                }
                priorIdDispenser = interlockedResult; // we already have a volatile read that we can reuse for the next loop
            }

            Debug.Assert(id != ManagedThreadIdNone);

            t_currentThreadId        = new ManagedThreadId(id);
            t_currentManagedThreadId = id;

            return(id);
        }
Exemple #3
0
        private void Initialize()
        {
            _priority        = ThreadPriority.Normal;
            _managedThreadId = new ManagedThreadId();

            PlatformSpecificInitialize();
            RegisterThreadExitCallback();
        }
 public static int SetForCurrentThread(ManagedThreadId threadId)
 {
     t_currentThreadId        = threadId;
     t_currentManagedThreadId = threadId.Id;
     return(threadId.Id);
 }
Exemple #5
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;
                }
            }
        }
Exemple #6
0
        private static int MakeForCurrentThread()
        {
            if (s_idDispenser == null)
                Interlocked.CompareExchange(ref s_idDispenser, ImmutableIdDispenser.Empty, null);

            int id;

            var priorIdDispenser = Volatile.Read(ref s_idDispenser);
            for (;;)
            {
                var updatedIdDispenser = priorIdDispenser.AllocateId(out id);
                var interlockedResult = Interlocked.CompareExchange(ref s_idDispenser, updatedIdDispenser, priorIdDispenser);
                if (Object.ReferenceEquals(priorIdDispenser, interlockedResult))
                    break;
                priorIdDispenser = interlockedResult; // we already have a volatile read that we can reuse for the next loop
            }

            Debug.Assert(id != ManagedThreadIdNone);

            t_currentThreadId = new ManagedThreadId(id);
            t_currentManagedThreadId = id;

            return id;
        }
        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);
                }
            }
        }
Exemple #8
0
 private void SetStartHelper(Delegate threadStart, int maxStackSize)
 {
     _threadStart     = threadStart;
     _maxStackSize    = maxStackSize;
     _managedThreadId = new ManagedThreadId();
 }