--- gvpe/src/iom.h 2004/11/11 17:41:55 1.22 +++ gvpe/src/iom.h 2006/05/31 00:39:31 1.33 @@ -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,30 +28,19 @@ // 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 -#endif -#ifndef IOM_ACCURACY -# define IOM_ACCURACY 0.001 // start timers at most this much earlier (can be 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) + struct watcher; #if IOM_IO struct io_watcher; @@ -66,6 +57,9 @@ #if IOM_SIG struct sig_watcher; #endif +#if IOM_CHILD +struct child_watcher; +#endif template struct io_manager_vec : vector { @@ -74,7 +68,7 @@ watcher *w = (*this)[this->size () - 1]; this->pop_back (); - if (this->size ()) + if (!this->empty ()) if (((*this)[pos] = w)) // '=' is correct! w->active = pos + 1; } @@ -89,6 +83,14 @@ 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 #if IOM_IO static void reg (io_watcher &w); static void unreg (io_watcher &w); @@ -105,6 +107,9 @@ #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 static void loop (); }; @@ -112,13 +117,15 @@ 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 }; +enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = 1, EVENT_WRITE = 2 }; -struct io_watcher : watcher, callback2 { +struct io_watcher : watcher, callback { int fd; short events; @@ -129,16 +136,16 @@ void start (int fd_, short events_) { set (fd_, events_); io_manager::reg (*this); } 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 #if IOM_TIME -struct time_watcher : watcher, callback1 { +struct time_watcher : watcher, callback { tstamp at; void trigger (); @@ -149,9 +156,9 @@ void start (tstamp when) { set (when); io_manager::reg (*this); } 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 (); } }; @@ -159,13 +166,13 @@ #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 (); } }; @@ -173,32 +180,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