*** empty log message ***
[dana/urxvt.git] / src / iom.C
index 5240df3..6f8e654 100644 (file)
--- a/src/iom.C
+++ b/src/iom.C
@@ -14,7 +14,7 @@
  
     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
 */
 
 #include "iom.h"
@@ -35,7 +35,7 @@
 
 // for IOM_SIG
 #if IOM_SIG
-# include <signal.h>
+# include <csignal>
 # include <fcntl.h>
 #endif
 
@@ -96,12 +96,17 @@ static struct tw0 : time_watcher
 tstamp NOW;
 
 #if IOM_TIME
-inline void set_now (void)
+tstamp io_manager::now ()
 {
   struct timeval tv;
 
   gettimeofday (&tv, 0);
-  NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.;
+  return (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.;
+}
+
+void io_manager::set_now ()
+{
+  NOW = now ();
 }
 #endif
 
@@ -120,14 +125,14 @@ static struct init {
         abort ();
       }
 
-    fcntl (sigpipe[0], F_SETFL, O_NONBLOCK);
-    fcntl (sigpipe[1], F_SETFL, O_NONBLOCK);
+    fcntl (sigpipe[0], F_SETFL, O_NONBLOCK); fcntl (sigpipe[0], F_SETFD, FD_CLOEXEC);
+    fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); fcntl (sigpipe[1], F_SETFD, FD_CLOEXEC);
 #endif
 
     iom_valid = true;
 
 #if IOM_TIME
-    set_now ();
+    io_manager::set_now ();
 
     tw0.start (TSTAMP_MAX);
 #endif
@@ -377,7 +382,17 @@ void io_manager::loop ()
 # endif
 
 # if IOM_TIME
-      set_now ();
+      {
+        // 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 (fds > 0)
@@ -411,13 +426,14 @@ void io_manager::loop ()
               iow.erase_unordered (i);
             else
               {
-                short revents = iow[i]->events;
+                io_watcher &w = *iow[i];
+                short revents = w.events;
 
-                if (!FD_ISSET (iow[i]->fd, &rfd)) revents &= ~EVENT_READ;
-                if (!FD_ISSET (iow[i]->fd, &wfd)) revents &= ~EVENT_WRITE;
+                if (!FD_ISSET (w.fd, &rfd)) revents &= ~EVENT_READ;
+                if (!FD_ISSET (w.fd, &wfd)) revents &= ~EVENT_WRITE;
 
                 if (revents)
-                  iow[i]->call (*iow[i], revents);
+                  w.call (w, revents);
               }
 #endif
         }