private IEnumerator <T> GetEnumerator(ConcurrentQueue <T> .Segment head, ConcurrentQueue <T> .Segment tail, int headLow, int tailHigh) { try { SpinWait spin = new SpinWait(); if (head == tail) { for (int i = headLow; i <= tailHigh; ++i) { spin.Reset(); while (!head.m_state[i].m_value) { spin.SpinOnce(); } yield return(head.m_array[i]); } } else { for (int i = headLow; i < 32; ++i) { spin.Reset(); while (!head.m_state[i].m_value) { spin.SpinOnce(); } yield return(head.m_array[i]); } ConcurrentQueue <T> .Segment curr; for (curr = head.Next; curr != tail; curr = curr.Next) { for (int i = 0; i < 32; ++i) { spin.Reset(); while (!curr.m_state[i].m_value) { spin.SpinOnce(); } yield return(curr.m_array[i]); } } for (int i = 0; i <= tailHigh; ++i) { spin.Reset(); while (!tail.m_state[i].m_value) { spin.SpinOnce(); } yield return(tail.m_array[i]); } curr = (ConcurrentQueue <T> .Segment)null; } } finally { Interlocked.Decrement(ref this.m_numSnapshotTakers); } }
private IEnumerator <T> GetEnumerator(ConcurrentQueue <T> .Segment head, ConcurrentQueue <T> .Segment tail, int headLow, int tailHigh) { try { SpinWait spinWait = default(SpinWait); if (head == tail) { for (int i = headLow; i <= tailHigh; i++) { spinWait.Reset(); while (!head.m_state[i].m_value) { spinWait.SpinOnce(); } yield return(head.m_array[i]); } } else { for (int j = headLow; j < 32; j++) { spinWait.Reset(); while (!head.m_state[j].m_value) { spinWait.SpinOnce(); } yield return(head.m_array[j]); } for (ConcurrentQueue <T> .Segment next = head.Next; next != tail; next = next.Next) { for (int k = 0; k < 32; k++) { spinWait.Reset(); while (!next.m_state[k].m_value) { spinWait.SpinOnce(); } yield return(next.m_array[k]); } } for (int l = 0; l <= tailHigh; l++) { spinWait.Reset(); while (!tail.m_state[l].m_value) { spinWait.SpinOnce(); } yield return(tail.m_array[l]); } } } finally { Interlocked.Decrement(ref this.m_numSnapshotTakers); } yield break; }
public void CompleteAdding() { int num; this.CheckDisposed(); if (this.IsAddingCompleted) { return; } SpinWait wait = new SpinWait(); Label_0017: num = this.m_currentAdders; if ((num & -2147483648) != 0) { wait.Reset(); while (this.m_currentAdders != -2147483648) { wait.SpinOnce(); } } else if (Interlocked.CompareExchange(ref this.m_currentAdders, num | -2147483648, num) == num) { wait.Reset(); while (this.m_currentAdders != -2147483648) { wait.SpinOnce(); } if (this.Count == 0) { this.CancelWaitingConsumers(); } this.CancelWaitingProducers(); } else { wait.SpinOnce(); goto Label_0017; } }
/// <summary> /// Helper method of GetEnumerator to seperate out yield return statement, and prevent lazy evaluation. /// </summary> private IEnumerator <T> GetEnumerator(Segment head, Segment tail, int headLow, int tailHigh) { try { SpinWait spin = new SpinWait(); if (head == tail) { for (int i = headLow; i <= tailHigh; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!head.m_state[i].m_value) { spin.SpinOnce(); } yield return(head.m_array[i]); } } else { //iterate on head segment for (int i = headLow; i < SEGMENT_SIZE; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!head.m_state[i].m_value) { spin.SpinOnce(); } yield return(head.m_array[i]); } //iterate on middle segments Segment curr = head.Next; while (curr != tail) { for (int i = 0; i < SEGMENT_SIZE; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!curr.m_state[i].m_value) { spin.SpinOnce(); } yield return(curr.m_array[i]); } curr = curr.Next; } //iterate on tail segment for (int i = 0; i <= tailHigh; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!tail.m_state[i].m_value) { spin.SpinOnce(); } yield return(tail.m_array[i]); } } } finally { // This Decrement must happen after the enumeration is over. Interlocked.Decrement(ref m_numSnapshotTakers); } }
private bool TryAddWithNoTimeValidation(T item, int millisecondsTimeout, CancellationToken cancellationToken) { int num; this.CheckDisposed(); if (cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(SR.GetString("Common_OperationCanceled"), cancellationToken); } if (this.IsAddingCompleted) { throw new InvalidOperationException(SR.GetString("BlockingCollection_Completed")); } bool flag = true; if (this.m_freeNodes != null) { CancellationTokenSource source = null; try { flag = this.m_freeNodes.Wait(0); if (!flag && (millisecondsTimeout != 0)) { source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, this.m_ProducersCancellationTokenSource.Token); flag = this.m_freeNodes.Wait(millisecondsTimeout, source.Token); } } catch (OperationCanceledException) { if (cancellationToken.IsCancellationRequested) { throw new OperationCanceledException(SR.GetString("Common_OperationCanceled"), cancellationToken); } throw new InvalidOperationException(SR.GetString("BlockingCollection_Add_ConcurrentCompleteAdd")); } finally { if (source != null) { source.Dispose(); } } } if (!flag) { return(flag); } SpinWait wait = new SpinWait(); Label_00C3: num = this.m_currentAdders; if ((num & -2147483648) != 0) { wait.Reset(); while (this.m_currentAdders != -2147483648) { wait.SpinOnce(); } throw new InvalidOperationException(SR.GetString("BlockingCollection_Completed")); } if (Interlocked.CompareExchange(ref this.m_currentAdders, num + 1, num) != num) { wait.SpinOnce(); goto Label_00C3; } try { bool flag2 = false; try { cancellationToken.ThrowIfCancellationRequested(); flag2 = this.m_collection.TryAdd(item); } catch { if (this.m_freeNodes != null) { this.m_freeNodes.Release(); } throw; } if (!flag2) { throw new InvalidOperationException(SR.GetString("BlockingCollection_Add_Failed")); } this.m_occupiedNodes.Release(); return(flag); } finally { Interlocked.Decrement(ref this.m_currentAdders); } return(flag); }
/// <summary> /// Helper method of GetEnumerator to seperate out yield return statement, and prevent lazy evaluation. /// </summary> private IEnumerator <T> GetEnumerator(Segment head, Segment tail, int headLow, int tailHigh) { try { SpinWait spin = new SpinWait(); if (head == tail) { for (int i = headLow; i <= tailHigh; i++) { // 如果位置通过添加操作被保留,但是值却未被写入,在值有效之前一直自旋 spin.Reset(); while (!head.m_state[i].m_value) { spin.SpinOnce(); } yield return(head.m_array[i]);//迭代返回数组内容 } } else { //在head segment 中的迭代器 for (int i = headLow; i < SEGMENT_SIZE; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!head.m_state[i].m_value) { spin.SpinOnce(); } yield return(head.m_array[i]); } //在中间segment的 Segment curr = head.Next; while (curr != tail) { for (int i = 0; i < SEGMENT_SIZE; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!curr.m_state[i].m_value) { spin.SpinOnce(); } yield return(curr.m_array[i]); } curr = curr.Next; } //在tail segment中的迭代器 for (int i = 0; i <= tailHigh; i++) { // If the position is reserved by an Enqueue operation, but the value is not written into, // spin until the value is available. spin.Reset(); while (!tail.m_state[i].m_value) { spin.SpinOnce(); } yield return(tail.m_array[i]); } } } finally { // 减操作一定发生在迭代完毕后 Interlocked.Decrement(ref m_numSnapshotTakers); } }