--- rxvt-unicode/src/iom.h 2004/09/02 07:44:40 1.15 +++ rxvt-unicode/src/iom.h 2007/10/25 12:42:00 1.31 @@ -1,8 +1,10 @@ /* - iom.h -- generic I/O multiplexor - Copyright (C) 2003, 2004 Marc Lehmann + iom.h -- generic I/O multiplexer + Copyright (C) 2003-2006 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,8 +15,8 @@ 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 - Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + along with gvpe; if not, write to the Free Software + Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef IOM_H__ @@ -26,27 +28,32 @@ // edit iom_conf.h as appropriate. #include "iom_conf.h" -#include "callback.h" - -#ifndef IOM_IO -# define IOM_IO 0 -#endif -#ifndef IOM_TIME -# define IOM_TIME 0 -#endif -#ifndef IOM_CHECK -# define IOM_CHECK 0 -#endif -#ifndef IOM_IDLE -# define IOM_IDLE 0 -#endif -#ifndef IOM_SIG -# define IOM_SIG 0 +#if IOM_CHILD +# undef IOM_SIG +# define IOM_SIG 1 #endif +#include "callback.h" + typedef double tstamp; 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 +# undef IOM_TIME +# define IOM_TIME 1 +# undef IOM_IDLE // NYI +# undef IOM_SIG // NYI +# undef IOM_CHILD // NYI +#endif + struct watcher; #if IOM_IO struct io_watcher; @@ -63,20 +70,19 @@ #if IOM_SIG struct sig_watcher; #endif +#if IOM_CHILD +struct child_watcher; +#endif template struct io_manager_vec : vector { -#if IOM_CHECK - bool activity; -#endif - void erase_unordered (unsigned int pos) { watcher *w = (*this)[this->size () - 1]; this->pop_back (); - if (this->size ()) - if ((*this)[pos] = w) + if (!this->empty ()) + if (((*this)[pos] = w)) // '=' is correct! w->active = pos + 1; } }; @@ -90,21 +96,34 @@ static void unreg (watcher &w, io_manager_vec &queue); public: +#if IOM_TIME + // fetch time only + static tstamp now (); + + // set NOW + static void set_now (); +#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); +#if IOM_CHILD + static void reg (child_watcher &w); static void unreg (child_watcher &w); #endif static void loop (); @@ -113,13 +132,38 @@ struct watcher { int active; /* 0 == inactive, else index into respective vector */ + bool is_active () { return active; } + watcher () : active (0) { } }; #if IOM_IO -enum { EVENT_READ = 1, EVENT_WRITE = 2 }; +#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, callback2 { +struct io_watcher : watcher, callback { + struct event ev; + int fd; + short events; + + void set (int fd_, short events_); + void set (short events_) { set (fd, events_); } + void start () { if (!active) 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 { int fd; short events; @@ -127,19 +171,47 @@ 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 - io_watcher (O1 *object, void (O2::*method) (io_watcher &, short)) - : callback2 (object,method) + template + io_watcher (O object, M method) + : callback (object, method) { } ~io_watcher () { stop (); } }; #endif +#endif #if IOM_TIME -struct time_watcher : watcher, callback1 { +#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; + if (active) + start (); + } + void operator () () { trigger (); } + void start (); + void start (tstamp when) { at = when; start (); } + void stop () { if (active) evtimer_del (&ev); active = 0; } + + template + time_watcher (O object, M method) + : callback (object, method), at (0) + { } + ~time_watcher () { stop (); } +}; +#else +struct time_watcher : watcher, callback { tstamp at; void trigger (); @@ -147,26 +219,27 @@ 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 - time_watcher (O1 *object, void (O2::*method) (time_watcher &)) - : callback1 (object,method), at (0) + template + time_watcher (O object, M method) + : callback (object, method), at (0) { } ~time_watcher () { stop (); } }; #endif +#endif #if IOM_CHECK // run before checking for new events -struct check_watcher : watcher, callback1 { +struct check_watcher : watcher, callback { void start () { io_manager::reg (*this); } void stop () { io_manager::unreg (*this); } - template - check_watcher (O1 *object, void (O2::*method) (check_watcher &)) - : callback1 (object,method) + template + check_watcher (O object, M method) + : callback (object, method) { } ~check_watcher () { stop (); } }; @@ -174,32 +247,47 @@ #if IOM_IDLE // run after checking for any i/o, but before waiting -struct idle_watcher : watcher, callback1 { +struct idle_watcher : watcher, callback { void start () { io_manager::reg (*this); } void stop () { io_manager::unreg (*this); } - template - idle_watcher (O1 *object, void (O2::*method) (idle_watcher &)) - : callback1 (object,method) + template + idle_watcher (O object, M method) + : callback (object, method) { } ~idle_watcher () { stop (); } }; #endif #if IOM_SIG -struct sig_watcher : watcher, callback1 { +struct sig_watcher : watcher, callback { int signum; void start (int signum); void stop () { io_manager::unreg (*this); } - template - sig_watcher (O1 *object, void (O2::*method) (sig_watcher &)) - : callback1 (object,method), signum (-1) + template + sig_watcher (O object, M method) + : callback (object, method), signum (0) { } ~sig_watcher () { stop (); } }; #endif +#if IOM_CHILD +struct child_watcher : watcher, callback { + int /*pid_t*/ pid; + + void start (int pid) { this->pid = pid; io_manager::reg (*this); } + void stop () { io_manager::unreg (*this); } + + template + child_watcher (O object, M method) + : callback (object, method), pid (0) + { } + ~child_watcher () { stop (); } +}; +#endif + #endif