--- gvpe/src/iom.C 2004/11/12 10:23:33 1.23 +++ gvpe/src/iom.C 2005/03/07 01:31:26 1.31 @@ -1,8 +1,10 @@ /* iom.C -- generic I/O multiplexer - Copyright (C) 2003, 2004 Marc Lehmann + Copyright (C) 2003, 2004 Marc Lehmann - This program is free software; you can redistribute it and/or modify + This file is part of GVPE. + + GVPE is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. @@ -13,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software + along with gvpe; if not, write to the Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -35,7 +37,7 @@ // for IOM_SIG #if IOM_SIG -# include +# include # include #endif @@ -43,9 +45,6 @@ // until that happens, sys/select.h must come last #include -// TSTAMP_MAX must still fit into a positive struct timeval -#define TSTAMP_MAX (double)(1UL<<31) - #define TIMEVAL timeval #define TV_FRAC tv_usec #define TV_MULT 1000000L @@ -96,12 +95,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 +124,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 @@ -285,7 +289,7 @@ for (int i = tw.size (); i--; ) if (!tw[i]) tw.erase_unordered (i); - else if (tw[i]->at <= NOW + IOM_ACCURACY) + else if (tw[i]->at <= NOW) { time_watcher &w = *tw[i]; @@ -377,7 +381,17 @@ # endif # if IOM_TIME - set_now (); + { + // update time, try to compensate for gross non-monotonic time changes + tstamp diff = NOW; + set_now (); + diff = NOW - diff; + + if (diff < 0) + for (io_manager_vec::const_iterator i = tw.end (); i-- > tw.begin (); ) + if (*i) + (*i)->at += diff; + } # endif if (fds > 0) @@ -390,7 +404,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; @@ -411,13 +425,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 }