Author: robertj
Date: 2006-12-11 15:11:41 -0500 (Mon, 11 Dec 2006)
New Revision: 69357

Modified:
   trunk/mcs/class/System/System.Timers/ChangeLog
   trunk/mcs/class/System/System.Timers/Timer.cs
Log:
2006-03-19  Robert Jordan  <[EMAIL PROTECTED]>

        * Timer.cs: Fix race condition of the wait handle object.
        Fixes bug #77847.



Modified: trunk/mcs/class/System/System.Timers/ChangeLog
===================================================================
--- trunk/mcs/class/System/System.Timers/ChangeLog      2006-12-11 20:02:38 UTC 
(rev 69356)
+++ trunk/mcs/class/System/System.Timers/ChangeLog      2006-12-11 20:11:41 UTC 
(rev 69357)
@@ -1,3 +1,8 @@
+2006-03-19  Robert Jordan  <[EMAIL PROTECTED]>
+
+       * Timer.cs: Fix race condition of the wait handle object.
+       Fixes bug #77847.
+
 2005-11-16  Sebastien Pouliot  <[EMAIL PROTECTED]> 
  
        * TimersDescriptionAttribute.cs: Revert Description property fix 

Modified: trunk/mcs/class/System/System.Timers/Timer.cs
===================================================================
--- trunk/mcs/class/System/System.Timers/Timer.cs       2006-12-11 20:02:38 UTC 
(rev 69356)
+++ trunk/mcs/class/System/System.Timers/Timer.cs       2006-12-11 20:11:41 UTC 
(rev 69357)
@@ -44,6 +44,8 @@
                double interval;
                ISynchronizeInvoke so;
                ManualResetEvent wait;
+               Thread thread;
+               object locker = new object ();
 
                [Category("Behavior")]
                [TimersDescription("Occurs when the Interval has elapsed.")]
@@ -84,9 +86,10 @@
 
                                enabled = value;
                                if (value) {
-                                       Thread t = new Thread (new ThreadStart 
(StartTimer));
-                                       t.IsBackground = true;
-                                       t.Start ();
+                                       wait = new ManualResetEvent (false);
+                                       thread = new Thread (new ThreadStart 
(StartTimer));
+                                       thread.IsBackground = true;
+                                       thread.Start ();
                                } else {
                                        StopTimer ();
                                }
@@ -175,8 +178,6 @@
 
                void StartTimer ()
                {
-                       wait = new ManualResetEvent (false);
-
                        WaitCallback wc = new WaitCallback (Callback);
                        while (enabled && wait.WaitOne ((int) interval, false) 
== false) {
                                if (autoReset == false)
@@ -184,16 +185,25 @@
 
                                ThreadPool.QueueUserWorkItem (wc, this);
                        }
-                       
+
                        wc = null;
-                       ((IDisposable) wait).Dispose ();
-                       wait = null;
+
+                       lock (locker) {
+                               ((IDisposable) wait).Dispose ();
+                               wait = null;
+                       }
                }
 
                void StopTimer ()
                {
-                       if (wait != null)
-                               wait.Set ();
+                       lock (locker) {
+                               if (wait != null)
+                                       wait.Set ();
+                       }
+
+                       // the sleep speeds up the join under linux
+                       Thread.Sleep (0);
+                       thread.Join ();
                }
        }
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to