-- 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:
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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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