/// <summary> /// Pushes an item onto the queue. If the queue has reached /// capacity, the call will pend until the queue has space to /// receive the request. /// </summary> /// <param name="item"></param> public void Push(T item) { if (_maxLength != int.MaxValue) { if (!BoundBlockingQueueOverride.IsEngaged) { for (int ii = 0; Interlocked.Read(ref _count) > _maxLength;) { SlimLock.SmartWait(++ii); } } } // Create the new node var node = new Node(item); // Get the write node for the thread Node branch = _wnode; for (; ;) { Node temp; while ((temp = branch.Next) != null) { branch = temp; // temp is guaranteed to not be null } var pnode = Interlocked.CompareExchange( ref branch.Next, node, null); if (pnode == null) { _wnode = node; // Check for threads that have been waiting a long time ... these // threads will be using a slowLockInterest rather than a tight spin // loop. if (Interlocked.Read(ref _slowLockInterest) > 0) { lock (_slowLock) { Monitor.Pulse(_slowLock); } } // Increment the counter Interlocked.Increment(ref _count); return; } } }
/// <summary> /// Waits for completion of the future. /// </summary> /// <param name="timeOut"></param> /// <returns></returns> public bool Wait(TimeSpan timeOut) { var timeCur = PerformanceObserver.MilliTime; var timeEnd = timeCur + timeOut.TotalMilliseconds; for (var ii = 0; !HasValue; ii++) { timeCur = PerformanceObserver.MilliTime; if (timeCur > timeEnd) { return(false); } SlimLock.SmartWait(ii); } return(true); }