--- gvpe/src/iom.C 2003/03/21 23:17:01 1.4 +++ gvpe/src/iom.C 2003/03/28 05:40:54 1.7 @@ -37,22 +37,28 @@ void time_watcher::set (tstamp when) { - iom.unreg (this); at = when; - iom.reg (this); + + if (registered) + iom.reschedule_time_watchers (); + else + iom.reg (this); } void time_watcher::trigger () { - iom.unreg (this); call (at); - iom.reg (this); + + if (registered) + iom.reschedule_time_watchers (); + else + iom.reg (this); } void time_watcher::start () { - iom.unreg (this); - iom.reg (this); + if (!registered) + iom.reg (this); } void io_manager::reg (int fd, short events, io_watcher *w) @@ -91,24 +97,39 @@ } } +void io_manager::reschedule_time_watchers () +{ + make_heap (tw.begin (), tw.end (), lowest_first); +} + void io_manager::reg (time_watcher *w) { + if (w->registered) + slog (L_CRIT, "FATAL: io_manager::reg(time_watcher) called on already-registered watcher"); + + w->registered = true; + tw.push_back (w); push_heap (tw.begin (), tw.end (), lowest_first); } void io_manager::unreg (time_watcher *w) { - unsigned int sz = tw.size (); - unsigned int i = find (tw.begin (), tw.end (), w) - tw.begin (); - - if (i != sz) + if (w->registered) { - if (i != sz - 1) - tw[i] = tw[sz - 1]; + unsigned int sz = tw.size (); + unsigned int i = find (tw.begin (), tw.end (), w) - tw.begin (); + + if (i != sz) + { + if (i != sz - 1) + tw[i] = tw[sz - 1]; + + tw.pop_back (); + reschedule_time_watchers (); + } - tw.pop_back (); - make_heap (tw.begin (), tw.end (), lowest_first); + w->registered = false; } } @@ -129,16 +150,20 @@ { while (tw[0]->at <= NOW) { + // remove the first watcher + time_watcher *w = tw[0]; + pop_heap (tw.begin (), tw.end (), lowest_first); - time_watcher *w = *(tw.end () - 1); + tw.pop_back (); + + w->registered = false; + + // call it + w->call (w->at); - if (w->at >= 0) - { - w->call (w->at); - push_heap (tw.begin (), tw.end (), lowest_first); - } - else - tw.pop_back (); + // re-add it if necessary + if (w->at >= 0 && !w->registered) + reg (w); } int timeout = (int) ((tw[0]->at - NOW) * 1000);