Merge pull request #1068 from esdrubal/bug18421
authorJérémie Laval <jeremie.laval@gmail.com>
Fri, 30 May 2014 18:50:35 +0000 (14:50 -0400)
committerJérémie Laval <jeremie.laval@gmail.com>
Fri, 30 May 2014 18:50:35 +0000 (14:50 -0400)
Changed ConcurrentQueue to remove last ref/value. Fixes 18421

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

index d19cc4cec7d405515b9e0219798a29af7da44e4a..aff2492e0216df7ba60de976dbaf34a158b26fae 100644 (file)
@@ -97,12 +97,13 @@ namespace System.Collections.Concurrent
                public bool TryDequeue (out T result)
                {
                        result = default (T);
+                       Node oldNext = null;
                        bool advanced = false;
 
                        while (!advanced) {
                                Node oldHead = head;
                                Node oldTail = tail;
-                               Node oldNext = oldHead.Next;
+                               oldNext = oldHead.Next;
                                
                                if (oldHead == head) {
                                        // Empty case ?
@@ -122,6 +123,8 @@ namespace System.Collections.Concurrent
                                }
                        }
 
+                       oldNext.Value = default (T);
+
                        Interlocked.Decrement (ref count);
 
                        return true;
index b0006440afaa97429b21a4fb107623b8df43573b..80313356fe2f49a62ee92cd72cab5a5b10b222d5 100644 (file)
@@ -215,6 +215,28 @@ namespace MonoTests.System.Collections.Concurrent
                {
                        queue.CopyTo (new int[3], 0);
                }
+               
+               static WeakReference CreateWeakReference (object obj)
+               {
+                       return new WeakReference (obj);
+               }
+               
+               [Test]
+               public void TryDequeueReferenceTest ()
+               {
+                       var obj = new Object ();
+                       var weakReference = CreateWeakReference(obj);
+                       var queue = new ConcurrentQueue<object> ();
+
+                       queue.Enqueue (obj);
+                       queue.TryDequeue (out obj);
+                       obj = null;
+
+                       GC.Collect ();
+                       GC.WaitForPendingFinalizers ();
+
+                       Assert.IsFalse (weakReference.IsAlive);
+               }
        }
 }
 #endif