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 } } }
/// <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 } } }
/// <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 } }
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); } }