--- gvpe/src/iom.C 2004/09/02 07:50:43 1.21 +++ gvpe/src/iom.C 2004/12/19 18:44:33 1.27 @@ -1,5 +1,5 @@ /* - iom.C -- generic I/O multiplexor + iom.C -- generic I/O multiplexer Copyright (C) 2003, 2004 Marc Lehmann This program is free software; you can redistribute it and/or modify @@ -96,12 +96,17 @@ tstamp NOW; #if IOM_TIME -inline void set_now (void) +tstamp io_manager::now () { struct timeval tv; gettimeofday (&tv, 0); - NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.; + return (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.; +} + +void io_manager::set_now () +{ + NOW = now (); } #endif @@ -120,14 +125,14 @@ abort (); } - fcntl (sigpipe[0], F_SETFL, O_NONBLOCK); - fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); + fcntl (sigpipe[0], F_SETFL, O_NONBLOCK); fcntl (sigpipe[0], F_SETFD, FD_CLOEXEC); + fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); fcntl (sigpipe[1], F_SETFD, FD_CLOEXEC); #endif iom_valid = true; #if IOM_TIME - set_now (); + io_manager::set_now (); tw0.start (TSTAMP_MAX); #endif @@ -154,9 +159,6 @@ if (!w.active) { -#if IOM_CHECK - queue.activity = true; -#endif queue.push_back (&w); w.active = queue.size (); } @@ -275,67 +277,71 @@ for (;;) { - struct TIMEVAL *to = 0; - struct TIMEVAL tval; -#if IOM_IDLE - if (iw.size ()) - { - tval.tv_sec = 0; - tval.TV_FRAC = 0; - to = &tval; - } - else -#endif - { #if IOM_TIME - time_watcher *next; - - for (;;) - { - next = tw[0]; // the first time-watcher must exist at ALL times + // call pending time watchers + { + bool activity; - for (int i = tw.size (); i--; ) - if (!tw[i]) - tw.erase_unordered (i); - else if (tw[i]->at < next->at) - next = tw[i]; + do + { + activity = false; - if (next->at > NOW) - { - if (next != tw[0]) - { - double diff = next->at - NOW; - tval.tv_sec = (int)diff; - tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT); - to = &tval; - } - break; - } - else + for (int i = tw.size (); i--; ) + if (!tw[i]) + tw.erase_unordered (i); + else if (tw[i]->at <= NOW) { - unreg (*next); - next->call (*next); + time_watcher &w = *tw[i]; + + unreg (w); + w.call (w); + + activity = true; } - } + } + while (activity); + } #endif - } #if IOM_CHECK - tw.activity = false; - + // call all check watchers for (int i = cw.size (); i--; ) if (!cw[i]) cw.erase_unordered (i); else cw[i]->call (*cw[i]); +#endif + + struct TIMEVAL *to = 0; + struct TIMEVAL tval; - if (tw.activity) +#if IOM_IDLE + if (iw.size ()) { tval.tv_sec = 0; tval.TV_FRAC = 0; to = &tval; } + else +#endif + { +#if IOM_TIME + // find earliest active watcher + time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times + + for (io_manager_vec::const_iterator i = tw.end (); i-- > tw.begin (); ) + if (*i && (*i)->at < next->at) + next = *i; + + if (next->at > NOW && next != tw[0]) + { + double diff = next->at - NOW; + tval.tv_sec = (int)diff; + tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT); + to = &tval; + } + } #endif #if IOM_IO || IOM_SIG @@ -347,7 +353,7 @@ int fds = 0; # if IOM_IO - for (io_manager_vec::iterator i = iow.end (); i-- > iow.begin (); ) + for (io_manager_vec::const_iterator i = iow.end (); i-- > iow.begin (); ) if (*i) { if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd); @@ -357,7 +363,7 @@ } # endif - if (!to && !fds) //TODO: also check idle_watchers and check_watchers + if (!to && !fds) //TODO: also check idle_watchers and check_watchers? break; // no events # if IOM_SIG @@ -389,7 +395,7 @@ while (read (sigpipe[0], &ch, 1) > 0) ; - for (sig_vec **svp = sw.end (); svp-- > sw.begin (); ) + for (vector::iterator svp = sw.end (); svp-- > sw.begin (); ) if (*svp && (*svp)->pending) { sig_vec &sv = **svp; @@ -410,13 +416,14 @@ iow.erase_unordered (i); else { - short revents = iow[i]->events; + io_watcher &w = *iow[i]; + short revents = w.events; - if (!FD_ISSET (iow[i]->fd, &rfd)) revents &= ~EVENT_READ; - if (!FD_ISSET (iow[i]->fd, &wfd)) revents &= ~EVENT_WRITE; + if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ; + if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE; if (revents) - iow[i]->call (*iow[i], revents); + w.call (w, revents); } #endif }