*** empty log message ***
authorroot <root>
Thu, 25 Oct 2007 10:44:13 +0000 (10:44 +0000)
committerroot <root>
Thu, 25 Oct 2007 10:44:13 +0000 (10:44 +0000)
Changes
src/iom.C
src/iom.h

diff --git a/Changes b/Changes
index 4832b56a6fea4bb258d5ee778a75ba07fdf6bf13..2d43c60caab0682d41ad0717c097cccb1be05c79 100644 (file)
--- a/Changes
+++ b/Changes
@@ -25,6 +25,7 @@ DUMB: support tex fonts
         - fixed some minor memleaks on incorrect usage or
           missing DISPLAY.
         - implement xterm 1002/1003 mouse tracking modes (exg).
+        - updated io_manager.
 
 8.3  Wed Aug  1 20:21:31 CEST 2007
        - new option: skipScroll/-ss, enabled by default.
index 1516cf2ff9425eba11426efd54cea3af30f56392..69775517607a20ef04c2b26fed0f368ed55ff004 100644 (file)
--- a/src/iom.C
+++ b/src/iom.C
 #define TV_FRAC tv_usec
 #define TV_MULT 1000000L
 
+#ifndef IOM_LIBEVENT
 #if IOM_IO
 static io_manager_vec<io_watcher>    iow;
 #endif
-#if IOM_CHECK
-static io_manager_vec<check_watcher> cw;
-#endif
 #if IOM_TIME
 static io_manager_vec<time_watcher>  tw;
 #endif
+#endif
+
+#if IOM_CHECK
+static io_manager_vec<check_watcher> cw;
+#endif
 #if IOM_IDLE
 static io_manager_vec<idle_watcher>  iw;
 #endif
+
 #if IOM_SIG
 static int sigpipe[2]; // signal signalling pipe
 static sigset_t sigs;
@@ -74,6 +78,7 @@ struct sig_vec : io_manager_vec<sig_watcher> {
 };
 static vector<sig_vec *> sw;
 #endif
+
 #if IOM_CHILD
 static io_manager_vec<child_watcher>  pw;
 #endif
