public void UnregisterWait(WaitableObject waitableObject) { s_lock.VerifyIsLocked(); Debug.Assert(waitableObject != null); WaitedListNode previous = _previous; WaitedListNode next = _next; if (previous != null) { previous._next = next; _previous = null; } else { Debug.Assert(waitableObject.WaitersHead == this); waitableObject.WaitersHead = next; } if (next != null) { next._previous = previous; _next = null; } else { Debug.Assert(waitableObject.WaitersTail == this); waitableObject.WaitersTail = previous; } }
public void RegisterPrioritizedWait(WaitableObject waitableObject) { s_lock.VerifyIsLocked(); Debug.Assert(_waitInfo.Thread == Thread.CurrentThread); Debug.Assert(waitableObject != null); Debug.Assert(_previous == null); Debug.Assert(_next == null); WaitedListNode head = waitableObject.WaitersHead; if (head != null) { _next = head; head._previous = this; } else { waitableObject.WaitersTail = this; } waitableObject.WaitersHead = this; }
public void RegisterWait(WaitableObject waitableObject) { s_lock.VerifyIsLocked(); Debug.Assert(_waitInfo.Thread == Thread.CurrentThread); Debug.Assert(waitableObject != null); Debug.Assert(_previous == null); Debug.Assert(_next == null); WaitedListNode tail = waitableObject.WaitersTail; if (tail != null) { _previous = tail; tail._next = this; } else { waitableObject.WaitersHead = this; } waitableObject.WaitersTail = this; }
private WaitedListNode[] GetWaitedListNodeArray(int requiredCapacity) { Debug.Assert(_thread == Thread.CurrentThread); Debug.Assert(_waitedCount == 0); int currentLength = _waitedListNodes.Length; if (currentLength < requiredCapacity) { WaitedListNode[] newItems = new WaitedListNode[Math.Max(requiredCapacity, Math.Min(WaitHandle.MaxWaitHandles, 2 * currentLength))]; Array.Copy(_waitedListNodes, 0, newItems, 0, currentLength); for (int i = currentLength; i < newItems.Length; i++) { newItems[i] = new WaitedListNode(this, i); } _waitedListNodes = newItems; } return(_waitedListNodes); }
public bool TrySignalToSatisfyWait(WaitedListNode registeredListNode, bool isAbandonedMutex) { s_lock.VerifyIsLocked(); Debug.Assert(_thread != Thread.CurrentThread); Debug.Assert(registeredListNode != null); Debug.Assert(registeredListNode.WaitInfo == this); Debug.Assert(registeredListNode.WaitedObjectIndex >= 0); Debug.Assert(registeredListNode.WaitedObjectIndex < _waitedCount); Debug.Assert(_waitedCount > (_isWaitForAll ? 1 : 0)); int signaledWaitedObjectIndex = registeredListNode.WaitedObjectIndex; bool isWaitForAll = _isWaitForAll; bool wouldAnyMutexReacquireCountOverflow = false; if (isWaitForAll) { // Determine if all waits would be satisfied if (!WaitableObject.WouldWaitForAllBeSatisfiedOrAborted( _thread, _waitedObjects, _waitedCount, signaledWaitedObjectIndex, ref wouldAnyMutexReacquireCountOverflow, ref isAbandonedMutex)) { return(false); } } // The wait would be satisfied. Before making changes to satisfy the wait, acquire the monitor and verify that // the thread can accept a signal. _waitMonitor.Acquire(); if (!IsWaiting) { _waitMonitor.Release(); return(false); } if (isWaitForAll && !wouldAnyMutexReacquireCountOverflow) { // All waits would be satisfied, accept the signals WaitableObject.SatisfyWaitForAll(this, _waitedObjects, _waitedCount, signaledWaitedObjectIndex); } UnregisterWait(); Debug.Assert(_waitedObjectIndexThatSatisfiedWait < 0); if (wouldAnyMutexReacquireCountOverflow) { _waitSignalState = WaitSignalState.NotWaiting_SignaledToAbortWaitDueToMaximumMutexReacquireCount; } else { _waitedObjectIndexThatSatisfiedWait = signaledWaitedObjectIndex; _waitSignalState = isAbandonedMutex ? WaitSignalState.NotWaiting_SignaledToSatisfyWaitWithAbandonedMutex : WaitSignalState.NotWaiting_SignaledToSatisfyWait; } _waitMonitor.Signal_Release(); return(!wouldAnyMutexReacquireCountOverflow); }