-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: rxvt-unicode-sixel
action: commit
revision:
path_from:
revision_from: 8df4277dfe31e9e716634b165598cf33ea968c40:
path_to:
revision_to:

git.thebackupbox.net

rxvt-unicode-sixel

git://git.thebackupbox.net/rxvt-unicode-sixel

commit 8df4277dfe31e9e716634b165598cf33ea968c40
Author: Marc Lehmann <schmorp@schmorp.de>
Date:   Fri Jan 16 22:11:09 2004 +0000

    *** empty log message ***

diff --git a/Changes b/Changes

index 12d08c26f3589ca546818c354dd99d90ceca8f9e..

index ..1d33b770050e2520175a8f0c6dc58e4321dbc696 100644

--- a/Changes
+++ b/Changes
@@ -1,6 +1,7 @@
-1.4
+1.4  Fri Jan 16 23:03:22 CET 2004
 	- fix stupid segfault on esc-c.
         - small font tunings.
+        - much better io manager, less bugs, higher speed.

 1.3  2003-12-26
         - fix a bug in font height selection
diff --git a/src/Makefile.in b/src/Makefile.in

index cb5b9a180cd76e37c6f858b7c5c1afeebabdf5c8..

index ..b02189d14066a2eaa3d560e1479bac37a276c39a 100644

--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.6 2003/12/18 00:56:51 pcg Exp $
+# $Id: Makefile.in,v 1.7 2004/01/16 22:11:09 pcg Exp $
 @MCOMMON@

 LINT = lint -DNARROWPROTO=1 $(XINC) -chapbxz
@@ -12,7 +12,7 @@ basedir = ..
 thisdir = src
 MKDIR = @top_srcdir@/autoconf/mkinstalldirs

-SUPLIB = -lsupc++
+SUPLIB = -fno-exceptions -lsupc++ # TODO: only for g++

 # for developers: the following debug options may be used
 #	-DDEBUG_CMD -DDEBUG_MAIN -DDEBUG_MENU -DDEBUG_MENUARROWS
diff --git a/src/command.C b/src/command.C

index 4845be79f184bb13d25fb69369012cd214a7f450..

index ..82140ee9dd0306722c6c9e39aaa9731afab9c4ea 100644

