void SchedulerThread ()
{
Thread.CurrentThread.Name = "Timer-Scheduler";
ArrayList new_time = new ArrayList (512);
while (true) {
long ticks = DateTime.GetTimeMonotonic ();
lock (this) {
//PrintList ();
int i;
int count = list.Count;
for (i = 0; i < count; i++) {
Timer timer = (Timer) list.GetByIndex (i);
if (timer.next_run > ticks)
break;
list.RemoveAt (i);
count--;
i--;
ThreadPool.QueueUserWorkItem (new WaitCallback (timer.callback), timer.state);
long period = timer.period_ms;
long due_time = timer.due_time_ms;
bool no_more = (period == -1 || ((period == 0 || period == Timeout.Infinite) && due_time != Timeout.Infinite));
if (no_more) {
timer.next_run = Int64.MaxValue;
} else {
timer.next_run = DateTime.GetTimeMonotonic () + TimeSpan.TicksPerMillisecond * timer.period_ms;
new_time.Add (timer);
}
}
// Reschedule timers with a new due time
count = new_time.Count;
for (i = 0; i < count; i++) {
Timer timer = (Timer) new_time [i];
Add (timer);
}
new_time.Clear ();
ShrinkIfNeeded (new_time, 512);
// Shrink the list
int capacity = list.Capacity;
count = list.Count;
if (capacity > 1024 && count > 0 && (capacity / count) > 3)
list.Capacity = count * 2;
long min_next_run = Int64.MaxValue;
if (list.Count > 0)
min_next_run = ((Timer) list.GetByIndex (0)).next_run;
//PrintList ();
int ms_wait = -1;
if (min_next_run != Int64.MaxValue) {
long diff = min_next_run - DateTime.GetTimeMonotonic ();
ms_wait = (int)(diff / TimeSpan.TicksPerMillisecond);
if (ms_wait < 0)
ms_wait = 0;
}
// Wait until due time or a timer is changed and moves from/to the first place in the list.
Monitor.Wait (this, ms_wait);
}
}
}