private void AsyncUnlink(DListNode waiter) { lock (_lock) { DListNode.RemoveIfInserted(waiter); } }
private void SyncUnlink(DListNode waiter) { lock (_lock) { DListNode.RemoveIfInserted(waiter); MonitorEx.PulseAll(_lock, waiter); } }
private bool TrySetStateAndRemoveWaiter(Waiter <Data> waiter, int state) { bool res = waiter.TrySetState(state); if (res) { DListNode.RemoveIfInserted(waiter); } return(res); }
public void Release() { Waiter toFinish = null; lock (_lock) { if (currentPermits + 1 > maxPermits) { throw new ArgumentOutOfRangeException("releases"); } currentPermits += 1; Waiter waiter; while ((waiter = (Waiter)DListNode.FirstEntry(waiters)) != null) { if (Volatile.Read(ref waiter.state) != WAITING) { DListNode.RemoveIfInserted(waiter); continue; } if (waiter.TrySetState(SUCCESS)) { DListNode.RemoveIfInserted(waiter); currentPermits -= 1; toFinish = waiter; break; } } } // finish it outside the lock if (toFinish != null) { // cancel the active cancelers if (toFinish.ctkReg != null) { toFinish.ctkReg.Dispose(); } if (toFinish.timer != null) { toFinish.timer.Dispose(); } toFinish.tcs.SetResult(true); } }
public void OnCancellation(object state) { var waiter = (Waiter)state; if (waiter.TrySetState(CANCELED)) { if (DListNode.IsInList(waiter)) { lock (_lock) { DListNode.RemoveIfInserted(waiter); } } if (waiter.timer != null) { waiter.timer.Dispose(); } waiter.tcs.SetCanceled(); } }
public void OnTimeout(object state) { var waiter = (Waiter)state; if (waiter.TrySetState(CANCELED)) { if (DListNode.IsInList(waiter)) { lock (_lock) { DListNode.RemoveIfInserted(waiter); } } if (waiter.ctkReg != null) { waiter.ctkReg.Dispose(); } waiter.timer.Dispose(); waiter.tcs.SetResult(false); } }
public void Release() { Waiter <Data> toFinish = null; lock (_lock) { if (currentPermits + 1 > maxPermits) { throw new ArgumentOutOfRangeException("releases"); } currentPermits += 1; Waiter <Data> waiter; while ((waiter = (Waiter <Data>)DListNode.FirstEntry(waiters)) != null) { if (Volatile.Read(ref waiter.state) != WaiterState.WAITING) { // Shouldn't already be on the queue, ensure it is removed DListNode.RemoveIfInserted(waiter); continue; } if (waiter.TrySetStateAndUnlink(WaiterState.SUCCESS)) { currentPermits -= 1; // queue node for further processing outside the lock waiter.prev = toFinish; toFinish = waiter; break; } } } // finish the stack of satisfied requests while (toFinish != null) { toFinish.OnSuccess(); toFinish = (Waiter <Data>)toFinish.prev; } }