--- a/src/command.C
+++ b/src/command.C
@@ -1,7 +1,7 @@
 /*--------------------------------*-C-*---------------------------------*
  * File:	command.c
  *----------------------------------------------------------------------*
- * $Id: command.C,v 1.27 2003/12/30 01:35:58 pcg Exp $
+ * $Id: command.C,v 1.28 2004/01/16 22:11:09 pcg Exp $
  *
  * All portions of code are copyright by their respective author/s.
  * Copyright (c) 1992      John Bovey, University of Kent at Canterbury <jdb@ukc.ac.uk>
@@ -758,9 +758,10 @@ rxvt_term::process_x_events ()
 void
 rxvt_term::blink_cb (time_watcher &w)
 {
-  w.at += BLINK_INTERVAL;
   hidden_cursor = !hidden_cursor;
   want_refresh = 1;
+
+  w.start (w.at + BLINK_INTERVAL);
 }
 #endif

@@ -1039,8 +1040,6 @@ rxvt_term::pointer_unblank ()
 void
 rxvt_term::pointer_blank ()
 {
-  pointer_ev.stop ();
-
   if (!(Options & Opt_pointerBlank))
     return;

diff --git a/src/iom.C b/src/iom.C

index fd2b248ccf90e25aa882cd8b47daa4a1283ccc29..

index ..812b7aae8473c3c111700a9d4c6156340f78f743 100644

--- a/src/iom.C
+++ b/src/iom.C
@@ -20,48 +20,47 @@
 #include "../config.h"

 #include <cstdio>
+#include <cstdlib>
+#include <cerrno>

 #include <sys/select.h>
 #include <sys/time.h>

 #include "iom.h"

+// TSTAMP_MAX must still fit into a positive struct timeval
+#define TSTAMP_MAX (double)(1UL<<31)
+
 tstamp NOW;
-bool iom_valid;
+static bool iom_valid;
 io_manager iom;

 template<class watcher>
 void io_manager::reg (watcher *w, simplevec<watcher *> &queue)
 {
-  if (find (queue.begin (), queue.end (), w) == queue.end ())
-    queue.push_back (w);
+  if (!iom_valid)
+    abort ();
+
+  if (!w->active)
+    {
+      queue.push_back (w);
+      w->active = queue.size ();
+    }
 }

 template<class watcher>
 void io_manager::unreg (watcher *w, simplevec<watcher *> &queue)
 {
-  queue.erase (find (queue.begin (), queue.end (), w));
-}
-
-#if IOM_IO
-io_watcher::~io_watcher ()
-{
-  if (iom_valid)
-    iom.unreg (this);
-}
-
-void io_manager::reg (io_watcher *w)
-{
-  reg (w, iow);
-}
+  if (!iom_valid)
+    return;

-void io_manager::unreg (io_watcher *w)
-{
-  unreg (w, iow);
+  if (w->active)
+    {
+      queue [w->active - 1] = 0;
+      w->active = 0;
+    }
 }

-#endif
-
 #if IOM_TIME
 void time_watcher::trigger ()
 {
@@ -70,59 +69,23 @@ void time_watcher::trigger ()
   iom.reg (this);
 }

-time_watcher::~time_watcher ()
-{
-  if (iom_valid)
-    iom.unreg (this);
-
-  at = TSTAMP_CANCEL;
-}
-
-void io_manager::reg (time_watcher *w)
-{
-  reg (w, tw);
-}
+void io_manager::reg (time_watcher *w) { reg (w, tw); }
+void io_manager::unreg (time_watcher *w) { unreg (w, tw); }
+#endif

-void io_manager::unreg (time_watcher *w)
-{
-  unreg (w, tw);
-}
+#if IOM_IO
+void io_manager::reg (io_watcher *w) { reg (w, iow); }
+void io_manager::unreg (io_watcher *w) { unreg (w, iow); }
 #endif

 #if IOM_CHECK
-check_watcher::~check_watcher ()
-{
-  if (iom_valid)
-    iom.unreg (this);
-}
-
-void io_manager::reg (check_watcher *w)
-{
-  reg (w, cw);
-}
-
-void io_manager::unreg (check_watcher *w)
-{
-  unreg (w, cw);
-}
+void io_manager::reg (check_watcher *w) { reg (w, cw); }
+void io_manager::unreg (check_watcher *w) { unreg (w, cw); }
 #endif

 #if IOM_IDLE
-idle_watcher::~idle_watcher ()
-{
-  if (iom_valid)
-    iom.unreg (this);
-}
-
-void io_manager::reg (idle_watcher *w)
-{
-  reg (w, iw);
-}
-
-void io_manager::unreg (idle_watcher *w)
-{
-  unreg (w, iw);
-}
+void io_manager::reg (idle_watcher *w) { reg (w, iw); }
+void io_manager::unreg (idle_watcher *w) { unreg (w, iw); }
 #endif

 #if IOM_TIME
@@ -158,78 +121,97 @@ void io_manager::loop ()
 #endif
         {
 #if IOM_TIME
-          time_watcher *w;
+          time_watcher *next;

-          for (;tw.size ();)
+          for (;;)
             {
-              w = tw[0];
+              next = tw[0]; // the first time-watcher must exist at ALL times

-              for (time_watcher **i = tw.begin (); i < tw.end (); ++i)
-                if ((*i)->at < w->at)
-                  w = *i;
+              for (int i = tw.size (); i--; )
+                if (!tw[i])
+                  tw.erase_unordered (i);
+                else if (tw[i]->at < next->at)
+                  next = tw[i];

-              if (w->at > NOW)
+              if (next->at > NOW)
                 {
-                  double diff = w->at - NOW;
-                  tval.tv_sec  = (int)diff;
-                  tval.tv_usec = (int)((diff - tval.tv_sec) * 1000000);
-                  to = &tval;
+                  if (next != tw[0])
+                    {
+                      double diff = next->at - NOW;
+                      tval.tv_sec  = (int)diff;
+                      tval.tv_usec = (int)((diff - tval.tv_sec) * 1000000);
+                      to = &tval;
+                    }
                   break;
                 }
-              else if (w->at >= 0)
-                w->call (*w);
-              else
-                unreg (w);
+              else if (next->at >= 0)
+                {
+                  unreg (next);
+                  next->call (*next);
+                }
             }
 #endif
         }

 #if IOM_CHECK
-      for (int i = 0; i < cw.size (); ++i)
-        cw[i]->call (*cw[i]);
+      for (int i = cw.size (); i--; )
+        if (!cw[i])
+          cw.erase_unordered (i);
+        else
+          cw[i]->call (*cw[i]);
 #endif

 #if IOM_IO
-      fd_set rfd, wfd;
+      fd_set rfd, wfd, efd;

       FD_ZERO (&rfd);
       FD_ZERO (&wfd);

       int fds = 0;

-      for (io_watcher **w = iow.begin (); w < iow.end (); ++w)
-        {
-          if ((*w)->events & EVENT_READ ) FD_SET ((*w)->fd, &rfd);
-          if ((*w)->events & EVENT_WRITE) FD_SET ((*w)->fd, &wfd);
+      for (io_watcher **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 ((*w)->fd >= fds) fds = (*w)->fd + 1;
-        }
+            if ((*i)->fd >= fds) fds = (*i)->fd + 1;
+          }

-      if (!to && !fds)
+      if (!to && !fds) //TODO: also check idle_watchers and check_watchers
         break; // no events

-      fds = select (fds, &rfd, &wfd, 0, to);
+      fds = select (fds, &rfd, &wfd, &efd, to);
 # if IOM_TIME
       set_now ();
 # endif

       if (fds > 0)
-        for (int i = 0; i < iow.size (); ++i)
-          {
-            io_watcher *w = iow[i];
-
-            short revents = w->events;
+        for (int i = iow.size (); i--; )
+          if (!iow[i])
+            iow.erase_unordered (i);
+          else
+            {
+              short revents = iow[i]->events;

-            if (!FD_ISSET (w->fd, &rfd)) revents &= ~EVENT_READ;
-            if (!FD_ISSET (w->fd, &wfd)) revents &= ~EVENT_WRITE;
+              if (!FD_ISSET (iow[i]->fd, &rfd)) revents &= ~EVENT_READ;
+              if (!FD_ISSET (iow[i]->fd, &wfd)) revents &= ~EVENT_WRITE;

-            if (revents)
-              w->call (*w, revents);
-          }
+              if (revents)
+                iow[i]->call (*iow[i], revents);
+            }
+      else if (fds < 0 && errno != EINTR)
+        {
+          perror ("Error while waiting for I/O or time event");
+          abort ();
+        }
 #if IOM_IDLE
-      else if (iw.size ())
-        for (int i = 0; i < iw.size (); ++i)
-          iw[i]->call (*iw[i]);
+      else
+        for (int i = iw.size (); i--; )
+          if (!iw[i])
+            iw.erase_unordered (i);
+          else
+            iw[i]->call (*iw[i]);
 #endif

 #elif IOM_TIME
@@ -244,13 +226,31 @@ void io_manager::loop ()
     }
 }

+// this is a dummy time watcher to ensure that the first
+// time watcher is _always_ valid, this gets rid of a lot
+// of null-pointer-checks
+static struct tw0 : time_watcher {
+  void cb (time_watcher &w)
+  {
+    // should never get called
+    // reached end-of-time, or tstamp has a bogus definition :)
+    abort ();
+  }
+
+  tw0()
+  : time_watcher (this, &tw0::cb)
+  { }
+} tw0;
+
 io_manager::io_manager ()
 {
+  iom_valid = true;
+
 #if IOM_TIME
   set_now ();
-#endif

-  iom_valid = true;
+  tw0.start (TSTAMP_MAX);
+#endif
 }

 io_manager::~io_manager ()
diff --git a/src/iom.h b/src/iom.h

index 6912a6a3b29857d0c3644a5b25855cab826e0ab5..

index ..470791bcfaed4a1c5b0eb468aae6811225620983 100644

--- a/src/iom.h
+++ b/src/iom.h
@@ -22,18 +22,26 @@

 #include <cassert>

-#include "rxvtvec.h"
 #include "callback.h"
+#include "rxvtvec.h"
+
+#ifndef IOM_IO
+# define IOM_IO 1
+#endif
+#ifndef IOM_TIME
+# define IOM_TIME 1
+#endif
+#ifndef IOM_CHECK
+# define IOM_CHECK 1
+#endif
+#ifndef IOM_IDLE
+# define IOM_IDLE 0
+#endif

-#define IOM_IO 1
-#define IOM_TIME 1
-#define IOM_CHECK 1
-#define IOM_IDLE 0
+typedef double tstamp;
+extern tstamp NOW;

 #if IOM_IO
-  typedef double tstamp;
-  extern tstamp NOW;
-
   struct io_watcher;
 #endif
 #if IOM_TIME
@@ -46,18 +54,33 @@
   struct idle_watcher;
 #endif

+template<class watcher>
+struct io_manager_vec : protected simplevec<watcher *> {
+  friend class io_manager;
+protected:
+  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<io_watcher *>    iow;
+  io_manager_vec<io_watcher>    iow;
 #endif
 #if IOM_CHECK
-  simplevec<check_watcher *> cw;
+  io_manager_vec<check_watcher> cw;
 #endif
 #if IOM_TIME
-  simplevec<time_watcher *>  tw;
+  io_manager_vec<time_watcher>  tw;
 #endif
 #if IOM_IDLE
-  simplevec<idle_watcher *>  iw;
+  io_manager_vec<idle_watcher>  iw;
 #endif

   template<class watcher>
@@ -89,42 +112,38 @@ public:

 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<void, io_watcher &, short> {
+struct io_watcher : watcher, callback2<void, io_watcher &, short> {
   int fd;
   short events;

-  template<class O1, class O2>
-  io_watcher (O1 *object, void (O2::*method)(io_watcher &, short))
-    : callback2<void, io_watcher &, short>(object,method)
-    { }
-
-  ~io_watcher ();
-
   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); }
+
+  template<class O1, class O2>
+  io_watcher (O1 *object, void (O2::*method)(io_watcher &, short))
+  : callback2<void, io_watcher &, short>(object,method)
+  { }
+  ~io_watcher () { stop (); }
 };
 #endif

 #if IOM_TIME
-enum { TSTAMP_CANCEL = -1 };
-
-struct time_watcher : callback1<void, time_watcher &> {
+struct time_watcher : watcher, callback1<void, time_watcher &> {
   tstamp at;

-  template<class O1, class O2>
-  time_watcher (O1 *object, void (O2::*method)(time_watcher &))
-    : callback1<void, time_watcher &>(object,method)
-    { }
-
-  ~time_watcher ();
-
   void trigger ();

   void set (tstamp when) { at = when; }
@@ -133,41 +152,39 @@ struct time_watcher : callback1<void, time_watcher &> {
   void start (tstamp when) { set (when); iom.reg (this); }
   void stop () { iom.unreg (this); }

-  void reset (tstamp when = TSTAMP_CANCEL)
-    {
-      stop ();
-      at = when;
-    }
+  template<class O1, class O2>
+  time_watcher (O1 *object, void (O2::*method)(time_watcher &))
+  : callback1<void, time_watcher &>(object,method)
+  { }
+  ~time_watcher () { stop (); }
 };
 #endif

 #if IOM_CHECK
 // run before checking for new events
-struct check_watcher : callback1<void, check_watcher &> {
-  template<class O1, class O2>
-  check_watcher (O1 *object, void (O2::*method)(check_watcher &))
-    : callback1<void, check_watcher &>(object,method)
-    { }
-
-  ~check_watcher ();
-
+struct check_watcher : watcher, callback1<void, check_watcher &> {
   void start () { iom.reg (this); }
   void stop () { iom.unreg (this); }
+
+  template<class O1, class O2>
+  check_watcher (O1 *object, void (O2::*method)(check_watcher &))
+  : callback1<void, check_watcher &>(object,method)
+  { }
+  ~check_watcher () { stop (); }
 };
 #endif

 #if IOM_IDLE
 // run after checking for any i/o, but before waiting
-struct idle_watcher : callback1<void, idle_watcher &> {
+struct idle_watcher : watcher, callback1<void, idle_watcher &> {
+  void start () { iom.reg (this); }
+  void stop () { iom.unreg (this); }
+
   template<class O1, class O2>
   idle_watcher (O1 *object, void (O2::*method)(idle_watcher &))
     : callback1<void, idle_watcher &>(object,method)
     { }
-
-  ~idle_watcher ();
-
-  void start () { iom.reg (this); }
-  void stop () { iom.unreg (this); }
+  ~idle_watcher () { stop (); }
 };
 #endif

diff --git a/src/rxvtd.C b/src/rxvtd.C

index 52a1aa7ec617d96b2341d86add4a09de7836cd8f..

index ..dd7af9464639da987feebdec99afa93e8344cccd 100644

--- a/src/rxvtd.C
+++ b/src/rxvtd.C
@@ -171,3 +171,4 @@ main(int argc, const char *const *argv)
 #endif
   return EXIT_SUCCESS;
 }
+
diff --git a/src/screen.C b/src/screen.C

index 3eefa9b2eb55224602bfe057ab6f09e8c71031d6..

index ..cf49d2894897ee225588e0389729460cdaf253e0 100644

--- a/src/screen.C
+++ b/src/screen.C
@@ -1,7 +1,7 @@
 /*--------------------------------*-C-*--------------------------------------*
  * File:        screen.c
  *---------------------------------------------------------------------------*
- * $Id: screen.C,v 1.15 2004/01/16 16:34:56 pcg Exp $
+ * $Id: screen.C,v 1.16 2004/01/16 22:11:09 pcg Exp $
  *
  * Copyright (c) 1997-2001 Geoff Wing <gcw@pobox.com>
  *
@@ -2567,10 +2567,9 @@ rxvt_selection_paste(pR_ Window win, Atom prop, Bool delete_prop)
 void
 rxvt_term::incr_cb (time_watcher &w)
 {
-  w.stop ();
   selection_wait = Sel_none;

-  rxvt_print_error("data loss: timeout on INCR selection paste");
+  rxvt_print_error ("data loss: timeout on INCR selection paste");
 }

 /*

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 12:00:20 2024