@@ -153,6 +158,9 @@ static struct init {
   {
 #ifdef IOM_PREINIT
     { IOM_PREINIT }
+#endif
+#ifdef IOM_LIBEVENT
+    event_init ();
 #endif
     iom_valid = true;
 
@@ -229,19 +237,35 @@ void io_manager::unreg (watcher &w, io_manager_vec<watcher> &queue)
 }
 
 #if IOM_TIME
+# ifdef IOM_LIBEVENT
+  void iom_time_c_callback (int fd, short events, void *data)
+  {
+    time_watcher *w = static_cast<time_watcher *>(data);
+    w->call (*w);
+  }
+# else
+  void io_manager::reg   (time_watcher &w)  { io_manager::reg   (w, tw); }
+  void io_manager::unreg (time_watcher &w)  { io_manager::unreg (w, tw); }
+# endif
+
 void time_watcher::trigger ()
 {
   call (*this);
-  io_manager::reg (*this);
+  start ();
 }
-
-void io_manager::reg   (time_watcher &w)  { io_manager::reg   (w, tw); }
-void io_manager::unreg (time_watcher &w)  { io_manager::unreg (w, tw); }
 #endif
 
 #if IOM_IO
-void io_manager::reg   (io_watcher &w)    { io_manager::reg   (w, iow); }
-void io_manager::unreg (io_watcher &w)    { io_manager::unreg (w, iow); }
+# ifdef IOM_LIBEVENT
+  void iom_io_c_callback (int fd, short events, void *data)
+  {
+    io_watcher *w = static_cast<io_watcher *>(data);
+    w->call (*w, events);
+  }
+# else
+  void io_manager::reg   (io_watcher &w)    { io_manager::reg   (w, iow); }
+  void io_manager::unreg (io_watcher &w)    { io_manager::unreg (w, iow); }
+# endif
 #endif
 
 #if IOM_CHECK
@@ -329,47 +353,48 @@ void io_manager::loop ()
 {
   init::required ();
 
-#if IOM_TIME
-  set_now ();
-#endif
+  #if IOM_TIME
+    set_now ();
+  #endif
 
   for (;;)
     {
+      #ifndef IOM_LIBEVENT
+      #if IOM_TIME
+        // call pending time watchers
+        {
+          bool activity;
 
-#if IOM_TIME
-      // call pending time watchers
-      {
-        bool activity;
-
-        do
-          {
-            activity = false;
-
-            for (int i = tw.size (); i--; )
-              if (!tw[i])
-                tw.erase_unordered (i);
-              else if (tw[i]->at <= NOW)
-                {
-                  time_watcher &w = *tw[i];
-                  
-                  unreg (w);
-                  w.call (w);
+          do
+            {
+              activity = false;
 
-                  activity = true;
-                }
-          }
-        while (activity);
-      }
-#endif
+              for (int i = tw.size (); i--; )
+                if (!tw[i])
+                  tw.erase_unordered (i);
+                else if (tw[i]->at <= NOW)
+                  {
+                    time_watcher &w = *tw[i];
+                    
+                    unreg (w);
+                    w.call (w);
 
-#if IOM_CHECK
-      // call all check watchers
-      for (int i = cw.size (); i--; )
-        if (!cw[i])
-          cw.erase_unordered (i);
-        else
-          cw[i]->call (*cw[i]);
-#endif
+                    activity = true;
+                  }
+            }
+          while (activity);
+        }
+      #endif
+      #endif
+
+      #if IOM_CHECK
+        // call all check watchers
+        for (int i = cw.size (); i--; )
+          if (!cw[i])
+            cw.erase_unordered (i);
+          else
+            cw[i]->call (*cw[i]);
+      #endif
 
       struct TIMEVAL *to = 0;
       struct TIMEVAL tval;
@@ -383,24 +408,25 @@ void io_manager::loop ()
         }
       else
 #endif
+#ifndef IOM_LIBEVENT
         {
-#if IOM_TIME
-          // find earliest active watcher
-          time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times
+          #if IOM_TIME
+            // find earliest active watcher
+            time_watcher *next = tw[0]; // the first time-watcher must exist at ALL times
 
-          for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); )
-            if (*i && (*i)->at < next->at)
-              next = *i;
+            for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); )
+              if (*i && (*i)->at < next->at)
+                next = *i;
 
-          if (next->at > NOW && next != tw[0])
-            {
-              double diff = next->at - NOW;
-              tval.tv_sec  = (int)diff;
-              tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT);
-              to = &tval;
-            }
+            if (next->at > NOW && next != tw[0])
+              {
+                double diff = next->at - NOW;
+                tval.tv_sec  = (int)diff;
+                tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT);
+                to = &tval;
+              }
+          #endif
         }
-#endif
 
 #if IOM_IO || IOM_SIG
       fd_set rfd, wfd;
@@ -410,96 +436,108 @@ void io_manager::loop ()
 
       int fds = 0;
 
-if IOM_IO
-      for (io_manager_vec<io_watcher>::const_iterator i = iow.end (); i-- > iow.begin (); )
-        if (*i)
-          {
-            if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd);
-            if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd);
+      #if IOM_IO
+        for (io_manager_vec<io_watcher>::const_iterator i = iow.end (); i-- > iow.begin (); )
+          if (*i)
+            {
+              if ((*i)->events & EVENT_READ ) FD_SET ((*i)->fd, &rfd);
+              if ((*i)->events & EVENT_WRITE) FD_SET ((*i)->fd, &wfd);
 
-            if ((*i)->fd >= fds) fds = (*i)->fd + 1;
-          }
-endif
+              if ((*i)->fd >= fds) fds = (*i)->fd + 1;
+            }
+      #endif
 
       if (!to && !fds) //TODO: also check idle_watchers and check_watchers?
         break; // no events
 
