public bool Acquire(int units, int timeout) { Monitor.Enter(mon); try { if (q.Count == 0 && counter >= units) { counter -= units; return(true); } if (!TimeoutInstant.ShouldWait(timeout)) { return(false); } var node = q.AddLast(new Request(units)); var toi = new TimeoutInstant(timeout); while (true) { try { SyncUtils.Wait(mon, node.Value.condition, toi.Remaining); } catch (ThreadInterruptedException) { if (node.Value.ready) { Thread.CurrentThread.Interrupt(); return(true); } q.Remove(node); grantAllAvailable(); throw; } if (node.Value.ready) { return(true); } if (toi.IsTimeout) { q.Remove(node); grantAllAvailable(); return(false); } } } finally { Monitor.Exit(mon); } }
public bool Wait(int timeout) { if (signaled) { return(true); } if (!TimeoutInstant.ShouldWait(timeout)) { return(false); } lock (mon) { waiters += 1; Interlocked.MemoryBarrier(); if (signaled == true) { waiters -= 1; return(true); } TimeoutInstant ti = new TimeoutInstant(timeout); int myVersion = setVersion; while (true) { try { Monitor.Wait(mon, ti.Remaining); } catch (Exception) { waiters -= 1; throw; } if (signaled || myVersion != setVersion) { waiters -= 1; return(true); } if (ti.IsTimeout) { waiters -= 1; return(false); } } } }