Hi,
     I have implemented the Change() method[ false return value ) and the Dispose() 
method, which was incomplete.

Please inform me whether this is fine or it needs any other modification.

I will be interested to complete all the TODOs in the �System.Threading� namespace.

P.S: Timer.cs

Regards,
Deepak.
//
// System.Threading.Timer.cs
//
// Authors:
//      Dick Porter ([EMAIL PROTECTED])
//      Gonzalo Paniagua Javier ([EMAIL PROTECTED])
//
// (C) 2001, 2002 Ximian, Inc.  http://www.ximian.com
//


using System.Collections;
namespace System.Threading
{
        public sealed class Timer : MarshalByRefObject, IDisposable
        {
                // A Static ArrayList which holds all references to active timers
                private static ArrayList arrayList = new ArrayList();
                
                sealed class Runner : MarshalByRefObject, IDisposable
                {
                        ManualResetEvent wait;
                        AutoResetEvent start_event;
                        TimerCallback callback;
                        object state;
                        int dueTime;
                        int period;
                        bool disposed;
                        bool aborted;

                        public Runner (TimerCallback callback, object state, 
AutoResetEvent start_event)
                        {
                                this.callback = callback;
                                this.state = state;
                                this.start_event = start_event;
                                this.wait = new ManualResetEvent (false);
                        }

                        public int DueTime {
                                get { return dueTime; }
                                set { dueTime = value; }
                        }

                        public int Period {
                                get { return period; }
                                set { period = value == 0 ? Timeout.Infinite : value; }
                        }

                        bool WaitForDueTime ()
                        {
                                if (dueTime > 0) {
                                        bool signaled;
                                        do {
                                                wait.Reset ();
                                                signaled = wait.WaitOne (dueTime, 
false);
                                        } while (signaled == true && !disposed && 
!aborted);

                                        if (!signaled)
                                                callback (state);

                                        if (disposed)
                                                return false;
                                }

                                return true;
                        }

                        public void Abort ()
                        {
                                lock (this) {
                                        aborted = true;
                                        wait.Set ();
                                }
                        }

                        public void Start ()
                        {
                                while (start_event.WaitOne ()) {
                                        aborted = false;

                                        if (dueTime == Timeout.Infinite)
                                                continue;

                                        if (!WaitForDueTime ())
                                                return;

                                        if (aborted || (period == Timeout.Infinite))
                                                continue;

                                        bool signaled = false;
                                        while (true) {
                                                if (disposed)
                                                        return;

                                                if (aborted)
                                                        break;

                                                wait.Reset ();
                                                signaled = wait.WaitOne (period, 
false);

                                                if (!signaled) {
                                                        callback (state);
                                                } else if (!WaitForDueTime ()) {
                                                        return;
                                                }
                                        }
                                }
                        }

                        public void Dispose ()
                        {
                                Dispose (true);
                        }

                        void Dispose (bool disposing)
                        {
                                // Remove the current object from the arrayList
                                arrayList.Remove( this );
                                disposed = true;
                                if (wait != null) {
                                        wait.Set ();
                                        Thread.Sleep (100);
                                        ((IDisposable) wait).Dispose ();
                                        wait = null;
                                }

                                if (disposing)
                                        GC.SuppressFinalize (this);
                        }

                        ~Runner ()
                        {
                                Dispose (false);
                        }
                }

                Runner runner;
                AutoResetEvent start_event;

                public Timer (TimerCallback callback, object state, int dueTime, int 
period)
                {
                        if (dueTime < -1)
                                throw new ArgumentOutOfRangeException ("dueTime");

                        if (period < -1)
                                throw new ArgumentOutOfRangeException ("period");

                        Init (callback, state, dueTime, period);
                }

                public Timer (TimerCallback callback, object state, long dueTime, long 
period)
                {
                        if (dueTime < -1)
                                throw new ArgumentOutOfRangeException ("dueTime");

                        if (period < -1)
                                throw new ArgumentOutOfRangeException ("period");

                        Init (callback, state, (int) dueTime, (int) period);
                }

                public Timer (TimerCallback callback, object state, TimeSpan dueTime, 
TimeSpan period)
                        : this (callback, state, 
Convert.ToInt32(dueTime.TotalMilliseconds), Convert.ToInt32(period.TotalMilliseconds))
                {
                }

                [CLSCompliant(false)]
                public Timer (TimerCallback callback, object state, uint dueTime, uint 
period)
                        : this (callback, state, (long) dueTime, (long) period)
                {
                }

                void Init (TimerCallback callback, object state, int dueTime, int 
period)
                {
                        // An instance of the Timer class is generated - Add this to 
ArrayList
                        arrayList.Add( this );

                        start_event = new AutoResetEvent (false);
                        runner = new Runner (callback, state, start_event);
                        Change (dueTime, period);
                        Thread t = new Thread (new ThreadStart (runner.Start));
                        t.IsBackground = true;
                        t.Start ();
                }

                //[MonoTODO("false return?")]
                public bool Change (int dueTime, int period)
                {
                        if (dueTime < -1)
                                throw new ArgumentOutOfRangeException ("dueTime");

                        if (period < -1)
                                throw new ArgumentOutOfRangeException ("period");
                        
                        if( !arrayList.Contains( this ) )
                        {
                                return( false );
                        }
                        runner.DueTime = dueTime;
                        runner.Period = period;
                        runner.Abort ();
                        start_event.Set ();
                        return true;
                }

                public bool Change (long dueTime, long period)
                {
                        if(dueTime > 4294967294)
                                throw new NotSupportedException ("Due time too large");

                        if(period > 4294967294)
                                throw new NotSupportedException ("Period too large");

                        return Change ((int) dueTime, (int) period);
                }

                public bool Change (TimeSpan dueTime, TimeSpan period)
                {
                        return Change (Convert.ToInt32(dueTime.TotalMilliseconds), 
Convert.ToInt32(period.TotalMilliseconds));
                }

                [CLSCompliant(false)]
                public bool Change (uint dueTime, uint period)
                {
                        if (dueTime > Int32.MaxValue)
                                throw new NotSupportedException ("Due time too large");

                        if (period > Int32.MaxValue)
                                throw new NotSupportedException ("Period too large");

                        return Change ((int) dueTime, (int) period);
                }

                public void Dispose ()
                {
                        runner.Dispose ();
                        runner = null;
                        GC.SuppressFinalize (this);
                }

                //[MonoTODO("How to know the number of times the WaitOne() is called 
on Mutex?")]
                public bool Dispose (WaitHandle notifyObject)
                {
                        Dispose ();
                        if( notifyObject is AutoResetEvent )
                        {
                                AutoResetEvent ae = ( AutoResetEvent ) notifyObject;
                                ae.Set();
                        }
                        else if ( notifyObject is ManualResetEvent )
                        {
                                ManualResetEvent me = ( ManualResetEvent ) 
notifyObject;
                                me.Set();
                        }
                        else if ( notifyObject is Mutex )
                        {
                                Mutex mutexEvent = ( Mutex ) notifyObject;
                                mutexEvent.ReleaseMutex(); //FIXME
                        }
                        return true;
                }

                ~Timer ()
                {
                        runner = null;
                }
        }
}

Reply via email to