diff Implab/Parallels/MTQueue.cs @ 97:b11c7e9d93bc v2

added enumerable interface to MTQueue
author cin
date Fri, 31 Oct 2014 17:34:54 +0300
parents dc4942d09e74
children 4c945d94b9ab
line wrap: on
line diff
--- a/Implab/Parallels/MTQueue.cs	Thu Oct 30 10:06:16 2014 +0300
+++ b/Implab/Parallels/MTQueue.cs	Fri Oct 31 17:34:54 2014 +0300
@@ -1,7 +1,10 @@
 using System.Threading;
+using System.Collections.Generic;
+using System;
+using System.Collections;
 
 namespace Implab.Parallels {
-    public class MTQueue<T> {
+    public class MTQueue<T> : IEnumerable<T> {
         class Node {
             public Node(T value) {
                 this.value = value;
@@ -19,6 +22,8 @@
             var last = m_last;
             var next = new Node(value);
 
+            // Interlocaked.CompareExchange implies Thread.MemoryBarrier();
+            // to ensure that the next node is completely constructed
             while (last != Interlocked.CompareExchange(ref m_last, next, last))
                 last = m_last;
 
@@ -69,5 +74,70 @@
             value = first.value;
             return true;
         }
+
+        #region IEnumerable implementation
+
+        class Enumerator : IEnumerator<T> {
+            Node m_current;
+            Node m_first;
+
+            public Enumerator(Node first) {
+                m_first = first;
+            }
+
+            #region IEnumerator implementation
+
+            public bool MoveNext() {
+                m_current = m_current == null ? m_first : m_current.next;
+                return m_current != null;
+            }
+
+            public void Reset() {
+                m_current = null;
+            }
+
+            public object IEnumerator.Current {
+                get {
+                    if (m_current == null)
+                        throw new InvalidOperationException();
+                    return m_current.value;
+                }
+            }
+
+            #endregion
+
+            #region IDisposable implementation
+
+            public void Dispose() {
+            }
+
+            #endregion
+
+            #region IEnumerator implementation
+
+            public T Current {
+                get {
+                    if (m_current == null)
+                        throw new InvalidOperationException();
+                    return m_current.value;
+                }
+            }
+
+            #endregion
+        }
+
+        public IEnumerator<T> GetEnumerator() {
+            return new Enumerator(m_first);
+        }
+
+        #endregion
+
+        #region IEnumerable implementation
+
+        IEnumerator IEnumerable.GetEnumerator() {
+            return GetEnumerator();
+        }
+
+        #endregion
     }
 }