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