[System] Check for Abort state when poping so that we can retry
authorJeremie Laval <jeremie.laval@gmail.com>
Wed, 25 Jul 2012 16:36:55 +0000 (17:36 +0100)
committerJeremie Laval <jeremie.laval@gmail.com>
Wed, 25 Jul 2012 16:37:52 +0000 (17:37 +0100)
mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs

index 49b519e9a18eda02f88015ee4c36493e7af3de1c..827bc74b83cdca80c0bf7127051d4b99d64f6bb1 100644 (file)
@@ -87,13 +87,17 @@ namespace System.Collections.Concurrent
                        bool ret = true;
                        
                        if (bag == null || bag.PopBottom (out result) != PopResult.Succeed) {
+                               var self = bag;
                                foreach (var other in staging) {
                                        // Try to retrieve something based on a hint
                                        ret = TryGetHint (out hintIndex) && (bag = container[hintIndex]).PopTop (out result) == PopResult.Succeed;
 
                                        // We fall back to testing our slot
-                                       if (!ret && other.Value != bag) {
-                                               ret = other.Value.PopTop (out result) == PopResult.Succeed;
+                                       if (!ret && other.Value != self) {
+                                               var status = other.Value.PopTop (out result);
+                                               while (status == PopResult.Abort)
+                                                       status = other.Value.PopTop (out result);
+                                               ret = status == PopResult.Succeed;
                                                hintIndex = other.Key;
                                                bag = other.Value;
                                        }
@@ -124,12 +128,13 @@ namespace System.Collections.Concurrent
                        bool ret = true;
 
                        if (bag == null || !bag.PeekBottom (out result)) {
+                               var self = bag;
                                foreach (var other in staging) {
                                        // Try to retrieve something based on a hint
                                        ret = TryGetHint (out hintIndex) && container[hintIndex].PeekTop (out result);
 
                                        // We fall back to testing our slot
-                                       if (!ret && other.Value != bag)
+                                       if (!ret && other.Value != self)
                                                ret = other.Value.PeekTop (out result);
 
                                        // If we found something, stop