[Mono-devel-list] Patch for Review - System.threading.Timerr

S Umadevi sUmadevi at novell.com
Tue Jun 14 22:36:49 EDT 2005


Hey Ben
  I guess the indentation got off becos I was partially writing the
code on a windows box and did some copy paste stuff..
Thanks for your comments..I will look into them.

Regards
uma

>>> Ben Maurer <bmaurer at ximian.com> 06/14/05 9:11 PM >>>
Hey,

First of all, the indentation on this file got out of whack. It's half
spaces and half tabs. Can you fix it up to use tabs (as it was
before).


> +			int hashCode =
this.GetHashCode();				
> +			for (int i=0;i<timers.Count;i++)
> +			{
> +				//find my timer.
> +				TimerObject timerObject =
(TimerObject)timers[i];
> +				if (timerObject.uniqueid == hashCode)

Hashcodes for objects could collide (exceedingly unlikely, but
technically possible).


> static void RunnerCallback(object o)
> +	{
> +			mut.WaitOne();
> +
> +			triggeredOnce = true;
> +			for (int i=0;i<timers.Count;i++)
> +			{
> +				TimerObject timerObject =
(TimerObject)timers[i];
> +				int diff = (int)(DateTime.Now.Ticks -
timerObject.lastSignalledTime.Ticks);
> +				if ( diff > timerObject.dueTime)
> +				{
>
+					timerObject.timerCallback(timerObject.state);
> +					timerObject.lastSignalledTime =
DateTime.Now;
> +				}
> +				
> +			}
> +					mut.ReleaseMutex();
> +	}

The user's callback is called within the runtime's lock. Imagine
somebody had code that did this:

Main thread:
        while (true) {
        	lock (myObj) {
        		// Create new timer
        	}
        }
        
Timer callback:
        lock (myObj) {
        	// Do something
        }
        
The user's code would deadlock.


> +		 internal struct TimerObject

I don't think this should be a struct. You are just going to end up
getting boxing. Also, we don't need value type stuff here. It should
also be renamed `TimerObject' means nothing.


> + int diff = (int)(DateTime.Now.Ticks -
timerObject.lastSignalledTime.Ticks);

How does this handle spring forward / fall back (daylight's savings
time
changes)? Also, what if the user changes their time zone (just got off
an airplane)?


> +		private static Mutex mut = new Mutex();
> +                private AutoResetEvent start_event  

We should avoid using mutexes and *Events. C# has more native locking
in
the Monitor class. Those two classes are really interop helpers for
the
io-layer. The c# stuff is cleaner -- for example, by doing lock (blah)
it does try...finally which means that stuff is handled in the case of
exceptions.


> +
> +	 public delegate void RunnerCallback(object state);
> +

You can't add public types...


>  		sealed class Runner : MarshalByRefObject
>  		{

The new design should probably get rid of this as it is just something
from the old one. Your design seems to try to put a new layer on top
of
the old one, rather than just do a single threaded design from the
start.


> +				// i am the last timer to be disposed.
> +				if (t != null && t.IsAlive) 
> +				{
> +					if (t != Thread.CurrentThread)
> +						t.Abort ();
> +					t = null;

Abort is really unreliable, it can cause some nasty deadlocks. It
should
really be avoided.


I think you should try rewriting the timers to do the folloing

static void TimerLoop ()
{
	while (true) {
		ArrayList ar = new ArrayList ();
		lock (lockObj) {
			int t = GetTimeToNextEvent ()
			if (t == -1)
				return; // all timers are gone
				// NOTE: make sure there are no races 
				// between this and creating another
				// event. Also may want to sleep for
				// a bit to try and get another timer
				// to avoid creating and destroying
				// thread rapidly
			
			Monitor.Wait (lockObj, t);

			foreach (Task t in alltasks)
				if (t.IsDue)
					ar.Add (t);
		}

		foreach (Task t in ar)
			t.Callback ();

		ar.Clear ();
	}
}

Then, every time you change allTasks, you .Pulse the monitor.

-- Ben

_______________________________________________
Mono-devel-list mailing list
Mono-devel-list at lists.ximian.com 
http://lists.ximian.com/mailman/listinfo/mono-devel-list



More information about the Mono-devel-list mailing list