##// END OF EJS Templates
fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.

File last commit:

r98:4c945d94b9ab v2
r196:40d7fed4a09e default
Show More
MTQueue.cs
143 lines | 4.2 KiB | text/x-csharp | CSharpLexer
cin
improved tracing...
r93 using System.Threading;
cin
added enumerable interface to MTQueue
r97 using System.Collections.Generic;
using System;
using System.Collections;
cin
Implemented interllocked queue...
r14
namespace Implab.Parallels {
cin
added enumerable interface to MTQueue
r97 public class MTQueue<T> : IEnumerable<T> {
cin
Implemented interllocked queue...
r14 class Node {
public Node(T value) {
this.value = value;
}
public readonly T value;
public Node next;
}
Node m_first;
Node m_last;
public void Enqueue(T value) {
cin
added memory barriers
r80 Thread.MemoryBarrier();
cin
Implemented interllocked queue...
r14 var last = m_last;
var next = new Node(value);
cin
added enumerable interface to MTQueue
r97 // Interlocaked.CompareExchange implies Thread.MemoryBarrier();
// to ensure that the next node is completely constructed
cin
Implemented interllocked queue...
r14 while (last != Interlocked.CompareExchange(ref m_last, next, last))
last = m_last;
if (last != null)
last.next = next;
else
m_first = next;
}
public bool TryDequeue(out T value) {
Node first;
cin
improved tracing...
r93 Node next;
cin
Implemented interllocked queue...
r14 value = default(T);
cin
added memory barriers
r80 Thread.MemoryBarrier();
cin
Implemented interllocked queue...
r14 do {
first = m_first;
if (first == null)
return false;
next = first.next;
if (next == null) {
// this is the last element,
cin
Promise is rewritten to use interlocked operations instead of locks
r19 // then try to update the tail
cin
Implemented interllocked queue...
r14 if (first != Interlocked.CompareExchange(ref m_last, null, first)) {
cin
code cleanup
r71 // this is the race condition
cin
Implemented interllocked queue...
r14 if (m_last == null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 // the queue is empty
cin
Implemented interllocked queue...
r14 return false;
cin
code cleanup
r71 // tail has been changed, we need to restart
cin
Implemented interllocked queue...
r14 continue;
}
// tail succesfully updated and first.next will never be changed
cin
code cleanup
r71 // other readers will fail due to inconsistency m_last != m_fist && m_first.next == null
// however the parallel writer may update the m_first since the m_last is null
cin
Implemented interllocked queue...
r14
cin
code cleanup
r71 // so we need to fix inconsistency by setting m_first to null or if it has been
// updated by the writer already then we should just to give up
cin
Implemented interllocked queue...
r14 Interlocked.CompareExchange(ref m_first, null, first);
break;
}
cin
improved tracing...
r93 if (first == Interlocked.CompareExchange(ref m_first, next, first))
// head succesfully updated
break;
cin
Implemented interllocked queue...
r14 } while (true);
value = first.value;
return true;
}
cin
added enumerable interface to MTQueue
r97
#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;
}
cin
fix MTQueue syntax error
r98 object IEnumerator.Current {
cin
added enumerable interface to MTQueue
r97 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
cin
Implemented interllocked queue...
r14 }
}