Implemenent v4 Monitor::TryEnter overloads.
[mono.git] / mcs / class / corlib / System.Threading / CountdownEvent.cs
index 156b8f431c5ba61612299d9e3b3a2fb1fc317a71..eaeb3ac6e14e8a087bbadfc7f4ba70609cc53599 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // CountdownEvent.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
@@ -23,6 +22,8 @@
 //
 //
 
+#if NET_4_0 || BOOTSTRAP_NET_4_0
+
 using System;
 
 namespace System.Threading
@@ -31,7 +32,7 @@ namespace System.Threading
        {
                int count;
                readonly int initial;
-               ManualResetEvent evt = new ManualResetEvent (false);
+               ManualResetEventSlim evt = new ManualResetEventSlim (false);
                
                public CountdownEvent (int count)
                {
@@ -47,7 +48,7 @@ namespace System.Threading
                
                public bool Signal (int num)
                {
-                       if (num < 0)
+                       if (num <= 0)
                                throw new ArgumentOutOfRangeException ("num");
                        
                        Action<int> check = delegate (int value) {
@@ -59,7 +60,7 @@ namespace System.Threading
                        if (!ApplyOperation (-num, check, out newValue))
                                throw new InvalidOperationException ("The event is already set");
                        
-                       if (newValue <= 0) {
+                       if (newValue == 0) {
                                evt.Set ();
                                return true;
                        }
@@ -91,9 +92,7 @@ namespace System.Threading
                        if (num < 0)
                                throw new ArgumentOutOfRangeException ("num");
                        
-                       Action<int> check = delegate (int value) {      };
-                       
-                       return ApplyOperation (num, check);
+                       return ApplyOperation (num, null);
                }
                
                bool ApplyOperation (int num, Action<int> doCheck)
@@ -108,14 +107,14 @@ namespace System.Threading
                        newValue = 0;
                        
                        do {
-                               if (IsSet)
+                               oldCount = count;
+                               if (oldCount == 0)
                                        return false;
                                
-                               oldCount = count;
                                newValue = oldCount + num;
                                
-                               doCheck (newValue);
-                               
+                               if (doCheck != null)
+                                       doCheck (newValue);
                        } while (Interlocked.CompareExchange (ref count, newValue, oldCount) != oldCount);
                        
                        return true;
@@ -123,72 +122,34 @@ namespace System.Threading
                
                public void Wait ()
                {
-                       SpinWait wait = new SpinWait ();
-                       while (!IsSet) {
-                               wait.SpinOnce ();
-                       }
+                       evt.Wait ();
                }
                
-               public bool Wait (CancellationToken token)
+               public void Wait (CancellationToken token)
                {
-                       return Wait (() => token.IsCancellationRequested);
+                       evt.Wait (token);
                }
                
                public bool Wait (int timeoutMilli)
                {
-                       if (timeoutMilli == -1) {
-                               Wait ();
-                               return true;
-                       }
-                       
-                       Watch sw = Watch.StartNew ();
-                       long timeout = (long)timeoutMilli;
-                       
-                       bool result = Wait (() => sw.ElapsedMilliseconds > timeout);
-                       sw.Stop ();
-                       
-                       return result;
+                       return evt.Wait (timeoutMilli);
                }
                
                public bool Wait(TimeSpan span)
                {
-                       return Wait ((int)span.TotalMilliseconds);
+                       return evt.Wait (span);
                }
                
                public bool Wait (int timeoutMilli, CancellationToken token)
                {
-                       if (timeoutMilli == -1) {
-                               Wait ();
-                               return true;
-                       }
-                       
-                       Watch sw = Watch.StartNew ();
-                       long timeout = (long)timeoutMilli;
-                       
-                       bool result = Wait (() => sw.ElapsedMilliseconds > timeout || token.IsCancellationRequested);
-                       sw.Stop ();
-                       
-                       return result;
+                       return evt.Wait (timeoutMilli, token);
                }
                
                public bool Wait(TimeSpan span, CancellationToken token)
                {
-                       return Wait ((int)span.TotalMilliseconds, token);
+                       return evt.Wait (span, token);
                }
-               
-               bool Wait (Func<bool> waitPredicate)
-               {
-                       SpinWait wait = new SpinWait ();
-                       
-                       while (!IsSet) {
-                               if (waitPredicate ())
-                                       return false;
-                               wait.SpinOnce ();
-                       }
-                       
-                       return true;
-               }
-               
+
                public void Reset ()
                {
                        Reset (initial);
@@ -214,13 +175,13 @@ namespace System.Threading
                        
                public bool IsSet {
                        get {
-                               return count <= 0;
+                               return count == 0;
                        }
                }
                
                public WaitHandle WaitHandle {
                        get {
-                               return evt;
+                               return evt.WaitHandle;
                        }
                }