Commit df6523ef authored by Marc Gravell's avatar Marc Gravell

Preserve order: didn't (quite); fixed

parent d80ca807
......@@ -110,8 +110,14 @@ private static void ProcessAsyncCompletionQueue(object state)
}
partial void OnCompletedAsync();
int activeAsyncWorkerThread = 0;
private void ProcessAsyncCompletionQueueImpl()
{
int currentThread = Environment.CurrentManagedThreadId;
try
{
if (Interlocked.CompareExchange(ref activeAsyncWorkerThread, currentThread, 0) != 0) return;
int total = 0;
do
{
......@@ -121,32 +127,41 @@ private void ProcessAsyncCompletionQueueImpl()
next = asyncCompletionQueue.Count == 0 ? null
: asyncCompletionQueue.Dequeue();
}
if(next == null && Thread.Yield()) // give it a moment and try again
if (next == null)
{
// give it a moment and try again, noting that we might lose the battle
// when we pause
Interlocked.CompareExchange(ref activeAsyncWorkerThread, 0, currentThread);
if (Thread.Yield() && Interlocked.CompareExchange(ref activeAsyncWorkerThread, currentThread, 0) == 0)
{
// we paused, and we got the lock back; anything else?
lock (asyncCompletionQueue)
{
next = asyncCompletionQueue.Count == 0 ? null
: asyncCompletionQueue.Dequeue();
}
}
if (next == null) break; // nothing to do
}
if (next == null) break; // nothing to do <===== exit point
try
{
multiplexer.Trace("Completing async (ordered): " + next, name);
next.TryComplete(true);
Interlocked.Increment(ref completedAsync);
}
catch(Exception ex)
catch (Exception ex)
{
multiplexer.Trace("Async completion error: " + ex.Message, name);
Interlocked.Increment(ref failedAsync);
}
total++;
} while (true);
multiplexer.Trace("Async completion worker processed " + total + " operations", name);
}
finally
{
Interlocked.CompareExchange(ref activeAsyncWorkerThread, 0, currentThread);
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment