Beispiel #1
0
 public override void Signal()
 {
     AssertOwnership();
     for (; ;)
     {
         WaitNode w = _wq.Dequeue();
         if (w == null)
         {
             return;             // no one to signal
         }
         if (w.Signal(_sync))
         {
             return;                  // notify if still waiting, else skip
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// Retrieves and removes the head of this queue, waiting if necessary
        /// until another thread inserts it.
        /// </summary>
        /// <returns> the head of this queue</returns>
        /// <exception cref="ThreadInterruptedException">
        /// if interrupted while waiting.
        /// </exception>
        public override T Take()
        {
            for (; ;)
            {
                Node node;
                bool mustWait;

                //if (Thread.interrupted()) throw new InterruptedException();
                using (_qlock.Lock())
                {
                    node     = _waitingProducers.Dequeue();
                    mustWait = (node == null);
                    if (mustWait)
                    {
                        node = _waitingConsumers.Enqueue(default(T));
                    }
                }

                if (mustWait)
                {
                    try
                    {
                        return(node.WaitForPut());
                    }
                    catch (ThreadInterruptedException e)
                    {
                        UnlinkCancelledConsumer(node);
                        throw SystemExtensions.PreserveStackTrace(e);
                    }
                }
                else
                {
                    T x;
                    if (node.GetItem(out x))
                    {
                        return(x);
                    }
                    // else cancelled, so retry
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Inserts the specified element into this queue, waiting if necessary
        /// another thread to receive it.
        /// </summary>
        /// <param name="element">the element to add</param>
        /// <exception cref="ThreadInterruptedException">
        /// if interrupted while waiting.
        /// </exception>
        public override void Put(T element)
        {
            for (; ;)
            {
                Node node;
                bool mustWait;
                //if (Thread.Interrupted) throw new InterruptedException();
                using (_qlock.Lock())
                {
                    node     = _waitingConsumers.Dequeue();
                    mustWait = (node == null);
                    if (mustWait)
                    {
                        node = _waitingProducers.Enqueue(element);
                    }
                }

                if (mustWait)
                {
                    try
                    {
                        node.WaitForTake();
                        return;
                    }
                    catch (ThreadInterruptedException tie)
                    {
                        UnlinkCancelledProducer(node);
                        throw SystemExtensions.PreserveStackTrace(tie);
                    }
                }

                else if (node.SetItem(element))
                {
                    return;
                }

                // else consumer cancelled, so retry
            }
        }
Beispiel #4
0
 private WaitNode GetSignallee(Thread caller)
 {
     lock (this)
     {
         if (caller != _owner)
         {
             throw new SynchronizationLockException("Not owner");
         }
         if (_holds >= 2) // current thread will keep the lock
         {
             --_holds;
             return(null);
         }
         var w = _wq.Dequeue();
         if (w == null) // if none, clear for new arrivals
         {
             _owner = null;
             _holds = 0;
         }
         return(w);
     }
 }