--- rxvt-unicode/src/iom.C 2004/01/19 17:26:43 1.11 +++ rxvt-unicode/src/iom.C 2004/08/10 20:39:19 1.17 @@ -23,7 +23,9 @@ #include -#if 1 // older unices need these includes for select(2) +#include + +#if 1 // older unices need these includes for select (2) # include # include #endif @@ -32,6 +34,9 @@ // until that happens, sys/select.h must come last #include +// for IOM_SIG +#include + #include "iom.h" // TSTAMP_MAX must still fit into a positive struct timeval @@ -41,19 +46,20 @@ // time watcher is _always_ valid, this gets rid of a lot // of null-pointer-checks // (must come _before_ iom is being defined) -static struct tw0 : time_watcher { - void cb (time_watcher &w) +static struct tw0 : time_watcher { - // should never get called - // reached end-of-time, or tstamp has a bogus definition, - // or compiler initilization order broken, or somethine else :) - abort (); - } + void cb (time_watcher &w) + { + // should never get called + // reached end-of-time, or tstamp has a bogus definition, + // or compiler initialisation order broken, or something else :) + abort (); + } - tw0() - : time_watcher (this, &tw0::cb) - { } -} tw0; + tw0 () + : time_watcher (this, &tw0::cb) + { } + } tw0; tstamp NOW; static bool iom_valid; @@ -67,6 +73,9 @@ if (!w->active) { +#if IOM_CHECK + queue.activity = true; +#endif queue.push_back (w); w->active = queue.size (); } @@ -98,7 +107,7 @@ #endif #if IOM_IO -void io_manager::reg (io_watcher *w) { reg (w, iow); } +void io_manager::reg (io_watcher *w) { reg (w, iow); } void io_manager::unreg (io_watcher *w) { unreg (w, iow); } #endif @@ -120,9 +129,67 @@ 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 @@ -143,6 +210,7 @@ } else #endif + { #if IOM_TIME time_watcher *next; @@ -163,7 +231,7 @@ { double diff = next->at - NOW; tval.tv_sec = (int)diff; - tval.tv_usec = (int)((diff - tval.tv_sec) * 1000000); + tval.tv_usec = (int) ((diff - tval.tv_sec) * 1000000); to = &tval; } break; @@ -175,18 +243,28 @@ } } #endif + } #if IOM_CHECK + tw.activity = false; + for (int i = cw.size (); i--; ) if (!cw[i]) cw.erase_unordered (i); else cw[i]->call (*cw[i]); + + if (tw.activity) + { + tval.tv_sec = 0; + tval.tv_usec = 0; + to = &tval; + } #endif #if IOM_IO - fd_set rfd, wfd, efd; + fd_set rfd, wfd; FD_ZERO (&rfd); FD_ZERO (&wfd); @@ -205,7 +283,7 @@ if (!to && !fds) //TODO: also check idle_watchers and check_watchers break; // no events - fds = select (fds, &rfd, &wfd, &efd, to); + fds = select (fds, &rfd, &wfd, NULL, to); # if IOM_TIME set_now (); # endif @@ -247,6 +325,7 @@ #else break; #endif + } }