-if IOM_SIG
-      FD_SET (sigpipe[0], &rfd);
-      if (sigpipe[0] >= fds) fds = sigpipe[0] + 1;
-endif
+      #if IOM_SIG
+        FD_SET (sigpipe[0], &rfd);
+        if (sigpipe[0] >= fds) fds = sigpipe[0] + 1;
+      #endif
 
-if IOM_SIG
-      // there is no race, as we use a pipe for signals, so select
-      // will return if a signal is caught.
-      sigprocmask (SIG_UNBLOCK, &sigs, NULL);
-endif
+      #if IOM_SIG
+        // there is no race, as we use a pipe for signals, so select
+        // will return if a signal is caught.
+        sigprocmask (SIG_UNBLOCK, &sigs, NULL);
+      #endif
       fds = select (fds, &rfd, &wfd, NULL, to);
-if IOM_SIG
-      sigprocmask (SIG_BLOCK, &sigs, NULL);
-endif
+      #if IOM_SIG
+        sigprocmask (SIG_BLOCK, &sigs, NULL);
+      #endif
 
-# if IOM_TIME
-      {
-        // update time, try to compensate for gross non-monotonic time changes
-        tstamp diff = NOW;
-        set_now ();
-        diff = NOW - diff;
-
-        if (diff < 0)
-          for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); )
-            if (*i)
-              (*i)->at += diff;
-      }
-# endif
+#else
+      if (to)
+        event_loop (EVLOOP_NONBLOCK);
+      else
+        event_loop (EVLOOP_ONCE);
+#endif
 
-      if (fds > 0)
+      #if IOM_TIME
         {
-# if IOM_SIG
-          if (FD_ISSET (sigpipe[0], &rfd))
-            {
-              char ch;
-
-              while (read (sigpipe[0], &ch, 1) > 0)
-                ;
-
-              for (vector<sig_vec *>::iterator svp = sw.end (); svp-- > sw.begin (); )
-                if (*svp && (*svp)->pending)
-                  {
-                    sig_vec &sv = **svp;
-                    for (int i = sv.size (); i--; )
-                      if (!sv[i])
-                        sv.erase_unordered (i);
-                      else
-                        sv[i]->call (*sv[i]);
-
-                    sv.pending = false;
-                  }
-            }
-# endif
+          // update time, try to compensate for gross non-monotonic time changes
+          tstamp diff = NOW;
+          set_now ();
+          diff = NOW - diff;
+
+          if (diff < 0)
+            for (io_manager_vec<time_watcher>::const_iterator i = tw.end (); i-- > tw.begin (); )
+              if (*i)
+                (*i)->at += diff;
+        }
+      #endif
 
-# if IOM_IO
-          for (int i = iow.size (); i--; )
-            if (!iow[i])
-              iow.erase_unordered (i);
-            else
+#ifndef IOM_LIBEVENT
+      if (fds > 0)
+        {
+          #if IOM_SIG
+            if (FD_ISSET (sigpipe[0], &rfd))
               {
-                io_watcher &w = *iow[i];
-                short revents = w.events;
+                char ch;
+
+                while (read (sigpipe[0], &ch, 1) > 0)
+                  ;
+
+                for (vector<sig_vec *>::iterator svp = sw.end (); svp-- > sw.begin (); )
+                  if (*svp && (*svp)->pending)
+                    {
+                      sig_vec &sv = **svp;
+                      for (int i = sv.size (); i--; )
+                        if (!sv[i])
+                          sv.erase_unordered (i);
+                        else
+                          sv[i]->call (*sv[i]);
+
+                      sv.pending = false;
+                    }
+              }
+          #endif
 
-                if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ;
-                if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE;
+          #if IOM_IO
+            for (int i = iow.size (); i--; )
+              if (!iow[i])
+                iow.erase_unordered (i);
+              else
+                {
+                  io_watcher &w = *iow[i];
+                  short revents = w.events;
 
-                if (revents)
-                  w.call (w, revents);
-              }
-#endif
+                  if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ;
+                  if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE;
+
+                  if (revents)
+                    w.call (w, revents);
+                }
+          #endif
         }
       else if (fds < 0 && errno != EINTR)
         {
           perror ("io_manager: fatal error while waiting for I/O or time event, aborting.");
           abort ();
         }
