Example #1
0
        private void DoWait(Action <WaitNode> action)
        {
            int holdCount = Lock.HoldCount;

            if (holdCount == 0)
            {
                throw new SynchronizationLockException();
            }
            WaitNode n = new WaitNode();

            _wq.Enqueue(n);
            for (int i = holdCount; i > 0; i--)
            {
                Lock.Unlock();
            }
            try
            {
                action(n);
            }
            finally
            {
                for (int i = holdCount; i > 0; i--)
                {
                    Lock.Lock();
                }
            }
        }
Example #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
                }
            }
        }
Example #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
            }
        }
Example #4
0
            public bool Recheck(WaitNode node)
            {
                var caller = Thread.CurrentThread;

                lock (this)
                {
                    if (GetHold(caller))
                    {
                        return(true);
                    }
                    _wq.Enqueue(node);
                    return(false);
                }
            }