/** * Auxiliary methods */ /** * Returns the list of all pending async acquires that can be satisfied with * the current number of permits owned by the semaphore. * * Note: Tis method is called when the current thread owns the lock. */ private List <AsyncAcquire> SatisfyPendingAsyncAcquires() { List <AsyncAcquire> satisfied = null; while (asyncAcquires.Count > 0) { AsyncAcquire acquire = asyncAcquires.First.Value; // Check if available permits allow satisfy this request if (acquire.acquires > permits) { break; } // Remove the request from the queue asyncAcquires.RemoveFirst(); // Try lock the request and complete it if succeeded if (acquire.TryLock()) { permits -= acquire.acquires; if (satisfied == null) { satisfied = new List <AsyncAcquire>(1); } satisfied.Add(acquire); } } return(satisfied); }
/** * Try to cancel an async acquire request */ private void AcquireCancellationHandler(object _acquireNode, bool canceling) { LinkedListNode <AsyncAcquire> acquireNode = (LinkedListNode <AsyncAcquire>)_acquireNode; AsyncAcquire acquire = acquireNode.Value; if (acquire.TryLock()) { List <AsyncAcquire> satisfied = null; // To access shared mutable state we must acquire the lock lock (theLock) { if (acquireNode.List != null) { asyncAcquires.Remove(acquireNode); } if (asyncAcquires.Count > 0 && permits >= asyncAcquires.First.Value.acquires) { satisfied = SatisfyPendingAsyncAcquires(); } } // Complete the satisfied async acquires CompleteSatisfiedAsyncAcquires(satisfied); // Release the resources associated with the async acquire. acquire.Dispose(canceling); // Complete the TaskCompletionSource to RanToCompletion (timeout) // or Canceled final state. if (canceling) { acquire.SetCanceled(); } else { acquire.SetResult(false); } } }