private void SignalMutex(bool isAbandoned)
            {
                s_lock.VerifyIsLocked();

                Debug.Assert(IsMutex);
                Debug.Assert(!IsSignaled);

                _ownershipInfo.RelinquishOwnership(this, isAbandoned);

                for (ThreadWaitInfo.WaitedListNode waiterNode = _waitersHead, nextWaiterNode;
                     waiterNode != null;
                     waiterNode = nextWaiterNode)
                {
                    // Signaling a waiter will unregister the waiter node, but it may only abort the wait without satisfying the
                    // wait, in which case we would try to signal another waiter. So, keep the next node before trying.
                    nextWaiterNode = waiterNode.Next;

                    ThreadWaitInfo waitInfo = waiterNode.WaitInfo;
                    if (waitInfo.TrySignalToSatisfyWait(waiterNode, isAbandoned))
                    {
                        _ownershipInfo.AssignOwnership(this, waitInfo);
                        return;
                    }
                }

                _signalCount = 1;
            }
            private void SignalAutoResetEvent()
            {
                s_lock.VerifyIsLocked();
                Debug.Assert(IsAutoResetEvent);

                if (IsSignaled)
                {
                    return;
                }

                for (ThreadWaitInfo.WaitedListNode waiterNode = _waitersHead, nextWaiterNode;
                     waiterNode != null;
                     waiterNode = nextWaiterNode)
                {
                    // Signaling a waiter will unregister the waiter node, but it may only abort the wait without satisfying the
                    // wait, in which case we would try to signal another waiter. So, keep the next node before trying.
                    nextWaiterNode = waiterNode.Next;

                    if (waiterNode.WaitInfo.TrySignalToSatisfyWait(waiterNode, isAbandonedMutex: false))
                    {
                        return;
                    }
                }

                _signalCount = 1;
            }
Пример #3
0
            public int SignalSemaphore(int count)
            {
                s_lock.VerifyIsLocked();
                Debug.Assert(count > 0);

                if (!IsSemaphore)
                {
                    WaitHandle.ThrowInvalidHandleException();
                }

                int oldSignalCount = _signalCount;

                Debug.Assert(oldSignalCount <= _maximumSignalCount);
                if (count > _maximumSignalCount - oldSignalCount)
                {
                    throw new SemaphoreFullException();
                }

                if (oldSignalCount != 0)
                {
                    Debug.Assert(_waitersHead == null);
                    Debug.Assert(_waitersTail == null);

                    _signalCount = oldSignalCount + count;
                    return(oldSignalCount);
                }

                for (ThreadWaitInfo.WaitedListNode waiterNode = _waitersHead, nextWaiterNode;
                     waiterNode != null;
                     waiterNode = nextWaiterNode)
                {
                    // Signaling the waiter will unregister the waiter node, so keep the next node before trying
                    nextWaiterNode = waiterNode.Next;

                    if (waiterNode.WaitInfo.TrySignalToSatisfyWait(waiterNode, isAbandonedMutex: false) && --count == 0)
                    {
                        return(oldSignalCount);
                    }
                }

                _signalCount = count;
                return(oldSignalCount);
            }
            private void SignalManualResetEvent()
            {
                s_lock.VerifyIsLocked();
                Debug.Assert(IsManualResetEvent);

                if (IsSignaled)
                {
                    return;
                }

                for (ThreadWaitInfo.WaitedListNode waiterNode = _waitersHead, nextWaiterNode;
                     waiterNode != null;
                     waiterNode = nextWaiterNode)
                {
                    // Signaling a waiter will unregister the waiter node, so keep the next node before trying
                    nextWaiterNode = waiterNode.Next;

                    waiterNode.WaitInfo.TrySignalToSatisfyWait(waiterNode, isAbandonedMutex: false);
                }

                _signalCount = 1;
            }