Merge branch 'bugfix-main-thread-root'
[mono.git] / mcs / class / corlib / System.Threading / ReaderWriterLock.cs
old mode 100755 (executable)
new mode 100644 (file)
index c35bd45..7cb1213
 //
 
 using System.Collections;
+using System.Runtime.InteropServices;
+using System.Runtime.ConstrainedExecution;
+
 
 namespace System.Threading
 {
-       public sealed class ReaderWriterLock
+       [ComVisible (true)]
+       public sealed class ReaderWriterLock: CriticalFinalizerObject
        {
                private int seq_num = 1;
-               private int state = 0;
-               private int readers = 0;
+               private int state;
+               private int readers;
                private LockQueue writer_queue;
                private Hashtable reader_locks;
                private int writer_lock_owner;
-               private int readyWaitingReaders = 0;
 
                public ReaderWriterLock()
                {
                        writer_queue = new LockQueue (this);
                        reader_locks = new Hashtable ();
+
+                       GC.SuppressFinalize (this);
+               }
+
+               ~ReaderWriterLock ()
+               {
                }
 
                public bool IsReaderLockHeld {
+                       [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                        get {
                                lock (this) return reader_locks.ContainsKey (Thread.CurrentThreadId);
                        }
                }
 
                public bool IsWriterLockHeld {
+                       [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                        get {
                                lock (this) return (state < 0 && Thread.CurrentThreadId == writer_lock_owner);
                        }
@@ -92,10 +103,11 @@ namespace System.Threading
                                        readers++;
                                        try {
                                                if (state < 0 || !writer_queue.IsEmpty) {
-                                                       if (!Monitor.Wait (this, millisecondsTimeout))
-                                                               throw new ApplicationException ("Timeout expired");
+                                                       do {
+                                                               if (!Monitor.Wait (this, millisecondsTimeout))
+                                                                       throw new ApplicationException ("Timeout expired");
+                                                       } while (state < 0);
                                                }
-                                               readyWaitingReaders--;
                                        }
                                        finally {
                                                readers--;
@@ -132,9 +144,11 @@ namespace System.Threading
                                
                                // wait while there are reader locks or another writer lock, or
                                // other threads waiting for the writer lock
-                               if (state != 0 || !writer_queue.IsEmpty || readers > 0) {
-                                       if (!writer_queue.Wait (millisecondsTimeout))
-                                               throw new ApplicationException ("Timeout expited");
+                               if (state != 0 || !writer_queue.IsEmpty) {
+                                       do {
+                                               if (!writer_queue.Wait (millisecondsTimeout))
+                                                       throw new ApplicationException ("Timeout expired");
+                                       } while (state != 0);
                                }
 
                                state = -initialLockCount;
@@ -163,7 +177,6 @@ namespace System.Threading
                                state = lockCookie.ReaderLocks;
                                reader_locks [Thread.CurrentThreadId] = state;
                                if (readers > 0) {
-                                       readyWaitingReaders = readers;
                                        Monitor.PulseAll (this);
                                }
                                
@@ -186,6 +199,7 @@ namespace System.Threading
                        return cookie;
                }
                
+               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                public void ReleaseReaderLock()
                {
                        lock (this) {
@@ -200,6 +214,7 @@ namespace System.Threading
                                                return;
                                        }
                                }
+
                                throw new ApplicationException ("The thread does not have any reader or writer locks.");
                        }
                }
@@ -214,10 +229,11 @@ namespace System.Threading
                                reader_locks [Thread.CurrentThreadId] = new_count;
                                
                        state -= releaseCount;
-                       if (state == 0 && (readers == 0 || readyWaitingReaders <= 0) && !writer_queue.IsEmpty)
+                       if (state == 0 && !writer_queue.IsEmpty)
                                writer_queue.Pulse ();
                }
 
+               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
                public void ReleaseWriterLock()
                {
                        lock (this) {
@@ -233,7 +249,6 @@ namespace System.Threading
                        state += releaseCount;
                        if (state == 0) {
                                if (readers > 0) {
-                                       readyWaitingReaders = readers;
                                        Monitor.PulseAll (this);
                                }
                                else if (!writer_queue.IsEmpty)