Mercurial > pub > ImplabNet
comparison 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 |
comparison
equal
deleted
inserted
replaced
96:daffa72a1cec | 97:b11c7e9d93bc |
---|---|
1 using System.Threading; | 1 using System.Threading; |
2 using System.Collections.Generic; | |
3 using System; | |
4 using System.Collections; | |
2 | 5 |
3 namespace Implab.Parallels { | 6 namespace Implab.Parallels { |
4 public class MTQueue<T> { | 7 public class MTQueue<T> : IEnumerable<T> { |
5 class Node { | 8 class Node { |
6 public Node(T value) { | 9 public Node(T value) { |
7 this.value = value; | 10 this.value = value; |
8 } | 11 } |
9 public readonly T value; | 12 public readonly T value; |
17 Thread.MemoryBarrier(); | 20 Thread.MemoryBarrier(); |
18 | 21 |
19 var last = m_last; | 22 var last = m_last; |
20 var next = new Node(value); | 23 var next = new Node(value); |
21 | 24 |
25 // Interlocaked.CompareExchange implies Thread.MemoryBarrier(); | |
26 // to ensure that the next node is completely constructed | |
22 while (last != Interlocked.CompareExchange(ref m_last, next, last)) | 27 while (last != Interlocked.CompareExchange(ref m_last, next, last)) |
23 last = m_last; | 28 last = m_last; |
24 | 29 |
25 if (last != null) | 30 if (last != null) |
26 last.next = next; | 31 last.next = next; |
67 } while (true); | 72 } while (true); |
68 | 73 |
69 value = first.value; | 74 value = first.value; |
70 return true; | 75 return true; |
71 } | 76 } |
77 | |
78 #region IEnumerable implementation | |
79 | |
80 class Enumerator : IEnumerator<T> { | |
81 Node m_current; | |
82 Node m_first; | |
83 | |
84 public Enumerator(Node first) { | |
85 m_first = first; | |
86 } | |
87 | |
88 #region IEnumerator implementation | |
89 | |
90 public bool MoveNext() { | |
91 m_current = m_current == null ? m_first : m_current.next; | |
92 return m_current != null; | |
93 } | |
94 | |
95 public void Reset() { | |
96 m_current = null; | |
97 } | |
98 | |
99 public object IEnumerator.Current { | |
100 get { | |
101 if (m_current == null) | |
102 throw new InvalidOperationException(); | |
103 return m_current.value; | |
104 } | |
105 } | |
106 | |
107 #endregion | |
108 | |
109 #region IDisposable implementation | |
110 | |
111 public void Dispose() { | |
112 } | |
113 | |
114 #endregion | |
115 | |
116 #region IEnumerator implementation | |
117 | |
118 public T Current { | |
119 get { | |
120 if (m_current == null) | |
121 throw new InvalidOperationException(); | |
122 return m_current.value; | |
123 } | |
124 } | |
125 | |
126 #endregion | |
127 } | |
128 | |
129 public IEnumerator<T> GetEnumerator() { | |
130 return new Enumerator(m_first); | |
131 } | |
132 | |
133 #endregion | |
134 | |
135 #region IEnumerable implementation | |
136 | |
137 IEnumerator IEnumerable.GetEnumerator() { | |
138 return GetEnumerator(); | |
139 } | |
140 | |
141 #endregion | |
72 } | 142 } |
73 } | 143 } |