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; }
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; }