Move CompletionContainer to use ConcurrentOrderedList to allows easier removal
authorJérémie Laval <jeremie.laval@gmail.com>
Sat, 15 Oct 2011 12:53:12 +0000 (14:53 +0200)
committerJérémie Laval <jeremie.laval@gmail.com>
Sat, 15 Oct 2011 13:34:55 +0000 (15:34 +0200)
mcs/class/corlib/System.Threading.Tasks/CompletionContainer.cs

index 198348f5df48e601ca3c4276865e88b371301925..9409aeee68897a6c7feacb8b1ee1804debe8ea30 100644 (file)
@@ -38,15 +38,25 @@ namespace System.Threading.Tasks
        internal struct TaskCompletionQueue<TCompletion> where TCompletion : class
        {
                TCompletion single;
-               ConcurrentQueue<TCompletion> completed;
+               ConcurrentOrderedList<TCompletion> completed;
 
                public void Add (TCompletion continuation)
                {
                        if (single == null && Interlocked.CompareExchange (ref single, continuation, null) == null)
                                return;
                        if (completed == null)
-                               Interlocked.CompareExchange (ref completed, new ConcurrentQueue<TCompletion> (), null);
-                       completed.Enqueue (continuation);
+                               Interlocked.CompareExchange (ref completed, new ConcurrentOrderedList<TCompletion> (), null);
+                       completed.TryAdd (continuation);
+               }
+
+               public bool Remove (TCompletion continuation)
+               {
+                       TCompletion temp = single;
+                       if (temp != null && temp == continuation && Interlocked.CompareExchange (ref single, null, continuation) == continuation)
+                               return true;
+                       else if (completed != null)
+                               return completed.TryRemove (continuation);
+                       return false;
                }
 
                public bool HasElements {
@@ -62,7 +72,7 @@ namespace System.Threading.Tasks
                        if (single != null && (continuation = Interlocked.Exchange (ref single, null)) != null)
                                return true;
 
-                       return completed != null && completed.TryDequeue (out continuation);
+                       return completed != null && completed.TryPop (out continuation);
                }
        }
 }