Changed TryPeek to handle race condition with Dequeue.
authormarcos henrich <marcoshenrich@gmail.com>
Fri, 30 May 2014 19:31:47 +0000 (20:31 +0100)
committermarcos henrich <marcoshenrich@gmail.com>
Fri, 30 May 2014 19:31:47 +0000 (20:31 +0100)
Dequeue sets the head.Value to its default. When TryPeek is interrupted in the process of retrieving the value some times Dequeue sets the value to its default. TryPeek now checks the head has not been changed before returning the value.

mcs/class/corlib/System.Collections.Concurrent/ConcurrentQueue.cs

index aff2492e0216df7ba60de976dbaf34a158b26fae..ea8984394b46030245c00440b404dd639de7b2e9 100644 (file)
@@ -132,14 +132,24 @@ namespace System.Collections.Concurrent
                
                public bool TryPeek (out T result)
                {
-                       Node first = head.Next; 
+                       result = default (T);
+                       bool update = true;
+                       
+                       while (update)
+                       {
+                               Node oldHead = head;
+                               Node oldNext = oldHead.Next;
 
-                       if (first == null) {
-                               result = default (T);
-                               return false;
-                       }
+                               if (oldNext == null) {
+                                       result = default (T);
+                                       return false;
+                               }
 
-                       result = first.Value;
+                               result = oldNext.Value;
+                               
+                               //check if head has been updated
+                               update = head != oldHead;
+                       }
                        return true;
                }