From d841d4e0cdcaa8986ea06cda8088fcc93baaa1a0 Mon Sep 17 00:00:00 2001 From: vsadov <8218165+VSadov@users.noreply.github.com> Date: Wed, 9 Nov 2022 19:46:58 -0800 Subject: [PATCH] Must read `SequenceNumber` before reading the `Item` --- .../System/Collections/Concurrent/ConcurrentQueue.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs index 3fa2f71ade78fa..e700a1fb8a5de5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Concurrent/ConcurrentQueue.cs @@ -528,13 +528,11 @@ private static T GetItemWhenAvailable(ConcurrentQueueSegment segment, int i) // If the expected sequence number is not yet written, we're still waiting for // an enqueuer to finish storing it. Spin until it's there. - if ((segment._slots[i].SequenceNumber & segment._slotsMask) != expectedSequenceNumberAndMask) + SpinWait spinner = default; + // Must read SequenceNumber before reading Item, thus Volatile.Read + while ((Volatile.Read(ref segment._slots[i].SequenceNumber) & segment._slotsMask) != expectedSequenceNumberAndMask) { - SpinWait spinner = default; - while ((Volatile.Read(ref segment._slots[i].SequenceNumber) & segment._slotsMask) != expectedSequenceNumberAndMask) - { - spinner.SpinOnce(); - } + spinner.SpinOnce(); } // Return the value from the slot.