Example #1
0
        TryDequeueSlow(out result);     // slow path that needs to fix up segments

        /// <summary>Tries to dequeue an item, removing empty segments as needed.</summary>
        private bool TryDequeueSlow(out T item)
        {
            while (true)
            {
                // Get the current head
                ConcurrentQueueSegment <T> head = _head;

                // Try to take.  If we're successful, we're done.
                if (head.TryDequeue(out item))
                {
                    return(true);
                }

                // Check to see whether this segment is the last. If it is, we can consider
                // this to be a moment-in-time empty condition (even though between the TryDequeue
                // check and this check, another item could have arrived).
                if (head._nextSegment == null)
                {
                    item = default(T);
                    return(false);
                }

                // At this point we know that head.Next != null, which means
                // this segment has been frozen for additional enqueues. But between
                // the time that we ran TryDequeue and checked for a next segment,
                // another item could have been added.  Try to dequeue one more time
                // to confirm that the segment is indeed empty.
                Debug.Assert(head._frozenForEnqueues);
                if (head.TryDequeue(out item))
                {
                    return(true);
                }

                // This segment is frozen (nothing more can be added) and empty (nothing is in it).
                // Update head to point to the next segment in the list, assuming no one's beat us to it.
                lock (_crossSegmentLock)
                {
                    if (head == _head)
                    {
                        _head = head._nextSegment;
                    }
                }
            }
        }
Example #2
0
            TryDequeueSlow(out result); // slow path that needs to fix up segments

        /// <summary>Tries to dequeue an item, removing empty segments as needed.</summary>
        private bool TryDequeueSlow([MaybeNullWhen(false)] out T item)
        {
            while (true)
            {
                // Get the current head
                ConcurrentQueueSegment<T> head = _head;

                // Try to take.  If we're successful, we're done.
                if (head.TryDequeue(out item))
                {
                    return true;
                }

                // Check to see whether this segment is the last. If it is, we can consider
                // this to be a moment-in-time empty condition (even though between the TryDequeue
                // check and this check, another item could have arrived).
                if (head._nextSegment == null)
                {
                    item = default!;
Example #3
0
 /// <summary>
 /// Attempts to remove and return the object at the beginning of the <see
 /// cref="ConcurrentQueue{T}"/>.
 /// </summary>
 /// <param name="result">
 /// When this method returns, if the operation was successful, <paramref name="result"/> contains the
 /// object removed. If no object was available to be removed, the value is unspecified.
 /// </param>
 /// <returns>
 /// true if an element was removed and returned from the beginning of the
 /// <see cref="ConcurrentQueue{T}"/> successfully; otherwise, false.
 /// </returns>
 public bool TryDequeue(out T result) =>
 _head.TryDequeue(out result) || // fast-path that operates just on the head segment
 TryDequeueSlow(out result);     // slow path that needs to fix up segments