/// <summary>
            /// Dequeue
            /// </summary>
            /// <returns></returns>
            protected internal virtual LinkedNode Deq()
            {
                LinkedNode p = head;

                if (p != null && (head = p.Next) == null)
                {
                    last = null;
                }
                return(p);
            }
 /// <summary>
 /// Enqueue
 /// </summary>
 /// <param name="p">node to enqueue</param>
 protected internal virtual void  Enq(LinkedNode p)
 {
     if (last == null)
     {
         last = head = p;
     }
     else
     {
         last = last.Next = p;
     }
 }
예제 #3
0
 /// <summary> Create a queue with the given capacity</summary>
 /// <exception cref="ArgumentException"> if capacity less or equal to zero
 ///
 /// </exception>
 public BoundedLinkedQueue(int capacity)
 {
     if (capacity <= 0)
     {
         throw new ArgumentException();
     }
     capacity_          = capacity;
     putSidePutPermits_ = capacity;
     head_ = new LinkedNode(null);
     last_ = head_;
 }
예제 #4
0
        /// <summary> Create and insert a node.
        /// Call only under synch on putGuard_
        ///
        /// </summary>
        protected internal virtual void  Insert(Object x)
        {
            --putSidePutPermits_;
            LinkedNode p = new LinkedNode(x);

            lock (last_)
            {
                last_.Next = p;
                last_      = p;
            }
        }
예제 #5
0
 /// <summary>
 /// <see cref="IChannel.Peek"/>
 /// </summary>
 public virtual Object Peek()
 {
     lock (head_)
     {
         LinkedNode first = head_.Next;
         if (first != null)
         {
             return(first.Value);
         }
         else
         {
             return(null);
         }
     }
 }
예제 #6
0
 /// <summary>Main mechanics for put/offer *</summary>
 protected internal virtual void  insert(Object x)
 {
     lock (putLock_)
     {
         LinkedNode p = new LinkedNode(x);
         lock (last_)
         {
             last_.Next = p;
             last_      = p;
         }
         if (waitingForTake_ > 0)
         {
             Monitor.Pulse(putLock_);
         }
     }
 }
예제 #7
0
 /// <summary>Main mechanics for take/poll *</summary>
 protected internal virtual Object Extract()
 {
     lock (this)
     {
         lock (head_)
         {
             Object     x     = null;
             LinkedNode first = head_.Next;
             if (first != null)
             {
                 x           = first.Value;
                 first.Value = null;
                 head_       = first;
             }
             return(x);
         }
     }
 }
예제 #8
0
 /// <summary>Main mechanics for take/poll *</summary>
 protected internal virtual Object Extract()
 {
     lock (this)
     {
         lock (head_)
         {
             Object     x     = null;
             LinkedNode first = head_.Next;
             if (first != null)
             {
                 x           = first.Value;
                 first.Value = null;
                 head_       = first;
                 ++takeSidePutPermits_;
                 Monitor.Pulse(this);
             }
             return(x);
         }
     }
 }
예제 #9
0
 /// <summary>Main mechanics for put/offer *</summary>
 protected internal virtual void insert(Object x)
 {
     lock (putLock_)
     {
         LinkedNode p = new LinkedNode(x);
         lock (last_)
         {
             last_.Next = p;
             last_ = p;
         }
         if (waitingForTake_ > 0)
             Monitor.Pulse(putLock_);
     }
 }
예제 #10
0
 /// <summary>
 /// creates a new queue with a node not paired to any object
 /// </summary>
 public LinkedQueue()
 {
     head_ = new LinkedNode(null);
     last_ = head_;
 }
예제 #11
0
 /// <summary>
 /// Creates a node
 /// </summary>
 /// <param name="x">the object paired to this node</param>
 /// <param name="n">a node to link to</param>
 public LinkedNode(Object x, LinkedNode n)
 {
     Value = x; Next = n;
 }
