/*
- iom.h -- generic I/O multiplexor
+ iom.h -- generic I/O multiplexer
Copyright (C) 2003, 2004 Marc Lehmann <pcg@goof.com>
This program is free software; you can redistribute it and/or modify
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
+ Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef IOM_H__
#ifndef IOM_IDLE
# define IOM_IDLE 0
#endif
+#ifndef IOM_SIG
+# define IOM_SIG 0
+#endif
typedef double tstamp;
extern tstamp NOW;
#if IOM_IDLE
struct idle_watcher;
#endif
-
-template<class watcher>
-struct io_manager_vec : protected vector<watcher *> {
- friend class io_manager;
-protected:
-#if IOM_CHECK
- bool activity;
+#if IOM_SIG
+struct sig_watcher;
#endif
+template<class watcher>
+struct io_manager_vec : vector<watcher *> {
void erase_unordered (unsigned int pos)
{
- watcher *w = (*this)[size () - 1];
- pop_back ();
+ watcher *w = (*this)[this->size () - 1];
+ this->pop_back ();
- if (size ())
- if ((*this)[pos] = w)
+ if (!this->empty ())
+ if (((*this)[pos] = w)) // '=' is correct!
w->active = pos + 1;
}
};
+// only used as a namespace, and for initialisation purposes
class io_manager {
-#if IOM_IO
- io_manager_vec<io_watcher> iow;
-#endif
-#if IOM_CHECK
- io_manager_vec<check_watcher> cw;
-#endif
-#if IOM_TIME
- io_manager_vec<time_watcher> tw;
-#endif
-#if IOM_IDLE
- io_manager_vec<idle_watcher> iw;
-#endif
-
template<class watcher>
- void reg (watcher *w, io_manager_vec<watcher> &queue);
+ static void reg (watcher &w, io_manager_vec<watcher> &queue);
template<class watcher>
- void unreg (watcher *w, io_manager_vec<watcher> &queue);
+ static void unreg (watcher &w, io_manager_vec<watcher> &queue);
public:
+#if IOM_TIME
+ // fetch time only
+ static tstamp now ();
+
+ // set NOW
+ static void set_now ();
+#endif
+
// register a watcher
#if IOM_IO
- void reg (io_watcher *w); void unreg (io_watcher *w);
+ static void reg (io_watcher &w); static void unreg (io_watcher &w);
#endif
#if IOM_TIME
- void reg (time_watcher *w); void unreg (time_watcher *w);
+ static void reg (time_watcher &w); static void unreg (time_watcher &w);
#endif
#if IOM_CHECK
- void reg (check_watcher *w); void unreg (check_watcher *w);
+ static void reg (check_watcher &w); static void unreg (check_watcher &w);
#endif
#if IOM_IDLE
- void reg (idle_watcher *w); void unreg (idle_watcher *w);
+ 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
- void loop ();
-
- io_manager ();
- ~io_manager ();
+ static void loop ();
};
-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) { }
+ watcher () : active (0) { }
};
#if IOM_IO
void set (int fd_, short events_) { fd = fd_; events = 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); }
+ void start () { io_manager::reg (*this); }
+ void start (int fd_, short events_) { set (fd_, events_); io_manager::reg (*this); }
+ void stop () { io_manager::unreg (*this); }
template<class O1, class O2>
- io_watcher (O1 *object, void (O2::*method)(io_watcher &, short))
- : callback2<void, io_watcher &, short>(object,method)
+ io_watcher (O1 *object, void (O2::*method) (io_watcher &, short))
+ : callback2<void, io_watcher &, short> (object,method)
{ }
~io_watcher () { stop (); }
};
void trigger ();
void set (tstamp when) { at = when; }
- void operator ()() { trigger (); }
- void start () { iom.reg (this); }
- void start (tstamp when) { set (when); iom.reg (this); }
- void stop () { iom.unreg (this); }
+ void operator () () { trigger (); }
+ void start () { io_manager::reg (*this); }
+ void start (tstamp when) { set (when); io_manager::reg (*this); }
+ void stop () { io_manager::unreg (*this); }
template<class O1, class O2>
- time_watcher (O1 *object, void (O2::*method)(time_watcher &))
- : callback1<void, time_watcher &>(object,method), at(0)
+ time_watcher (O1 *object, void (O2::*method) (time_watcher &))
+ : callback1<void, time_watcher &> (object,method), at (0)
{ }
~time_watcher () { stop (); }
};
#if IOM_CHECK
// run before checking for new events
struct check_watcher : watcher, callback1<void, check_watcher &> {
- void start () { iom.reg (this); }
- void stop () { iom.unreg (this); }
+ void start () { io_manager::reg (*this); }
+ void stop () { io_manager::unreg (*this); }
template<class O1, class O2>
- check_watcher (O1 *object, void (O2::*method)(check_watcher &))
- : callback1<void, check_watcher &>(object,method)
+ check_watcher (O1 *object, void (O2::*method) (check_watcher &))
+ : callback1<void, check_watcher &> (object,method)
{ }
~check_watcher () { stop (); }
};
#if IOM_IDLE
// run after checking for any i/o, but before waiting
struct idle_watcher : watcher, callback1<void, idle_watcher &> {
- void start () { iom.reg (this); }
- void stop () { iom.unreg (this); }
+ void start () { io_manager::reg (*this); }
+ void stop () { io_manager::unreg (*this); }
template<class O1, class O2>
- idle_watcher (O1 *object, void (O2::*method)(idle_watcher &))
- : callback1<void, idle_watcher &>(object,method)
+ idle_watcher (O1 *object, void (O2::*method) (idle_watcher &))
+ : callback1<void, idle_watcher &> (object,method)
{ }
~idle_watcher () { stop (); }
};
#endif
+#if IOM_SIG
+struct sig_watcher : watcher, callback1<void, sig_watcher &> {
+ int signum;
+
+ void start (int signum);
+ void stop () { io_manager::unreg (*this); }
+
+ template<class O1, class O2>
+ sig_watcher (O1 *object, void (O2::*method) (sig_watcher &))
+ : callback1<void, sig_watcher &> (object,method), signum (-1)
+ { }
+ ~sig_watcher () { stop (); }
+};
+#endif
+
#endif