+#else
+      if (0)
+        ;
+#endif
 #if IOM_IDLE
       else
         for (int i = iw.size (); i--; )
@@ -513,9 +551,8 @@ void io_manager::loop ()
       if (!to)
         break;
 
-      select (0, 0, 0, 0, &to);
+      select (0, 0, 0, 0, to);
       set_now ();
-#else
       break;
 #endif
     }
index d6f4196ca726b3d3b53627de62182ae68abeba0b..e8f98a6d030bf429607c752d963e5504ec1a30b4 100644 (file)
--- a/src/iom.h
+++ b/src/iom.h
@@ -41,6 +41,14 @@ 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 <sys/time.h>
+# include IOM_LIBEVENT
+# undef IOM_IO
+# define IOM_IO 1
+#endif
+
 struct watcher;
 #if IOM_IO
 struct io_watcher;
@@ -92,21 +100,23 @@ public:
 #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);
-#endif
 #if IOM_CHILD
   static void reg (child_watcher &w); static void unreg (child_watcher &w);
 #endif
@@ -123,6 +133,29 @@ struct watcher {
 };
 
 #if IOM_IO
+#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, callback<void (io_watcher &, short)> {
+  struct event ev;
+  int fd;
+
+  void set (int fd_, short events_) { fd = fd_; event_set (&ev, fd_, events_, iom_io_c_callback, (void *)this); }
+
+  void set (short events_) { set (fd, events_); }
+  void start () { 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<class O, class M>
+  io_watcher (O object, M method)
+  : callback<void (io_watcher &, short)> (object, method)
+  { }
+  ~io_watcher () { stop (); }
+};
+#else
 enum { EVENT_UNDEF = -1, EVENT_NONE = 0, EVENT_READ = 1, EVENT_WRITE = 2 };
 
 struct io_watcher : watcher, callback<void (io_watcher &, short)> {
@@ -133,7 +166,7 @@ struct io_watcher : watcher, callback<void (io_watcher &, short)> {
 
   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<class O, class M>
@@ -143,8 +176,40 @@ struct io_watcher : watcher, callback<void (io_watcher &, short)> {
   ~io_watcher () { stop (); }
 };
 #endif
+#endif
 
 #if IOM_TIME
+#ifdef IOM_LIBEVENT
+void iom_time_c_callback (int fd, short events, void *data);
+
+struct time_watcher : watcher, callback<void (time_watcher &)> {
+  struct event ev;
+  tstamp at;
+
+  void trigger ();
+
+  void set (tstamp when) { at = when; }
+  void operator () () { trigger (); }
+  void start ()
+  {
+    struct timeval tv;
+    tv.tv_sec  = (long)at;
+    tv.tv_usec = (long)((at - (tstamp)tv.tv_sec) * 1000000.);
+    evtimer_add (&ev, &tv);
+    active = 1;
+  }
+  void start (tstamp when) { set (when); start (); }
+  void stop () { if (active) evtimer_del (&ev); active = 0; }
+
+  template<class O, class M>
+  time_watcher (O object, M method)
+  : callback<void (time_watcher &)> (object, method), at (0)
+  {
+    evtimer_set (&ev, iom_time_c_callback, (void *)this);
+  }
+  ~time_watcher () { stop (); }
+};
+#else
 struct time_watcher : watcher, callback<void (time_watcher &)> {
   tstamp at;
 
@@ -153,7 +218,7 @@ struct time_watcher : watcher, callback<void (time_watcher &)> {
   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<class O, class M>
@@ -163,6 +228,7 @@ struct time_watcher : watcher, callback<void (time_watcher &)> {
   ~time_watcher () { stop (); }
 };
 #endif
+#endif
 
 #if IOM_CHECK
 // run before checking for new events