예제 #12
0
 /// <summary>Main mechanics for take/poll *</summary>
 protected internal virtual Object Extract()
 {
     lock (this)
     {
         lock (head_)
         {
             Object x = null;
             LinkedNode first = head_.Next;
             if (first != null)
             {
                 x = first.Value;
                 first.Value = null;
                 head_ = first;
             }
             return x;
         }
     }
 }
        /*
         * Offer and poll are just like put and take, except even messier.
         */


        /// <summary>
        /// <see cref="IPuttable.Offer"/>
        /// </summary>
        public virtual bool Offer(Object x, long msecs)
        {
            if (x == null)
            {
                throw new ArgumentException();
            }
            long waitTime  = msecs;
            long startTime = 0; // lazily initialize below if needed

            for (; ;)
            {
                Utils.FailFastIfInterrupted();
                LinkedNode slot;
                LinkedNode item = null;

                lock (this)
                {
                    slot = waitingTakes.Deq();
                    if (slot == null)
                    {
                        if (waitTime <= 0)
                        {
                            return(false);
                        }
                        else
                        {
                            waitingPuts.Enq(item = new LinkedNode(x));
                        }
                    }
                }

                if (slot != null)
                {
                    lock (slot)
                    {
                        if (slot.Value != Cancelled)
                        {
                            slot.Value = x;
                            Monitor.Pulse(slot);
                            return(true);
                        }
                    }
                }

                long now = Utils.CurrentTimeMillis;
                if (startTime == 0)
                {
                    startTime = now;
                }
                else
                {
                    waitTime = msecs - (now - startTime);
                }

                if (item != null)
                {
                    lock (item)
                    {
                        try
                        {
                            for (; ;)
                            {
                                if (item.Value == null)
                                {
                                    return(true);
                                }
                                if (waitTime <= 0)
                                {
                                    item.Value = Cancelled;
                                    return(false);
                                }
                                Monitor.Wait(item, TimeSpan.FromMilliseconds(waitTime));
                                waitTime = msecs - (Utils.CurrentTimeMillis - startTime);
                            }
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            if (item.Value == null)
                            {
                                Thread.CurrentThread.Interrupt();
                                return(true);
                            }
                            else
                            {
                                item.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// <see cref="ITakable.Poll"/>
        /// </summary>
        public virtual Object Poll(long msecs)
        {
            long waitTime  = msecs;
            long startTime = 0;

            for (; ;)
            {
                Utils.FailFastIfInterrupted();
                LinkedNode item;
                LinkedNode slot = null;

                lock (this)
                {
                    item = waitingPuts.Deq();
                    if (item == null)
                    {
                        if (waitTime <= 0)
                        {
                            return(null);
                        }
                        else
                        {
                            waitingTakes.Enq(slot = new LinkedNode());
                        }
                    }
                }

                if (item != null)
                {
                    lock (item)
                    {
                        Object x = item.Value;
                        if (x != Cancelled)
                        {
                            item.Value = null;
                            item.Next  = null;
                            Monitor.Pulse(item);
                            return(x);
                        }
                    }
                }

                long now = Utils.CurrentTimeMillis;
                if (startTime == 0)
                {
                    startTime = now;
                }
                else
                {
                    waitTime = msecs - (now - startTime);
                }

                if (slot != null)
                {
                    lock (slot)
                    {
                        try
                        {
                            for (; ;)
                            {
                                Object x = slot.Value;
                                if (x != null)
                                {
                                    slot.Value = null;
                                    slot.Next  = null;
                                    return(x);
                                }
                                if (waitTime <= 0)
                                {
                                    slot.Value = Cancelled;
                                    return(null);
                                }
                                Monitor.Wait(slot, TimeSpan.FromMilliseconds(waitTime));
                                waitTime = msecs - (Utils.CurrentTimeMillis - startTime);
                            }
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            Object x = slot.Value;
                            if (x != null)
                            {
                                slot.Value = null;
                                slot.Next  = null;
                                Thread.CurrentThread.Interrupt();
                                return(x);
                            }
                            else
                            {
                                slot.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// <see cref="IPuttable.Put"/>
        /// </summary>
        public virtual void  Put(Object x)
        {
            if (x == null)
            {
                throw new ArgumentException();
            }

            // This code is conceptually straightforward, but messy
            // because we need to intertwine handling of put-arrives first
            // vs take-arrives first cases.

            // Outer loop is to handle retry due to cancelled waiting taker
            for (; ;)
            {
                // Get out now if we are interrupted
                Utils.FailFastIfInterrupted();
                // Exactly one of item or slot will be nonnull at end of
                // synchronized block, depending on whether a put or a take
                // arrived first.
                LinkedNode slot;
                LinkedNode item = null;

                lock (this)
                {
                    // Try to match up with a waiting taker; fill and signal it below
                    slot = waitingTakes.Deq();

                    // If no takers yet, create a node and wait below
                    if (slot == null)
                    {
                        waitingPuts.Enq(item = new LinkedNode(x));
                    }
                }

                if (slot != null)
                {
                    // There is a waiting taker.
                    // Fill in the slot created by the taker and signal taker to
                    // continue.
                    lock (slot)
                    {
                        if (slot.Value != Cancelled)
                        {
                            slot.Value = x;
                            Monitor.Pulse(slot);
                            return;
                        }
                        // else the taker has cancelled, so retry outer loop
                    }
                }
                else
                {
                    // Wait for a taker to arrive and take the item.
                    lock (item)
                    {
                        try
                        {
                            while (item.Value != null)
                            {
                                Monitor.Wait(item);
                            }
                            return;
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            // If item was taken, return normally but set interrupt status
                            if (item.Value == null)
                            {
                                Thread.CurrentThread.Interrupt();
                                return;
                            }
                            else
                            {
                                item.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// <see cref="ITakable.Poll"/>
        /// </summary>
        public virtual Object Poll(long msecs)
        {
            long waitTime = msecs;
            long startTime = 0;

            for (; ; )
            {
                Utils.FailFastIfInterrupted();
                LinkedNode item;
                LinkedNode slot = null;

                lock (this)
                {
                    item = waitingPuts.Deq();
                    if (item == null)
                    {
                        if (waitTime <= 0)
                            return null;
                        else
                            waitingTakes.Enq(slot = new LinkedNode());
                    }
                }

                if (item != null)
                {
                    lock (item)
                    {
                        Object x = item.Value;
                        if (x != Cancelled)
                        {
                            item.Value = null;
                            item.Next = null;
                            Monitor.Pulse(item);
                            return x;
                        }
                    }
                }

                long now = Utils.CurrentTimeMillis;
                if (startTime == 0)
                    startTime = now;
                else
                    waitTime = msecs - (now - startTime);

                if (slot != null)
                {
                    lock (slot)
                    {
                        try
                        {
                            for (; ; )
                            {
                                Object x = slot.Value;
                                if (x != null)
                                {
                                    slot.Value = null;
                                    slot.Next = null;
                                    return x;
                                }
                                if (waitTime <= 0)
                                {
                                    slot.Value = Cancelled;
                                    return null;
                                }
                                Monitor.Wait(slot, TimeSpan.FromMilliseconds(waitTime));
                                waitTime = msecs - (Utils.CurrentTimeMillis - startTime);
                            }
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            Object x = slot.Value;
                            if (x != null)
                            {
                                slot.Value = null;
                                slot.Next = null;
                                Thread.CurrentThread.Interrupt();
                                return x;
                            }
                            else
                            {
                                slot.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
예제 #17
0
 /// <summary>Main mechanics for take/poll *</summary>
 protected internal virtual Object Extract()
 {
     lock (this)
     {
         lock (head_)
         {
             Object x = null;
             LinkedNode first = head_.Next;
             if (first != null)
             {
                 x = first.Value;
                 first.Value = null;
                 head_ = first;
                 ++takeSidePutPermits_;
                 Monitor.Pulse(this);
             }
             return x;
         }
     }
 }
예제 #18
0
 /// <summary>
 /// Creates a node
 /// </summary>
 /// <param name="x">the object paired to this node</param>
 /// <param name="n">a node to link to</param>
 public LinkedNode(Object x, LinkedNode n)
 {
     Value = x; Next = n;
 }
예제 #19
0
 /// <summary>
 /// creates a new queue with a node not paired to any object
 /// </summary>
 public LinkedQueue()
 {
     head_ = new LinkedNode(null);
     last_ = head_;
 }
        /// <summary>
        /// <see cref="ITakable.Take"/>
        /// </summary>
        public virtual Object Take()
        {
            // Entirely symmetric to put()

            for (; ; )
            {
                Utils.FailFastIfInterrupted();
                LinkedNode item;
                LinkedNode slot = null;

                lock (this)
                {
                    item = waitingPuts.Deq();
                    if (item == null)
                        waitingTakes.Enq(slot = new LinkedNode());
                }

                if (item != null)
                {
                    lock (item)
                    {
                        Object x = item.Value;
                        if (x != Cancelled)
                        {
                            item.Value = null;
                            item.Next = null;
                            Monitor.Pulse(item);
                            return x;
                        }
                    }
                }
                else
                {
                    lock (slot)
                    {
                        try
                        {
                            for (; ; )
                            {
                                Object x = slot.Value;
                                if (x != null)
                                {
                                    slot.Value = null;
                                    slot.Next = null;
                                    return x;
                                }
                                else
                                    Monitor.Wait(slot);
                            }
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            Object x = slot.Value;
                            if (x != null)
                            {
                                slot.Value = null;
                                slot.Next = null;
                                Thread.CurrentThread.Interrupt();
                                return x;
                            }
                            else
                            {
                                slot.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// <see cref="IPuttable.Put"/>
        /// </summary>
        public virtual void Put(Object x)
        {
            if (x == null)
                throw new ArgumentException();

            // This code is conceptually straightforward, but messy
            // because we need to intertwine handling of put-arrives first
            // vs take-arrives first cases.

            // Outer loop is to handle retry due to cancelled waiting taker
            for (; ; )
            {

                // Get out now if we are interrupted
                Utils.FailFastIfInterrupted();
                // Exactly one of item or slot will be nonnull at end of
                // synchronized block, depending on whether a put or a take
                // arrived first.
                LinkedNode slot;
                LinkedNode item = null;

                lock (this)
                {
                    // Try to match up with a waiting taker; fill and signal it below
                    slot = waitingTakes.Deq();

                    // If no takers yet, create a node and wait below
                    if (slot == null)
                        waitingPuts.Enq(item = new LinkedNode(x));
                }

                if (slot != null)
                {
                    // There is a waiting taker.
                    // Fill in the slot created by the taker and signal taker to
                    // continue.
                    lock (slot)
                    {
                        if (slot.Value != Cancelled)
                        {
                            slot.Value = x;
                            Monitor.Pulse(slot);
                            return ;
                        }
                        // else the taker has cancelled, so retry outer loop
                    }
                }
                else
                {
                    // Wait for a taker to arrive and take the item.
                    lock (item)
                    {
                        try
                        {
                            while (item.Value != null)
                                Monitor.Wait(item);
                            return ;
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            // If item was taken, return normally but set interrupt status
                            if (item.Value == null)
                            {
                                Thread.CurrentThread.Interrupt();
                                return ;
                            }
                            else
                            {
                                item.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
예제 #22
0
 /// <summary> Create and insert a node.
 /// Call only under synch on putGuard_
 /// 
 /// </summary>
 protected internal virtual void Insert(Object x)
 {
     --putSidePutPermits_;
     LinkedNode p = new LinkedNode(x);
     lock (last_)
     {
         last_.Next = p;
         last_ = p;
     }
 }
        /// <summary>
        /// <see cref="ITakable.Take"/>
        /// </summary>
        public virtual Object Take()
        {
            // Entirely symmetric to put()

            for (; ;)
            {
                Utils.FailFastIfInterrupted();
                LinkedNode item;
                LinkedNode slot = null;

                lock (this)
                {
                    item = waitingPuts.Deq();
                    if (item == null)
                    {
                        waitingTakes.Enq(slot = new LinkedNode());
                    }
                }

                if (item != null)
                {
                    lock (item)
                    {
                        Object x = item.Value;
                        if (x != Cancelled)
                        {
                            item.Value = null;
                            item.Next  = null;
                            Monitor.Pulse(item);
                            return(x);
                        }
                    }
                }
                else
                {
                    lock (slot)
                    {
                        try
                        {
                            for (; ;)
                            {
                                Object x = slot.Value;
                                if (x != null)
                                {
                                    slot.Value = null;
                                    slot.Next  = null;
                                    return(x);
                                }
                                else
                                {
                                    Monitor.Wait(slot);
                                }
                            }
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            Object x = slot.Value;
                            if (x != null)
                            {
                                slot.Value = null;
                                slot.Next  = null;
                                Thread.CurrentThread.Interrupt();
                                return(x);
                            }
                            else
                            {
                                slot.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Dequeue
 /// </summary>
 /// <returns></returns>
 protected internal virtual LinkedNode Deq()
 {
     LinkedNode p = head;
     if (p != null && (head = p.Next) == null)
         last = null;
     return p;
 }
        /*
        Offer and poll are just like put and take, except even messier.
        */
        /// <summary>
        /// <see cref="IPuttable.Offer"/>
        /// </summary>
        public virtual bool Offer(Object x, long msecs)
        {
            if (x == null)
                throw new ArgumentException();
            long waitTime = msecs;
            long startTime = 0; // lazily initialize below if needed

            for (; ; )
            {
                Utils.FailFastIfInterrupted();
                LinkedNode slot;
                LinkedNode item = null;

                lock (this)
                {
                    slot = waitingTakes.Deq();
                    if (slot == null)
                    {
                        if (waitTime <= 0)
                            return false;
                        else
                            waitingPuts.Enq(item = new LinkedNode(x));
                    }
                }

                if (slot != null)
                {
                    lock (slot)
                    {
                        if (slot.Value != Cancelled)
                        {
                            slot.Value = x;
                            Monitor.Pulse(slot);
                            return true;
                        }
                    }
                }

                long now = Utils.CurrentTimeMillis;
                if (startTime == 0)
                    startTime = now;
                else
                    waitTime = msecs - (now - startTime);

                if (item != null)
                {
                    lock (item)
                    {
                        try
                        {
                            for (; ; )
                            {
                                if (item.Value == null)
                                    return true;
                                if (waitTime <= 0)
                                {
                                    item.Value = Cancelled;
                                    return false;
                                }
                                Monitor.Wait(item, TimeSpan.FromMilliseconds(waitTime));
                                waitTime = msecs - (Utils.CurrentTimeMillis - startTime);
                            }
                        }
                        catch (ThreadInterruptedException ie)
                        {
                            if (item.Value == null)
                            {
                                Thread.CurrentThread.Interrupt();
                                return true;
                            }
                            else
                            {
                                item.Value = Cancelled;
                                throw SystemExtensions.PreserveStackTrace(ie);
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Enqueue
 /// </summary>
 /// <param name="p">node to enqueue</param>
 protected internal virtual void Enq(LinkedNode p)
 {
     if (last == null)
         last = head = p;
     else
         last = last.Next = p;
 }
예제 #27
0
 /// <summary> Create a queue with the given capacity</summary>
 /// <exception cref="ArgumentException"> if capacity less or equal to zero
 /// 
 /// </exception>
 public BoundedLinkedQueue(int capacity)
 {
     if (capacity <= 0)
         throw new ArgumentException();
     capacity_ = capacity;
     putSidePutPermits_ = capacity;
     head_ = new LinkedNode(null);
     last_ = head_;
 }