From 930b197ab9bd69dd231ec0c2ba4527b54cbae5c9 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 25 Oct 2007 10:44:13 +0000 Subject: [PATCH] *** empty log message *** --- Changes | 1 + src/iom.C | 297 ++++++++++++++++++++++++++++++------------------------ src/iom.h | 76 +++++++++++++- 3 files changed, 239 insertions(+), 135 deletions(-) diff --git a/Changes b/Changes index 4832b56a..2d43c60c 100644 --- a/Changes +++ b/Changes @@ -25,6 +25,7 @@ DUMB: support tex fonts - fixed some minor memleaks on incorrect usage or missing DISPLAY. - implement xterm 1002/1003 mouse tracking modes (exg). + - updated io_manager. 8.3 Wed Aug 1 20:21:31 CEST 2007 - new option: skipScroll/-ss, enabled by default. diff --git a/src/iom.C b/src/iom.C index 1516cf2f..69775517 100644 --- a/src/iom.C +++ b/src/iom.C @@ -51,18 +51,22 @@ #define TV_FRAC tv_usec #define TV_MULT 1000000L +#ifndef IOM_LIBEVENT #if IOM_IO static io_manager_vec iow; #endif -#if IOM_CHECK -static io_manager_vec cw; -#endif #if IOM_TIME static io_manager_vec tw; #endif +#endif + +#if IOM_CHECK +static io_manager_vec cw; +#endif #if IOM_IDLE static io_manager_vec iw; #endif + #if IOM_SIG static int sigpipe[2]; // signal signalling pipe static sigset_t sigs; @@ -74,6 +78,7 @@ struct sig_vec : io_manager_vec { }; static vector sw; #endif + #if IOM_CHILD static io_manager_vec pw; #endif @@ -153,6 +158,9 @@ static struct init { { #ifdef IOM_PREINIT { IOM_PREINIT } +#endif +#ifdef IOM_LIBEVENT + event_init (); #endif iom_valid = true; @@ -229,19 +237,35 @@ void io_manager::unreg (watcher &w, io_manager_vec &queue) } #if IOM_TIME +# ifdef IOM_LIBEVENT + void iom_time_c_callback (int fd, short events, void *data) + { + time_watcher *w = static_cast(data); + w->call (*w); + } +# else + void io_manager::reg (time_watcher &w) { io_manager::reg (w, tw); } + void io_manager::unreg (time_watcher &w) { io_manager::unreg (w, tw); } +# endif + void time_watcher::trigger () { call (*this); - io_manager::reg (*this); + start (); } - -void io_manager::reg (time_watcher &w) { io_manager::reg (w, tw); } -void io_manager::unreg (time_watcher &w) { io_manager::unreg (w, tw); } #endif #if IOM_IO -void io_manager::reg (io_watcher &w) { io_manager::reg (w, iow); } -void io_manager::unreg (io_watcher &w) { io_manager::unreg (w, iow); } +# ifdef IOM_LIBEVENT + void iom_io_c_callback (int fd, short events, void *data) + { + io_watcher *w = static_cast(data); + w->call (*w, events); + } +# else + void io_manager::reg (io_watcher &w) { io_manager::reg (w, iow); } + void io_manager::unreg (io_watcher &w) { io_manager::unreg (w, iow); } +# endif #endif #if IOM_CHECK @@ -329,47 +353,48 @@ void io_manager::loop () { init::required (); -#if IOM_TIME - set_now (); -#endif + #if IOM_TIME + set_now (); + #endif for (;;) { + #ifndef IOM_LIBEVENT + #if IOM_TIME + // call pending time watchers + { + bool activity; -#if IOM_TIME - // call pending time watchers - { - bool activity; - - do - { - activity = false; - - for (int i = tw.size (); i--; ) - if (!tw[i]) - tw.erase_unordered (i); - else if (tw[i]->at <= NOW) - { - time_watcher &w = *tw[i]; - - unreg (w); - w.call (w); + do + { + activity = false; - activity = true; - } - } - while (activity); - } -#endif + for (int i = tw.size (); i--; ) + if (!tw[i]) + tw.erase_unordered (i); + else if (tw[i]->at <= NOW) + { + time_watcher &w = *tw[i]; + + unreg (w); + w.call (w); -#if IOM_CHECK - // call all check watchers - for (int i = cw.size (); i--; ) - if (!cw[i]) - cw.erase_unordered (i); - else - cw[i]->call (*cw[i]); -#endif + activity = true; + } + } + while (activity); + } + #endif + #endif + + #if IOM_CHECK + // 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; @@ -383,24 +408,25 @@ void io_manager::loop () } else #endif +#ifndef IOM_LIBEVENT { -#if IOM_TIME - // find earliest active watcher - time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times + #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; + 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; - } + 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 } -#endif #if IOM_IO || IOM_SIG fd_set rfd, wfd; @@ -410,96 +436,108 @@ void io_manager::loop () int fds = 0; -# if IOM_IO - for (io_manager_vec::const_iterator i = iow.end (); i-- > iow.begin (); ) - if (*i) - { - if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd); - if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd); + #if IOM_IO + for (io_manager_vec::const_iterator i = iow.end (); i-- > iow.begin (); ) + if (*i) + { + if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd); + if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd); - if ((*i)->fd >= fds) fds = (*i)->fd + 1; - } -# endif + if ((*i)->fd >= fds) fds = (*i)->fd + 1; + } + #endif if (!to && !fds) //TODO: also check idle_watchers and check_watchers? break; // no events -# if IOM_SIG - FD_SET (sigpipe[0], &rfd); - if (sigpipe[0] >= fds) fds = sigpipe[0] + 1; -# endif + #if IOM_SIG + FD_SET (sigpipe[0], &rfd); + if (sigpipe[0] >= fds) fds = sigpipe[0] + 1; + #endif -# if IOM_SIG - // there is no race, as we use a pipe for signals, so select - // will return if a signal is caught. - sigprocmask (SIG_UNBLOCK, &sigs, NULL); -# endif + #if IOM_SIG + // there is no race, as we use a pipe for signals, so select + // will return if a signal is caught. + sigprocmask (SIG_UNBLOCK, &sigs, NULL); + #endif fds = select (fds, &rfd, &wfd, NULL, to); -# if IOM_SIG - sigprocmask (SIG_BLOCK, &sigs, NULL); -# endif + #if IOM_SIG + sigprocmask (SIG_BLOCK, &sigs, NULL); + #endif -# if IOM_TIME - { - // 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 +#else + if (to) + event_loop (EVLOOP_NONBLOCK); + else + event_loop (EVLOOP_ONCE); +#endif - if (fds > 0) + #if IOM_TIME { -# if IOM_SIG - if (FD_ISSET (sigpipe[0], &rfd)) - { - char ch; - - while (read (sigpipe[0], &ch, 1) > 0) - ; - - for (vector::iterator svp = sw.end (); svp-- > sw.begin (); ) - if (*svp && (*svp)->pending) - { - sig_vec &sv = **svp; - for (int i = sv.size (); i--; ) - if (!sv[i]) - sv.erase_unordered (i); - else - sv[i]->call (*sv[i]); - - sv.pending = false; - } - } -# endif + // 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 IOM_IO - for (int i = iow.size (); i--; ) - if (!iow[i]) - iow.erase_unordered (i); - else +#ifndef IOM_LIBEVENT + if (fds > 0) + { + #if IOM_SIG + if (FD_ISSET (sigpipe[0], &rfd)) { - io_watcher &w = *iow[i]; - short revents = w.events; + char ch; + + while (read (sigpipe[0], &ch, 1) > 0) + ; + + for (vector::iterator svp = sw.end (); svp-- > sw.begin (); ) + if (*svp && (*svp)->pending) + { + sig_vec &sv = **svp; + for (int i = sv.size (); i--; ) + if (!sv[i]) + sv.erase_unordered (i); + else + sv[i]->call (*sv[i]); + + sv.pending = false; + } + } + #endif - if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ; - if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE; + #if IOM_IO + for (int i = iow.size (); i--; ) + if (!iow[i]) + iow.erase_unordered (i); + else + { + io_watcher &w = *iow[i]; + short revents = w.events; - if (revents) - w.call (w, revents); - } -#endif + if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ; + if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE; + + if (revents) + w.call (w, revents); + } + #endif } else if (fds < 0 && errno != EINTR) { perror ("io_manager: fatal error while waiting for I/O or time event, aborting."); abort (); } +#else + if (0) + ; +#endif #if IOM_IDLE else for (int i = iw.size (); i--; ) @@ -513,9 +551,8 @@ void io_manager::loop () if (!to) break; - select (0, 0, 0, 0, &to); + select (0, 0, 0, 0, to); set_now (); -#else break; #endif } diff --git a/src/iom.h b/src/iom.h index d6f4196c..e8f98a6d 100644 --- a/src/iom.h +++ b/src/iom.h @@ -41,6 +41,14 @@ extern tstamp NOW; // TSTAMP_MAX must still fit into a positive struct timeval #define TSTAMP_MAX (double)(1UL<<31) +//#define IOM_LIBEVENT "event.h" *NOT* a supported feature +#ifdef IOM_LIBEVENT +# include +# include IOM_LIBEVENT +# undef IOM_IO +# define IOM_IO 1 +#endif + struct watcher; #if IOM_IO struct io_watcher; @@ -92,21 +100,23 @@ public: #endif // register a watcher +#ifndef IOM_LIBEVENT #if IOM_IO static void reg (io_watcher &w); static void unreg (io_watcher &w); #endif #if IOM_TIME static void reg (time_watcher &w); static void unreg (time_watcher &w); #endif +#if IOM_SIG + static void reg (sig_watcher &w); static void unreg (sig_watcher &w); +#endif #if IOM_CHECK static void reg (check_watcher &w); static void unreg (check_watcher &w); #endif +#endif #if IOM_IDLE static void reg (idle_watcher &w); static void unreg (idle_watcher &w); #endif -#if IOM_SIG - static void reg (sig_watcher &w); static void unreg (sig_watcher &w); -#endif #if IOM_CHILD static void reg (child_watcher &w); static void unreg (child_watcher &w); #endif @@ -123,6 +133,29 @@ struct watcher { }; #if IOM_IO +#ifdef IOM_LIBEVENT +enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = EV_READ, EVENT_WRITE = EV_WRITE }; + +void iom_io_c_callback (int fd, short events, void *data); + +struct io_watcher : watcher, callback { + struct event ev; + int fd; + + void set (int fd_, short events_) { fd = fd_; event_set (&ev, fd_, events_, iom_io_c_callback, (void *)this); } + + void set (short events_) { set (fd, events_); } + void start () { event_add (&ev, 0); active = 1; } + void start (int fd_, short events_) { set (fd_, events_); start (); } + void stop () { if (active) event_del (&ev); active = 0; } + + template + io_watcher (O object, M method) + : callback (object, method) + { } + ~io_watcher () { stop (); } +}; +#else enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = 1, EVENT_WRITE = 2 }; struct io_watcher : watcher, callback { @@ -133,7 +166,7 @@ struct io_watcher : watcher, callback { void set (short events_) { set (fd, events_); } void start () { io_manager::reg (*this); } - void start (int fd_, short events_) { set (fd_, events_); io_manager::reg (*this); } + void start (int fd_, short events_) { set (fd_, events_); start (); } void stop () { io_manager::unreg (*this); } template @@ -143,8 +176,40 @@ struct io_watcher : watcher, callback { ~io_watcher () { stop (); } }; #endif +#endif #if IOM_TIME +#ifdef IOM_LIBEVENT +void iom_time_c_callback (int fd, short events, void *data); + +struct time_watcher : watcher, callback { + struct event ev; + tstamp at; + + void trigger (); + + void set (tstamp when) { at = when; } + void operator () () { trigger (); } + void start () + { + struct timeval tv; + tv.tv_sec = (long)at; + tv.tv_usec = (long)((at - (tstamp)tv.tv_sec) * 1000000.); + evtimer_add (&ev, &tv); + active = 1; + } + void start (tstamp when) { set (when); start (); } + void stop () { if (active) evtimer_del (&ev); active = 0; } + + template + time_watcher (O object, M method) + : callback (object, method), at (0) + { + evtimer_set (&ev, iom_time_c_callback, (void *)this); + } + ~time_watcher () { stop (); } +}; +#else struct time_watcher : watcher, callback { tstamp at; @@ -153,7 +218,7 @@ struct time_watcher : watcher, callback { void set (tstamp when) { at = when; } void operator () () { trigger (); } void start () { io_manager::reg (*this); } - void start (tstamp when) { set (when); io_manager::reg (*this); } + void start (tstamp when) { set (when); start (); } void stop () { io_manager::unreg (*this); } template @@ -163,6 +228,7 @@ struct time_watcher : watcher, callback { ~time_watcher () { stop (); } }; #endif +#endif #if IOM_CHECK // run before checking for new events -- 2.34.1