2009-12-11 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Fri, 11 Dec 2009 05:36:59 +0000 (05:36 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Fri, 11 Dec 2009 05:36:59 +0000 (05:36 -0000)
* Barrier.cs: Implement IDisposable, add a bunch of IDisposable
checks and some checks from the docs.

svn path=/trunk/mcs/; revision=148091

mcs/class/System/System.Threading/Barrier.cs
mcs/class/System/System.Threading/ChangeLog

index 105783e8f16daadad408baffb8cc4e2c74855449..615184fbaa8471b9ad55b12a48e461b08ec0412f 100644 (file)
@@ -29,14 +29,15 @@ using System;
 
 namespace System.Threading
 {
-       public class Barrier
+       public class Barrier : IDisposable
        {
-               readonly Action<Barrier> postPhaseAction;
+               const int MAX_PARTICIPANTS = 32767;
+               Action<Barrier> postPhaseAction;
                
                int participants;
                CountdownEvent cntd;
                AtomicBoolean cleaned = new AtomicBoolean ();
-               int phase;
+               long phase;
                
                public Barrier (int participants) : this (participants, null)
                {
@@ -44,25 +45,56 @@ namespace System.Threading
                
                public Barrier (int participants, Action<Barrier> postPhaseAction)
                {
+                       if (participants < 0 || participants > MAX_PARTICIPANTS)
+                               throw new ArgumentOutOfRangeException ("participants");
+                       
                        this.participants = participants;
                        this.postPhaseAction = postPhaseAction;
                        
                        InitCountdownEvent ();
                }
-               
+
+               public void Dispose ()
+               {
+                       Dispose (true);
+               }
+
+               protected virtual void Dispose (bool disposing)
+               {
+                       if (disposing){
+                               if (cntd != null){
+                                       cntd.Dispose ();
+                                       cntd = null;
+                               }
+                               cleaned = null;
+                               postPhaseAction = null;
+                       }
+               }
+                       
                void InitCountdownEvent ()
                {
                        cleaned = new AtomicBoolean ();
                        cntd = new CountdownEvent (participants);
                }
                
-               public int AddParticipant ()
+               public long AddParticipant ()
                {
                        return AddParticipants (1);
                }
+
+               static Exception GetDisposed ()
+               {
+                       return new ObjectDisposedException ("Barrier");
+               }
                
-               public int AddParticipants (int participantCount)
+               public long AddParticipants (int participantCount)
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
+                       
+                       if (participantCount < 0)
+                               throw new InvalidOperationException ();
+                       
                        // Basically, we try to add ourselves and return
                        // the phase. If the call return false, we repeatdly try
                        // to add ourselves for the next phase
@@ -81,32 +113,47 @@ namespace System.Threading
                
                public void RemoveParticipants (int participantCount)
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
+                       if (participantCount < 0)
+                               throw new ArgumentOutOfRangeException ("participantCount");
+                       
                        cntd.Signal (participantCount);
                        Interlocked.Add (ref participants, -participantCount);
                }
                
                public void SignalAndWait ()
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
                        SignalAndWait ((c) => { c.Wait (); return true; });
                }
                
                public bool SignalAndWait (int millisecondTimeout)
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
                        return SignalAndWait ((c) => c.Wait (millisecondTimeout));
                }
                
                public bool SignalAndWait (TimeSpan ts)
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
                        return SignalAndWait ((c) => c.Wait (ts));
                }
                
                public bool SignalAndWait (int millisecondTimeout, CancellationToken token)
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
                        return SignalAndWait ((c) => c.Wait (millisecondTimeout, token));
                }
                
                public bool SignalAndWait (TimeSpan ts, CancellationToken token)
                {
+                       if (cleaned == null)
+                               throw GetDisposed ();
                        return SignalAndWait ((c) => c.Wait (ts, token));
                }
                
@@ -150,7 +197,7 @@ namespace System.Threading
                        cl.Value = true;
                }
                
-               public int CurrentPhaseNumber {
+               public long CurrentPhaseNumber {
                        get {
                                return phase;
                        }
index 8e816821de198fcaa422ea409c2cd85d98575009..bf61f1586011304e33286cc5cec41f7b276520d3 100644 (file)
@@ -1,3 +1,8 @@
+2009-12-11  Miguel de Icaza  <miguel@novell.com>
+
+       * Barrier.cs: Implement IDisposable, add a bunch of IDisposable
+       checks and some checks from the docs.
+
 2009-08-19  Jérémie Laval  <jeremie.laval@gmail.com>
 
        * Barrier.cs: Fix Barrier to be really thread-safe.