Fix the mobile build
[mono.git] / mcs / class / corlib / System.Threading / SpinLock.cs
index fbfe6c873f6aeebf2ca35502bd49b9847d396f6d..a14899c6d1902cd4272eca518c160d38d0506dd7 100644 (file)
@@ -42,9 +42,11 @@ namespace System.Threading
                public int Users;
        }
 
-       // Implement the ticket SpinLock algorithm described on http://locklessinc.com/articles/locks/
-       // This lock is usable on both endianness
-       // TODO: some 32 bits platform apparently doesn't support CAS with 64 bits value
+       /* Implement the ticket SpinLock algorithm described on http://locklessinc.com/articles/locks/
+        * This lock is usable on both endianness.
+        * All the try/finally patterns in this class and various extra gimmicks compared to the original
+        * algorithm are here to avoid problems caused by asynchronous exceptions.
+        */
        [System.Diagnostics.DebuggerDisplay ("IsHeld = {IsHeld}")]
        [System.Diagnostics.DebuggerTypeProxy ("System.Threading.SpinLock+SystemThreading_SpinLockDebugView")]
        public struct SpinLock
@@ -107,7 +109,7 @@ namespace System.Threading
                                while (slot != ticket.Value) {
                                        wait.SpinOnce ();
 
-                                       if (stallTickets != null && stallTickets.TryRemove (ticket.Value))
+                                       while (stallTickets != null && stallTickets.TryRemove (ticket.Value))
                                                ++ticket.Value;
                                }
                        } finally {
@@ -146,7 +148,7 @@ namespace System.Threading
                        bool stop = false;
 
                        do {
-                               if (stallTickets != null && stallTickets.TryRemove (ticket.Value))
+                               while (stallTickets != null && stallTickets.TryRemove (ticket.Value))
                                        ++ticket.Value;
 
                                long u = ticket.Users;
@@ -167,6 +169,7 @@ namespace System.Threading
                } while (!stop && (millisecondsTimeout == -1 || (sw.ElapsedMilliseconds - start) < millisecondsTimeout));
                }
 
+               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                public void Exit ()
                {
                        Exit (false);
@@ -182,7 +185,6 @@ namespace System.Threading
                                        throw new SynchronizationLockException ("Current thread is not the owner of this lock");
 
                                threadWhoTookLock = int.MinValue;
-                               // Fast path
                                do {
                                        if (useMemoryBarrier)
                                                Interlocked.Increment (ref ticket.Value);