*** empty log message ***
authorpcg <pcg>
Fri, 2 Apr 2004 14:30:06 +0000 (14:30 +0000)
committerpcg <pcg>
Fri, 2 Apr 2004 14:30:06 +0000 (14:30 +0000)
src/iom.C
src/iom.h

index 586301b..77c64f8 100644 (file)
--- a/src/iom.C
+++ b/src/iom.C
@@ -23,6 +23,8 @@
 
 #include <sys/time.h>
 
+#include <assert.h>
+
 #if 1 // older unices need these includes for select (2)
 # include <unistd.h>
 # include <sys/types.h>
@@ -32,6 +34,9 @@
 // until that happens, sys/select.h must come last
 #include <sys/select.h>
 
+// for IOM_SIG
+#include <signal.h>
+
 #include "iom.h"
 
 // TSTAMP_MAX must still fit into a positive struct timeval
@@ -53,8 +58,8 @@ static struct tw0 : time_watcher
 
     tw0 ()
         : time_watcher (this, &tw0::cb)
-    { }}
-tw0;
+    { }
+  } tw0;
 
 tstamp NOW;
 static bool iom_valid;
@@ -124,9 +129,67 @@ inline void set_now (void)
   gettimeofday (&tv, 0);
 
   NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000;
+}
 #endif
+
+#if IOM_SIG
+// race conditions galore
+
+void io_manager::sighandler (int signum)
+{
+  assert (0 < signum && signum <= iom.sw.size ());
+
+  sig_vec &sv = *iom.sw [signum - 1];
+
+  for (int i = sv.size (); i--; )
+    if (!sv[i])
+      sv.erase_unordered (i);
+    else
+      sv[i]->call (*sv[i]);
 }
 
+void io_manager::reg (sig_watcher *w)
+{
+  assert (0 < w->signum);
+
+  sw.reserve (w->signum);
+
+  sig_vec *&sv = sw [w->signum - 1];
+
+  if (!sv)
+    {
+      sv = new sig_vec;
+
+      struct sigaction sa;
+      sa.sa_handler = io_manager::sighandler;
+      sigfillset (&sa.sa_mask);
+      sa.sa_flags = 0;
+
+      if (sigaction (w->signum, &sa, 0))
+        {
+          perror ("Error while installing signal handler");
+          abort ();
+        }
+    }
+
+  reg (w, *sv);
+}
+
+void io_manager::unreg (sig_watcher *w)
+{
+  assert (0 < w->signum && w->signum <= sw.size ());
+  
+  unreg (w, *sw [w->signum - 1]);
+}
+
+void sig_watcher::start (int signum)
+{
+  stop ();
+  this->signum = signum;
+  iom.reg (this);
+}
+#endif
+  
 void io_manager::loop ()
 {
 #if IOM_TIME
index 0ae3e25..6106547 100644 (file)
--- a/src/iom.h
+++ b/src/iom.h
@@ -40,6 +40,9 @@
 #ifndef IOM_IDLE
 # define IOM_IDLE 0
 #endif
+#ifndef IOM_SIG
+# define IOM_SIG 0
+#endif
 
 typedef double tstamp;
 extern tstamp NOW;
@@ -57,6 +60,9 @@ struct check_watcher;
 #if IOM_IDLE
 struct idle_watcher;
 #endif
+#if IOM_SIG
+struct sig_watcher;
+#endif
 
 template<class watcher>
 struct io_manager_vec : vector<watcher *> {
@@ -88,6 +94,11 @@ class io_manager {
 #if IOM_IDLE
   io_manager_vec<idle_watcher>  iw;
 #endif
+#if IOM_SIG
+  typedef io_manager_vec<sig_watcher> sig_vec;
+  vector<sig_vec *> sw;
+  static void sighandler (int signum);
+#endif
 
   template<class watcher>
   void reg (watcher *w, io_manager_vec<watcher> &queue);
@@ -109,6 +120,9 @@ public:
 #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 ();
 
@@ -194,5 +208,20 @@ struct idle_watcher : watcher, callback1<void, idle_watcher &> {
 };
 #endif
 
+#if IOM_SIG
+struct sig_watcher : watcher, callback1<void, sig_watcher &> {
+  int signum;
+
+  void start (int signum);
+  void stop () { iom.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