New test.
[mono.git] / mcs / class / corlib / System.Threading / Timer.cs
old mode 100755 (executable)
new mode 100644 (file)
index 164c60e..a46b038
@@ -6,11 +6,7 @@
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
 // (C) 2001, 2002 Ximian, Inc.  http://www.ximian.com
-// (C) 2004 Novell, Inc. http://www.novell.com
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Runtime.InteropServices;
 
 namespace System.Threading
 {
+#if NET_2_0
+       [ComVisible (true)]
+#endif
        public sealed class Timer : MarshalByRefObject, IDisposable
        {
                sealed class Runner : MarshalByRefObject
@@ -105,7 +105,10 @@ namespace System.Threading
 
                        public void Start ()
                        {
-                               while (start_event.WaitOne () && !disposed) {
+                               while (!disposed && start_event.WaitOne ()) {
+                                       if (disposed)
+                                               return;
+
                                        aborted = false;
 
                                        if (dueTime == Timeout.Infinite)
@@ -125,9 +128,20 @@ namespace System.Threading
                                                if (aborted)
                                                        break;
 
-                                               wait.Reset ();
+                                               try {
+                                                       wait.Reset ();
+                                               } catch (ObjectDisposedException) {
+                                                       // FIXME: There is some race condition
+                                                       //        here when the thread is being
+                                                       //        aborted on exit.
+                                                       return;
+                                               }
+
                                                signaled = wait.WaitOne (period, false);
 
+                                               if (aborted || disposed)
+                                                       break;
+
                                                if (!signaled) {
                                                        callback (state);
                                                } else if (!WaitForDueTime ()) {
@@ -175,6 +189,13 @@ namespace System.Threading
                {
                }
 
+#if NET_2_0
+               public Timer (TimerCallback callback)
+               {
+                       Init (callback, this, Timeout.Infinite, Timeout.Infinite);
+               }
+#endif
+
                void Init (TimerCallback callback, object state, int dueTime, int period)
                {
                        start_event = new AutoResetEvent (false);
@@ -195,10 +216,11 @@ namespace System.Threading
 
                        if (runner == null)
                                return false;
-                       
+
+                       start_event.Reset ();
+                       runner.Abort ();
                        runner.DueTime = dueTime;
                        runner.Period = period;
-                       runner.Abort ();
                        start_event.Set ();
                        return true;
                }
@@ -238,8 +260,10 @@ namespace System.Threading
                                        t.Abort ();
                                t = null;
                        }
-                       runner.Dispose ();
-                       runner = null;
+                       if (runner != null) {
+                               runner.Dispose ();
+                               runner = null;
+                       }
                        GC.SuppressFinalize (this);
                }