/// <summary> /// Retrieves and removes the head of this queue, waiting up to the /// specified wait time if necessary for an element to become available. /// </summary> /// <param name="element"> /// Set to the head of this queue. <c>default(T)</c> if queue is empty. /// </param> /// <param name="duration">How long to wait before giving up.</param> /// <returns> /// <c>false</c> if the queue is still empty after waited for the time /// specified by the <paramref name="duration"/>. Otherwise <c>true</c>. /// </returns> public override bool Poll(TimeSpan duration, out T element) { DateTime deadline = WaitTime.Deadline(duration); using (_lock.LockInterruptibly()) { while (!_wrapped.Poll(out element)) { if (duration.Ticks <= 0) { element = default(T); return(false); } try { _notEmptyCondition.Await(WaitTime.Cap(duration)); duration = deadline.Subtract(DateTime.UtcNow); } catch (ThreadInterruptedException e) { _notEmptyCondition.Signal(); throw SystemExtensions.PreserveStackTrace(e); } } _notFullCondition.Signal(); return(true); } }
private bool Attempt(TimeSpan duration) { if (_state != 0) { return(true); } if (duration.Ticks <= 0) { _state = Cancel; Monitor.Pulse(this); return(false); } DateTime deadline = WaitTime.Deadline(duration); while (true) { Monitor.Wait(this, WaitTime.Cap(duration)); if (_state != 0) { return(true); } duration = deadline.Subtract(DateTime.UtcNow); if (duration.Ticks <= 0) { _state = Cancel; Monitor.Pulse(this); return(false); } } }
/// <summary> /// Retrieves and removes the head of this queue, waiting if necessary /// until an element with an expired delay is available on this queue, /// or the specified wait time expires. /// </summary> /// <param name="duration">How long to wait before giving up.</param> /// <param name="element"> /// Set to the head of this queue, or <c>default(T)</c> if the specified /// waiting time elapses before an element with an expired delay becomes /// available /// </param> /// <returns> /// <c>false</c> if the specified waiting time elapses before an element /// is available. Otherwise <c>true</c>. /// </returns> public override bool Poll(TimeSpan duration, out T element) { lock (_lock) { DateTime deadline = WaitTime.Deadline(duration); for (; ;) { T first; if (!_queue.Peek(out first)) { if (duration.Ticks <= 0) { element = default(T); return(false); } Monitor.Wait(_lock, WaitTime.Cap(duration)); duration = deadline.Subtract(DateTime.UtcNow); } else { TimeSpan delay = first.GetRemainingDelay(); if (delay.Ticks > 0) { if (duration.Ticks <= 0) { element = default(T); return(false); } if (delay > duration) { delay = duration; } Monitor.Wait(_lock, WaitTime.Cap(delay)); duration = deadline.Subtract(DateTime.UtcNow); } else { T x; bool hasOne = _queue.Poll(out x); Debug.Assert(hasOne); if (_queue.Count != 0) { Monitor.PulseAll(_lock); } element = x; return(true); } } } } }
/// <summary> /// Inserts the specified element into this queue, waiting up to the /// specified wait time if necessary for space to become available. /// </summary> /// <param name="element">the element to add</param> /// <param name="duration">how long to wait before giving up</param> /// <returns> <c>true</c> if successful, or <c>false</c> if /// the specified waiting time elapses before space is available /// </returns> /// <exception cref="System.InvalidOperationException"> /// If the element cannot be added at this time due to capacity restrictions. /// </exception> /// <exception cref="ThreadInterruptedException"> /// if interrupted while waiting. /// </exception> public override bool Offer(T element, TimeSpan duration) { var deadline = WaitTime.Deadline(duration); int tempCount; lock (_putLock) { for (;;) { if (_isBroken) { return(false); } if (_activeCount < _capacity) { Insert(element); lock (this) { tempCount = _activeCount++; } if (tempCount + 1 < _capacity) { Monitor.Pulse(_putLock); } break; } if (duration.Ticks <= 0) { return(false); } try { Monitor.Wait(_putLock, WaitTime.Cap(duration)); duration = deadline.Subtract(DateTime.UtcNow); } catch (ThreadInterruptedException e) { Monitor.Pulse(_putLock); throw e.PreserveStackTrace(); } } } if (tempCount == 0) { SignalNotEmpty(); } return(true); }
/// <summary> /// Retrieves and removes the head of this queue, waiting up to the /// specified wait time if necessary for an element to become available. /// </summary> /// <param name="element"> /// Set to the head of this queue. <c>default(T)</c> if queue is empty. /// </param> /// <param name="duration">How long to wait before giving up.</param> /// <returns> /// <c>false</c> if the queue is still empty after waited for the time /// specified by the <paramref name="duration"/>. Otherwise <c>true</c>. /// </returns> public override bool Poll(TimeSpan duration, out T element) { var deadline = WaitTime.Deadline(duration); T x; int c; lock (_takeLock) { for (;;) { if (_activeCount > 0) { x = Extract(); lock (this) { c = _activeCount--; } if (c > 1) { Monitor.Pulse(_takeLock); } break; } if (duration.Ticks <= 0 || _isBroken) { element = default(T); return(false); } try { Monitor.Wait(_takeLock, WaitTime.Cap(duration)); duration = deadline.Subtract(DateTime.UtcNow); } catch (ThreadInterruptedException e) { Monitor.Pulse(_takeLock); throw e.PreserveStackTrace(); } } } if (c == _capacity) { SignalNotFull(); } element = x; return(true); }