--- gvpe/src/iom.C 2003/03/28 05:40:54 1.7 +++ gvpe/src/iom.C 2003/04/05 02:32:40 1.11 @@ -23,31 +23,31 @@ #include #include +#include "gettext.h" + #include "slog.h" #include "iom.h" -inline bool lowest_first (const time_watcher *a, const time_watcher *b) +tstamp NOW; +bool iom_valid; +io_manager iom; + +inline bool earliest_first (const time_watcher *a, const time_watcher *b) { return a->at > b->at; } -tstamp NOW; - -io_manager iom; - void time_watcher::set (tstamp when) { at = when; if (registered) iom.reschedule_time_watchers (); - else - iom.reg (this); } void time_watcher::trigger () { - call (at); + call (*this); if (registered) iom.reschedule_time_watchers (); @@ -55,30 +55,57 @@ iom.reg (this); } -void time_watcher::start () +time_watcher::~time_watcher () { - if (!registered) - iom.reg (this); + if (iom_valid) + iom.unreg (this); } -void io_manager::reg (int fd, short events, io_watcher *w) +void io_watcher::set(int fd_, short events_) { - pollfd pfd; + fd = fd_; + events = events_; - pfd.fd = fd; - pfd.events = events; + if (registered) + { + iom.unreg (this); + iom.reg (this); + } +} - pfs.push_back (pfd); - iow.push_back (w); +io_watcher::~io_watcher () +{ + if (iom_valid) + iom.unreg (this); } -void io_manager::unreg (io_watcher *w) +void io_manager::reg (io_watcher *w) { - unsigned int sz = iow.size (); - unsigned int i = find (iow.begin (), iow.end (), w) - iow.begin (); + if (!w->registered) + { + w->registered = true; + + pollfd pfd; + + pfd.fd = w->fd; + pfd.events = w->events; + + pfs.push_back (pfd); + iow.push_back (w); + } +} - if (i != sz) +void io_manager::unreg (io_watcher *w) +{ + if (w->registered) { + w->registered = false; + + unsigned int sz = iow.size (); + unsigned int i = find (iow.begin (), iow.end (), w) - iow.begin (); + + assert (i != sz); + if (sz == 1) { pfs.clear (); @@ -99,37 +126,36 @@ void io_manager::reschedule_time_watchers () { - make_heap (tw.begin (), tw.end (), lowest_first); + make_heap (tw.begin (), tw.end (), earliest_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; + if (!w->registered) + { + w->registered = true; - tw.push_back (w); - push_heap (tw.begin (), tw.end (), lowest_first); + tw.push_back (w); + push_heap (tw.begin (), tw.end (), earliest_first); + } } void io_manager::unreg (time_watcher *w) { if (w->registered) { + w->registered = false; + 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]; + assert (i != sz); + + if (i != sz - 1) + tw[i] = tw[sz - 1]; - tw.pop_back (); - reschedule_time_watchers (); - } - - w->registered = false; + tw.pop_back (); + reschedule_time_watchers (); } } @@ -153,13 +179,13 @@ // remove the first watcher time_watcher *w = tw[0]; - pop_heap (tw.begin (), tw.end (), lowest_first); + pop_heap (tw.begin (), tw.end (), earliest_first); tw.pop_back (); w->registered = false; // call it - w->call (w->at); + w->call (*w); // re-add it if necessary if (w->at >= 0 && !w->registered) @@ -172,22 +198,36 @@ set_now (); - for (unsigned int i = iow.size (); fds > 0 && i--; ) - if (pfs[i].revents) + vector::iterator w; + vector::iterator p; + + for (w = iow.begin (), p = pfs.begin (); + fds > 0 && w < iow.end (); + ++w, ++p) + if (p->revents) { --fds; - iow[i]->call (pfs[i].revents); + + if (p->revents & POLLNVAL) + { + slog (L_ERR, _("io_watcher started on illegal file descriptor, disabling.")); + (*w)->stop (); + } + else + (*w)->call (**w, p->revents); } } } -void io_manager::idle_cb (tstamp &ts) +void io_manager::idle_cb (time_watcher &w) { - ts = NOW + 86400; // wake up every day, for no good reason + w.at = NOW + 86400; // wake up every day, for no good reason } io_manager::io_manager () { + iom_valid = true; + set_now (); idle = new time_watcher (this, &io_manager::idle_cb); idle->start (0); @@ -195,6 +235,6 @@ io_manager::~io_manager () { - // + iom_valid = false; }