--- rxvt-unicode/src/iom.h 2003/11/29 18:42:07 1.3 +++ rxvt-unicode/src/iom.h 2004/04/02 14:30:06 1.12 @@ -1,6 +1,6 @@ /* iom.h -- generic I/O multiplexor - Copyright (C) 2003 Marc Lehmann + Copyright (C) 2003, 2004 Marc Lehmann This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,59 +17,112 @@ Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef VPE_IOM_H__ -#define VPE_IOM_H__ +#ifndef IOM_H__ +#define IOM_H__ -#include +// required: +// - a vector template like simplevec or stl's vector +// - defines for all watcher types required in your app +// edit iom_conf.h as appropriate. +#include "iom_conf.h" -#include "rxvtvec.h" #include "callback.h" -#define IOM_IO 1 -#define IOM_TIME 1 -#undef IOM_CHECK +#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 -#if IOM_IO - typedef double tstamp; - extern tstamp NOW; +typedef double tstamp; +extern tstamp NOW; - struct io_watcher; +struct watcher; +#if IOM_IO +struct io_watcher; #endif #if IOM_TIME - struct time_watcher; +struct time_watcher; #endif #if IOM_CHECK - struct check_watcher; +struct check_watcher; +#endif +#if IOM_IDLE +struct idle_watcher; +#endif +#if IOM_SIG +struct sig_watcher; +#endif + +template +struct io_manager_vec : vector { +#if IOM_CHECK + bool activity; #endif + void erase_unordered (unsigned int pos) + { + watcher *w = (*this)[size () - 1]; + pop_back (); + + if (size ()) + if ((*this)[pos] = w) + w->active = pos + 1; + } +}; + class io_manager { #if IOM_IO - simplevec iow; + io_manager_vec iow; #endif #if IOM_CHECK - simplevec cw; + io_manager_vec cw; #endif #if IOM_TIME - simplevec tw; + io_manager_vec tw; +#endif +#if IOM_IDLE + io_manager_vec iw; +#endif +#if IOM_SIG + typedef io_manager_vec sig_vec; + vector sw; + static void sighandler (int signum); #endif template - void reg (watcher *w, simplevec &queue); + void reg (watcher *w, io_manager_vec &queue); template - void unreg (watcher *w, simplevec &queue); + void unreg (watcher *w, io_manager_vec &queue); public: // register a watcher #if IOM_IO - void reg (io_watcher *w); void unreg (io_watcher *w); + void reg (io_watcher *w); void unreg (io_watcher *w); #endif #if IOM_TIME - void reg (time_watcher *w); void unreg (time_watcher *w); + void reg (time_watcher *w); void unreg (time_watcher *w); #endif #if IOM_CHECK void reg (check_watcher *w); void unreg (check_watcher *w); #endif +#if IOM_IDLE + void reg (idle_watcher *w); void unreg (idle_watcher *w); +#endif +#if IOM_SIG + void reg (sig_watcher *w); void unreg (sig_watcher *w); +#endif void loop (); @@ -79,69 +132,94 @@ extern io_manager iom; // a singleton, together with it's construction/destruction problems. +struct watcher { + int active; /* 0 == inactive, else index into respective vector */ + + watcher () : active (0) { } +}; + #if IOM_IO enum { EVENT_READ = 1, EVENT_WRITE = 2 }; -struct io_watcher : callback2 { +struct io_watcher : watcher, callback2 { int fd; short events; - template - io_watcher (O1 *object, void (O2::*method)(io_watcher &, short)) - : callback2(object,method) - { } - - ~io_watcher (); - - void set(int fd_, short events_) { fd = fd_; events = events_; } + void set (int fd_, short events_) { fd = fd_; events = events_; } - void set(short events_) { set (fd, events_); } + void set (short events_) { set (fd, events_); } + void start () { iom.reg (this); } void start (int fd_, short events_) { set (fd_, events_); iom.reg (this); } void stop () { iom.unreg (this); } + + template + io_watcher (O1 *object, void (O2::*method) (io_watcher &, short)) + : callback2 (object,method) + { } + ~io_watcher () { stop (); } }; #endif #if IOM_TIME -enum { TSTAMP_CANCEL = -1 }; - -struct time_watcher : callback1 { +struct time_watcher : watcher, callback1 { tstamp at; - template - time_watcher (O1 *object, void (O2::*method)(time_watcher &)) - : callback1(object,method) - { } - - ~time_watcher (); - void trigger (); void set (tstamp when) { at = when; } - void operator ()() { trigger (); } + void operator () () { trigger (); } void start () { iom.reg (this); } void start (tstamp when) { set (when); iom.reg (this); } void stop () { iom.unreg (this); } - void reset (tstamp when = TSTAMP_CANCEL) - { - stop (); - at = when; - } + template + time_watcher (O1 *object, void (O2::*method) (time_watcher &)) + : callback1 (object,method), at (0) + { } + ~time_watcher () { stop (); } }; #endif #if IOM_CHECK // run before checking for new events -struct check_watcher : callback1 { +struct check_watcher : watcher, callback1 { + void start () { iom.reg (this); } + void stop () { iom.unreg (this); } + template - check_watcher (O1 *object, void (O2::*method)(check_watcher &)) - : callback1(object,method) + check_watcher (O1 *object, void (O2::*method) (check_watcher &)) + : callback1 (object,method) + { } + ~check_watcher () { stop (); } +}; +#endif + +#if IOM_IDLE +// run after checking for any i/o, but before waiting +struct idle_watcher : watcher, callback1 { + void start () { iom.reg (this); } + void stop () { iom.unreg (this); } + + template + idle_watcher (O1 *object, void (O2::*method) (idle_watcher &)) + : callback1 (object,method) { } + ~idle_watcher () { stop (); } +}; +#endif - ~check_watcher (); +#if IOM_SIG +struct sig_watcher : watcher, callback1 { + int signum; - void start () { iom.reg (this); } + void start (int signum); void stop () { iom.unreg (this); } + + template + sig_watcher (O1 *object, void (O2::*method) (sig_watcher &)) + : callback1 (object,method), signum (-1) + { } + ~sig_watcher () { stop (); } }; #endif