예제 #1
0
        /// <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);
            }
        }
예제 #2
0
            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);
                    }
                }
            }
예제 #3
0
 /// <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);
                 }
             }
         }
     }
 }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }