Merged pull request #58 from XTZGZoReX/master.
[mono.git] / mcs / class / corlib / System.Threading / CountdownEvent.cs
index 935ccf03ff52fca619c31163ad35eb9448f5209b..59c282ea567cd48aad06ab1008655f6b554be0b2 100644 (file)
@@ -1,4 +1,3 @@
-#if NET_4_0
 // CountdownEvent.cs
 //
 // Copyright (c) 2008 Jérémie "Garuma" Laval
 //
 //
 
+#if NET_4_0 || MOBILE
+
 using System;
 
 namespace System.Threading
-{      
+{
+       [System.Diagnostics.DebuggerDisplayAttribute ("Initial Count={InitialCount}, Current Count={CurrentCount}")]
        public class CountdownEvent : IDisposable
        {
-               int count;
-               readonly int initial;
-               bool isCanceled;
-               ManualResetEvent evt = new ManualResetEvent (false);
+               int initialCount;
+               int initial;
+               ManualResetEventSlim evt = new ManualResetEventSlim (false);
                
-               public CountdownEvent (int count)
+               public CountdownEvent (int initialCount)
                {
-                       if (count < 0)
-                               throw new ArgumentOutOfRangeException ("count is negative");
-                       this.initial = this.count = count;
+                       if (initialCount < 0)
+                               throw new ArgumentOutOfRangeException ("initialCount is negative");
+                       this.initial = this.initialCount = initialCount;
                }
                
                public bool Signal ()
@@ -46,23 +47,21 @@ namespace System.Threading
                        return Signal (1);
                }
                
-               public bool Signal (int num)
+               public bool Signal (int signalCount)
                {
-                       if (num < 0)
-                               throw new ArgumentOutOfRangeException ("num");
+                       if (signalCount <= 0)
+                               throw new ArgumentOutOfRangeException ("signalCount");
                        
                        Action<int> check = delegate (int value) {
                                if (value < 0)
-                               throw new InvalidOperationException ("the specified count is larger that CurrentCount");
-                               if (IsCanceled)
-                               throw new OperationCanceledException ();
+                               throw new InvalidOperationException ("the specified initialCount is larger that CurrentCount");
                        };
                        
                        int newValue;
-                       if (!ApplyOperation (-num, check, out newValue))
+                       if (!ApplyOperation (-signalCount, check, out newValue))
                                throw new InvalidOperationException ("The event is already set");
                        
-                       if (newValue <= 0) {
+                       if (newValue == 0) {
                                evt.Set ();
                                return true;
                        }
@@ -75,12 +74,12 @@ namespace System.Threading
                        AddCount (1);
                }
                
-               public void AddCount (int num)
+               public void AddCount (int signalCount)
                {
-                       if (num < 0)
-                               throw new ArgumentOutOfRangeException ("num");
+                       if (signalCount < 0)
+                               throw new ArgumentOutOfRangeException ("signalCount");
                        
-                       if (!TryAddCount (num))
+                       if (!TryAddCount (signalCount))
                                throw new InvalidOperationException ("The event is already set");
                }
                
@@ -89,17 +88,12 @@ namespace System.Threading
                        return TryAddCount (1);
                }
                
-               public bool TryAddCount (int num)
+               public bool TryAddCount (int signalCount)
                {       
-                       if (num < 0)
-                               throw new ArgumentOutOfRangeException ("num");
-                       
-                       Action<int> check = delegate (int value) {
-                               if (IsCanceled)
-                               throw new OperationCanceledException ();
-                       };
+                       if (signalCount < 0)
+                               throw new ArgumentOutOfRangeException ("signalCount");
                        
-                       return ApplyOperation (num, check);
+                       return ApplyOperation (signalCount, null);
                }
                
                bool ApplyOperation (int num, Action<int> doCheck)
@@ -114,96 +108,63 @@ namespace System.Threading
                        newValue = 0;
                        
                        do {
-                               if (IsSet)
+                               oldCount = initialCount;
+                               if (oldCount == 0)
                                        return false;
                                
-                               oldCount = count;
                                newValue = oldCount + num;
                                
-                               doCheck (newValue);
-                               
-                       } while (Interlocked.CompareExchange (ref count, newValue, oldCount) != oldCount);
+                               if (doCheck != null)
+                                       doCheck (newValue);
+                       } while (Interlocked.CompareExchange (ref initialCount, newValue, oldCount) != oldCount);
                        
                        return true;
                }
                
                public void Wait ()
                {
-                       SpinWait wait = new SpinWait ();
-                       while (!IsSet) {
-                               wait.SpinOnce ();
-                       }
+                       evt.Wait ();
                }
                
-               public bool Wait (int timeoutMilli)
+               public void Wait (CancellationToken cancellationToken)
                {
-                       if (timeoutMilli == -1) {
-                               Wait ();
-                               return true;
-                       }
-                       
-                       Watch sw = Watch.StartNew ();
-                       long timeout = (long)timeoutMilli;
-                       
-                       bool result = Wait (() => sw.ElapsedMilliseconds > timeout);
-                       sw.Stop ();
-                       
-                       return result;
+                       evt.Wait (cancellationToken);
                }
                
-               public bool Wait(TimeSpan span)
+               public bool Wait (int millisecondsTimeout)
                {
-                       return Wait ((int)span.TotalMilliseconds);
+                       return evt.Wait (millisecondsTimeout);
                }
                
-               public bool Wait (int timeoutMilli, CancellationToken token)
+               public bool Wait(TimeSpan timeout)
                {
-                       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 (timeout);
                }
                
-               public bool Wait(TimeSpan span, CancellationToken token)
+               public bool Wait (int millisecondsTimeout, CancellationToken cancellationToken)
                {
-                       return Wait ((int)span.TotalMilliseconds, token);
+                       return evt.Wait (millisecondsTimeout, cancellationToken);
                }
                
-               bool Wait (Func<bool> waitPredicate)
+               public bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
                {
-                       SpinWait wait = new SpinWait ();
-                       
-                       while (!IsSet) {
-                               if (waitPredicate ())
-                                       return false;
-                               wait.SpinOnce ();
-                       }
-                       
-                       return true;
+                       return evt.Wait (timeout, cancellationToken);
                }
-               
+
                public void Reset ()
                {
                        Reset (initial);
                }
                
-               public void Reset (int value)
+               public void Reset (int count)
                {
                        evt.Reset ();
-                       Interlocked.Exchange (ref count, value);
+                       initialCount = initial = count;
                }
                
                public int CurrentCount {
                        get {
-                               return count;
+                               return initialCount;
                        }
                }
                
@@ -215,13 +176,13 @@ namespace System.Threading
                        
                public bool IsSet {
                        get {
-                               return count <= 0;
+                               return initialCount == 0;
                        }
                }
                
                public WaitHandle WaitHandle {
                        get {
-                               return evt;
+                               return evt.WaitHandle;
                        }
                }
 
@@ -231,25 +192,12 @@ namespace System.Threading
                {
                        
                }
-               #endregion 
-               
                
-               #region ISupportsCancellation implementation 
-               
-               public void Cancel ()
+               protected virtual void Dispose (bool disposing)
                {
-                       Interlocked.Exchange (ref count, 0);
-                       isCanceled = true;
-               }
-               
-               public bool IsCanceled {
-                       get {
-                               return isCanceled;
-                       }
+                       
                }
-               
-               #endregion 
-               
+               #endregion      
        }
 }
 #endif