Niels Provos wrote:
> I am fine with removing rtsig.  I personally never liked that way to
> do event notification.  If someone feels strongly, they can revive it
> from svn and fix it.

Here's a patch to remove it, including the associated autoconf gunk.

Scott
>From a5d264a55153e029e58eebb60840f0ed17a81071 Mon Sep 17 00:00:00 2001
From: Scott Lamb <[EMAIL PROTECTED]>
Date: Tue, 31 Jul 2007 14:41:38 -0700
Subject: [PATCH] remove rtsig, which is obsolete and broken

---
 libevent/Makefile.am         |    2 +-
 libevent/WIN32-Code/config.h |    6 -
 libevent/configure.in        |   53 ---
 libevent/event.c             |    6 -
 libevent/rtsig.c             |  997 ------------------------------------------
 libevent/test/test.sh        |    7 -
 6 files changed, 1 insertions(+), 1070 deletions(-)
 delete mode 100644 libevent/rtsig.c

diff --git a/libevent/Makefile.am b/libevent/Makefile.am
index f88f8a1..e8aacac 100644
--- a/libevent/Makefile.am
+++ b/libevent/Makefile.am
@@ -6,7 +6,7 @@ bin_SCRIPTS = event_rpcgen.py
 EXTRA_DIST = acconfig.h event.h event-internal.h log.h evsignal.h evdns.3 \
        evrpc.h evrpc-internal.h \
        event.3 \
-       kqueue.c epoll_sub.c epoll.c select.c rtsig.c poll.c signal.c \
+       kqueue.c epoll_sub.c epoll.c select.c poll.c signal.c \
        evport.c devpoll.c event_rpcgen.py \
        sample/Makefile.am sample/Makefile.in sample/event-test.c \
        sample/signal-test.c sample/time-test.c \
diff --git a/libevent/WIN32-Code/config.h b/libevent/WIN32-Code/config.h
index aed9774..21ccc5b 100644
--- a/libevent/WIN32-Code/config.h
+++ b/libevent/WIN32-Code/config.h
@@ -115,9 +115,6 @@
 /* Define if you have the <poll.h> header file. */
 #undef HAVE_POLL_H
 
-/* Define if your system supports POSIX realtime signals */
-#undef HAVE_RTSIG
-
 /* Define if you have the `select' function. */
 #undef HAVE_SELECT
 
@@ -184,9 +181,6 @@
 /* Define if kqueue works correctly with pipes */
 #undef HAVE_WORKING_KQUEUE
 
-/* Define if realtime signals work on pipes */
-#undef HAVE_WORKING_RTSIG
-
 /* Name of package */
 #define PACKAGE "libevent"
 
diff --git a/libevent/configure.in b/libevent/configure.in
index 399d61e..623fac1 100644
--- a/libevent/configure.in
+++ b/libevent/configure.in
@@ -29,11 +29,6 @@ dnl   the command line with --enable-shared and 
--disable-shared.
 dnl AC_DISABLE_SHARED
 AC_SUBST(LIBTOOL_DEPS)
 
-dnl Check for optional stuff
-AC_ARG_WITH(rtsig,
-  [  --with-rtsig              compile with support for real time signals 
(experimental)],
-  [usertsig=yes], [usertsig=no])
-
 dnl Checks for libraries.
 AC_CHECK_LIB(socket, socket)
 AC_CHECK_LIB(resolv, inet_aton)
@@ -163,58 +158,10 @@ if test "x$haveselect" = "xyes" ; then
 fi
 
 havepoll=no
-havertsig=no
 AC_CHECK_FUNCS(poll, [havepoll=yes], )
 if test "x$havepoll" = "xyes" ; then
        AC_LIBOBJ(poll)
        needsignal=yes
-
-       if test "x$usertsig" = "xyes" ; then
-               AC_CHECK_FUNCS(sigtimedwait, [havertsig=yes], )
-       fi
-fi
-if test "x$havertsig" = "xyes" ; then
-       AC_MSG_CHECKING(for F_SETSIG in fcntl.h)
-       AC_EGREP_CPP(yes,
-[
-#define _GNU_SOURCE
-#include <fcntl.h>
-#ifdef F_SETSIG
-yes
-#endif
-],     [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no); havertsig=no])
-fi
-if test "x$havertsig" = "xyes" ; then
-       AC_DEFINE(HAVE_RTSIG, 1, [Define if your system supports POSIX realtime 
signals])
-       AC_LIBOBJ(rtsig)
-       AC_MSG_CHECKING(for working rtsig on pipes)
-       AC_TRY_RUN(
-[
-#define _GNU_SOURCE
-#include <fcntl.h>
-#include <signal.h>
-#include <unistd.h>
-
-int sigio()
-{
-       exit(0);
-}
-
-int main()
-{
-       int fd[2];
-
-       pipe(fd);
-       signal(SIGIO, sigio);
-       fcntl(fd[0], F_SETOWN, getpid());
-       fcntl(fd[0], F_SETSIG, SIGIO);
-       fcntl(fd[0], F_SETFL, fcntl(fd[0], F_GETFL) | O_ASYNC);
-       write(fd[1], "", 1);
-       return 1;
-}
-],     [ AC_MSG_RESULT(yes)
-         AC_DEFINE(HAVE_WORKING_RTSIG, 1, [Define if realtime signals work on 
pipes])],
-       AC_MSG_RESULT(no))
 fi
 
 haveepoll=no
diff --git a/libevent/event.c b/libevent/event.c
index 2af11a7..ab13664 100644
--- a/libevent/event.c
+++ b/libevent/event.c
@@ -66,9 +66,6 @@ extern const struct eventop selectops;
 #ifdef HAVE_POLL
 extern const struct eventop pollops;
 #endif
-#ifdef HAVE_RTSIG
-extern const struct eventop rtsigops;
-#endif
 #ifdef HAVE_EPOLL
 extern const struct eventop epollops;
 #endif
@@ -96,9 +93,6 @@ const struct eventop *eventops[] = {
 #ifdef HAVE_DEVPOLL
        &devpollops,
 #endif
-#ifdef HAVE_RTSIG
-       &rtsigops,
-#endif
 #ifdef HAVE_POLL
        &pollops,
 #endif
diff --git a/libevent/rtsig.c b/libevent/rtsig.c
deleted file mode 100644
index e0e55af..0000000
--- a/libevent/rtsig.c
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
- * Copyright (c) 2006 Mathew Mills <[EMAIL PROTECTED]>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Meta-level comments: You know that a kernel interface is wrong if
- * supporting it requires three times more code than any of the other
- * kernel interfaces supported in libevent.  Niels - 2006-02-22
- */
-/**
-
-   "RTSIG" is a shorthand for using O_ASYNC to make descriptors send
-   signals when readable/writable and to use POSIX real-time signals
-   witch are queued unlike normal signals.  At first blush this may
-   seem like a alternative to epoll, but a number of problems arise
-   when attempting to build an eventloop entirely out of rtsig.
-   Still, we can use rtsig in combination with poll() to
-   provide an eventloop that allows for many thousands of sockets
-   without huge overheads implicit with using select() or poll()
-   alone.  epoll and kqueue are far superior to rtsig and should be
-   used where available, but rtsig has been in standard Linux kernels
-   for a long time and have a huge installation base.  epoll requires
-   special patches for 2.4 kernels and 2.6 kernels are not yet nearly
-   so ubiquitous.
-
-   rtsig problems:
-    - O_ASYNC mechanisms work only on sockets - not pipes or tty's
-
-    - O_ASYNC signals are edge-triggered, POLLIN on packet arriving
-   or socket close; POLLOUT when a socket transitions from
-   non-writable to writable.  Being edge-triggered means the
-   event-handler callbacks must transition the level ( reading
-   completely the socket buffer contents ) or it will be unable to
-   reliably receive notification again.
-
-   - rtsig implementations must be intimately involved in how a
-   process dispatches signals.
-
-   - delivering signals per-event can be expensive, CPU-wise, but
-     sigtimedwait() blocks on signals only and means non-sockets
-     cannot be serviced.
-
-   Theory of operation:
-    This libevent module uses rtsig to allow us to manage a set of
-    poll-event descriptors.  We can drop uninteresting fd's from the
-    pollset if the fd will send a signal when it becomes interesting
-    again.
-
-    poll() offers us level-triggering and, when we have verified the
-    level of a socket, we can trust the edge-trigger nature of the
-    ASYNC signal.
-
-    As an eventloop we must poll for external events but leverage
-    kernel functionality to sleep between events ( until the loop's
-    next scheduled timed event ).
-
-    If we are polling on any non-sockets then we simply have no choice
-    about blocking on the poll() call.  If we blocked on the
-    sigtimedwait() call as rtsig papers recommend we will not wake on
-    non-socket state transitions.  As part of libevent, this module
-    must support non-socket polling.
-
-    Many applications, however, do not need to poll on non-sockets and
-    so this module should be able to optimize this case by using
-    sigtimedwait().  For this reason this module can actually trigger
-    events in each of three different ways:
-      - poll() returning ready events from descriptors in the pollset
-
-      - real-time signals dequeued via sigtimedwait()
-
-      - real-time signals that call an installed signal handler which in
-    turn writes the contents of siginfo to one end of a socketpair
-    DGRAM socket.  The other end of the socket is always in the
-    pollset so poll will be guaranteed to return even if the signal is
-    received before entering poll().
-
-    non-socket descriptors force us to block on the poll() for the
-    duration of a dispatch.  In this case we unblock (w/ sigprocmask)
-    the managed signals just before polling.  Each managed signal is
-    handled by signal_handler() which send()'s the contents of siginfo
-    over the socketpair.  Otherwise, we call poll() with a timeout of
-    0ms so it checks the levels of the fd's in the pollset and returns
-    immediately.  Any fd that is a socket and has no active state is
-    removed from the pollset for the next pass -- we will rely on
-    getting a signal for events on these fd's.
-
-    The receiving end of the siginfo socketpair is in the pollset
-    (permanently) so if we are polling on non-sockets, the delivery of
-    signals immediately following sigprocmask( SIG_UNBLOCK...) will
-    result in a readable op->signal_recv_fd which ensures the poll()
-    will return immediately.  If the poll() call is blocking and a
-    signal arrives ( possibly a real-time signal from a socket not in
-    the pollset ) its handler will write the data to the socketpair
-    and interrupt the poll().
-
-    After every poll call we attempt a non-blocking recv from the
-    signal_recv_fd and continue to recv and dispatch the events until
-    recv indicates the socket buffer is empty.
-
-    One might raise concerns about receiving event activations from
-    both poll() and from the rtsig data in the signal_recv_fd.
-    Fortunately, libevent is already structured for event coalescing,
-    so this issue is mitigated ( though we do some work twice for the
-    same event making us less efficient ).  I suspect that the cost of
-    turning off the O_ASYNC flag on fd's in the pollset is more
-    expensive than handling some events twice.  Looking at the
-    kernel's source code for setting O_ASYNC, it looks like it takes a
-    global kernel lock...
-
-    After a poll and recv-loop for the signal_recv_fd, we finally do a
-    sigtimedwait().  sigtimedwait will only block if we haven't
-    blocked in poll() and we have not enqueued events from either the
-    poll or the recv-loop.  Because sigtimedwait blocks all signals
-    that are not in the set of signals to be dequeued, we need to
-    dequeue almost all signals and make sure we dispatch them
-    correctly.  We dequeue any signal that is not blocked as well as
-    all libevent-managed signals.  If we get a signal that is not
-    managed by libevent we lookup the sigaction for the specific
-    signal and call that function ourselves.
-
-    Finally, I should mention that getting a SIGIO signal indicates
-    that the rtsig buffer has overflowed and we have lost events.
-    This forces us to add _every_ descriptor to the pollset to recover.
-
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* Enable F_SETSIG and F_SETOWN */
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else
-#include <sys/_time.h>
-#endif
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#include <unistd.h>
-#include <sys/socket.h>
-
-#include "event.h"
-#include "event-internal.h"
-#include "log.h"
-extern struct event_list signalqueue;
-
-#include <linux/unistd.h>
-#ifndef __NR_gettid
-#define gettid() getpid()
-#else
-
-#if ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
-_syscall0(pid_t,gettid)
-#endif
-
-#endif
-
-#define EVLIST_NONSOCK   0x1000 /* event is for a non-socket file-descriptor */
-#define EVLIST_DONTDEL   0x2000 /* event should always be in the pollset */
-#define MAXBUFFERSIZE (1024 * 1024 * 2) /* max socketbuffer for signal-spair */
-#define INIT_MAX 16     /* init/min # of fd positions in our pollset */
-
-static int signal_send_fd[_NSIG]; /* the globalend of the signal socketpair */
-static int trouble[_NSIG]; /* 1 when signal-handler cant send to 
signal_send_fd */
-
-struct rtdata;
-TAILQ_HEAD(rtdata_list, rtdata);
-
-struct rtsigop {
-       sigset_t sigs;        /* signal mask for all _managed_ signals */
-       struct pollfd *poll;  /* poll structures */
-       struct rtdata **ptodat;  /* map poll_position to rtdata */
-       int cur;              /* cur # fd's in a poll set */
-       int max;              /* max # fd's in a poll set, start at 16 and grow 
as needed */
-       int total;            /* count of fd's we are watching now */
-       int signo;            /* the signo we use for ASYNC fd notifications */
-       int nonsock;          /* number of non-socket fd's we are watching */
-       int highestfd;        /* highest fd accomodated by fdtodat */
-       struct rtdata_list **fdtodat; /* map fd to rtdata ( and thus to event ) 
*/
-       int signal_recv_fd;   /* recv side of the signal_send_fd */
-       int signal_send_fd;   /* recv side of the signal_send_fd */
-       struct event sigfdev; /* our own event structure for the signal fd */
-};
-
-struct rtdata {
-       /* rtdata holds rtsig-private state on each event */
-       TAILQ_ENTRY (rtdata) next;
-       struct event *ev;
-       int poll_position;
-};
-
-void *rtsig_init(struct event_base *);
-int rtsig_add(void *, struct event *);
-int rtsig_del(void *, struct event *);
-int rtsig_recalc(struct event_base *, void *, int);
-int rtsig_dispatch(struct event_base *, void *, struct timeval *);
-
-struct eventop rtsigops = {
-       "rtsig",
-       rtsig_init,
-       rtsig_add,
-       rtsig_del,
-       rtsig_recalc,
-       rtsig_dispatch
-};
-
-static void
-signal_handler(int sig, siginfo_t *info, void *ctx)
-{
-       /*
-        * the signal handler for all libevent-managed signals only
-        * used if we need to do a blocking poll() call due to
-        * non-socket fd's in the pollset.
-        */
-  
-       siginfo_t *i = info;
-       siginfo_t i_local;
-
-       if (trouble[sig - 1]) {
-               i_local.si_signo = SIGIO;
-               i_local.si_errno = 0;
-               i_local.si_code = 0;
-               i = &i_local;
-               trouble[sig - 1] = 0;
-       }
-
-       if (send(signal_send_fd[sig - 1], i, sizeof(*i),
-               MSG_DONTWAIT|MSG_NOSIGNAL) == -1)
-               trouble[sig - 1] = 1;
-}
-
-static void
-donothing(int fd, short event, void *arg)
-{
-       /*
-        * callback for our signal_recv_fd event structure
-        * we don't want to act on these events, we just want to wake the poll()
-        */
-};
-
-static void
-signotset(sigset_t *set)
-{
-       int i, l;
-       l = sizeof(*set) / 4;
-       for (i = 0; i < l; i++) {
-               ((unsigned *)set)[i] = ~((unsigned *)set)[i];
-       }
-}
-
-/*  The next three functions manage our private data about each event struct */
-
-static int
-grow_fdset(struct rtsigop *op, int newhigh)
-{
-       /*
-        * grow the fd -> rtdata array because we have encountered a
-        * new fd too high to fit in the existing array
-        */
-
-       struct rtdata_list **p;
-       struct rtdata_list *datset;
-       int i,x;
-       int newcnt = (newhigh + 1) << 1;
-
-       if (newhigh <= op->highestfd)
-               return (0);
-
-       p = op->fdtodat;
-       p = realloc(op->fdtodat, sizeof(struct rtdata_list *) * newcnt);
-       if (p == NULL)
-               return (-1);
-       op->fdtodat = p;
-
-       datset = calloc(newcnt - (op->highestfd + 1),
-           sizeof(struct rtdata_list));
-       if (datset == NULL)
-               return (-1);
-
-       for (i = op->highestfd + 1, x = 0; i < newcnt; i++, x++) {
-               op->fdtodat[i] = &(datset[x]);
-               TAILQ_INIT(op->fdtodat[i]);
-       }
-
-       op->highestfd = newcnt - 1;
-       return (0);
-}
-
-static struct rtdata *
-ev2dat(struct rtsigop *op, struct event *ev, int create)
-{
-       /*
-        * given an event struct, find the dat structure that
-        * corresponds to it if create is non-zero and the rtdata
-        * structure does not exist, create it return NULL if not
-        * found
-        */
-
-       int found = 0;
-       int fd = ev->ev_fd;
-       struct rtdata *ret = NULL;
-
-       if (op->highestfd < fd && create)
-               if (grow_fdset(op, fd) == -1)
-                       return (NULL);
-  
-       TAILQ_FOREACH(ret, op->fdtodat[fd], next) {
-               if (ret->ev == ev) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (!found) {
-               if (!create)
-                       return (NULL);
-
-               ret = calloc(1, sizeof(struct rtdata));
-               if (ret == NULL)
-                       return (NULL);
-               ret->ev = ev;
-               ret->poll_position = -1;
-               TAILQ_INSERT_TAIL(op->fdtodat[fd], ret, next);
-       }
-
-       return (ret);
-}
-
-static void
-dat_del(struct rtsigop *op, struct rtdata *dat)
-{
-       /*
-        * delete our private notes about a given event struct
-        * called from rtsig_del() only
-        */
-       int fd;
-       if (dat == NULL)
-               return;
-       fd = dat->ev->ev_fd;
-
-       TAILQ_REMOVE(op->fdtodat[fd], dat, next);
-       memset(dat, 0, sizeof(*dat));
-       free(dat);
-}
-
-
-static void
-set_sigaction(int sig)
-{
-       /*
-        * set the standard handler for any libevent-managed signal,
-        * including the rtsig used for O_ASYNC notifications
-        */
-       struct sigaction act;
-
-       act.sa_flags = SA_RESTART | SA_SIGINFO;
-       sigfillset(&(act.sa_mask));
-       act.sa_sigaction = &signal_handler;
-       sigaction(sig, &act, NULL);
-}
-
-static int
-find_rt_signal()
-{
-       /* find an unused rtsignal */
-       struct sigaction act;
-       int sig = SIGRTMIN;
-
-       while (sig <= SIGRTMAX) {
-               if (sigaction(sig, NULL, &act) != 0) {
-                       if (errno == EINTR)
-                               continue;
-               } else {
-                       if (act.sa_flags & SA_SIGINFO) {
-                               if (act.sa_sigaction == NULL)
-                                       return (sig);
-                       } else {
-                               if (act.sa_handler == SIG_DFL)
-                                       return (sig);
-                       }
-               }
-               sig++;
-       }
-       return (0);
-}
-
-/*
- * the next three functions manage our pollset and the memory management for 
- * fd -> rtdata -> event -> poll_position maps
- */
-
-static int
-poll_add(struct rtsigop *op, struct event *ev, struct rtdata *dat)
-{
-       struct pollfd *pfd;
-       int newmax = op->max << 1;
-       int pp;
-
-       if (op->poll == NULL)
-               return (0);
-
-       if (dat == NULL)
-               dat = ev2dat(op, ev, 0);
-
-       if (dat == NULL)
-               return (0);
-
-       pp = dat->poll_position;
-
-       if (pp != -1) {
-               pfd = &op->poll[pp];
-               if (ev->ev_events & EV_READ)
-                       pfd->events |= POLLIN;
-    
-               if (ev->ev_events & EV_WRITE)
-                       pfd->events |= POLLOUT;
-    
-               return (0);
-       }
-
-       if (op->cur == op->max) {
-               void *p = realloc(op->poll, sizeof(*op->poll) * newmax);
-               if (p == NULL) {
-                       errno = ENOMEM;
-                       return (-1);
-               }
-               op->poll = p;
-
-               p = realloc(op->ptodat, sizeof(*op->ptodat) * newmax);
-               if (p == NULL) {
-                       /* shrink the pollset back down */
-                       op->poll = realloc(op->poll,
-                           sizeof(*op->poll) * op->max);
-                       errno = ENOMEM;
-                       return (-1);
-               }
-               op->ptodat = p;
-               op->max = newmax;
-       }
-
-       pfd = &op->poll[op->cur];
-       pfd->fd = ev->ev_fd;
-       pfd->revents = 0;
-       pfd->events = 0;
-
-       if (ev->ev_events & EV_READ)
-               pfd->events |= POLLIN;
-  
-       if (ev->ev_events & EV_WRITE)
-               pfd->events |= POLLOUT;
-  
-       op->ptodat[op->cur] = dat;
-       dat->poll_position = op->cur;
-       op->cur++;
-
-       return (0);
-}
-
-static void
-poll_free(struct rtsigop *op, int n)
-{
-  if (op->poll == NULL)
-         return;
-
-  op->cur--;
-
-  if (n < op->cur) {
-    memcpy(&op->poll[n], &op->poll[op->cur], sizeof(*op->poll));
-    op->ptodat[n] = op->ptodat[op->cur];
-    op->ptodat[n]->poll_position = n;
-  }
-
-
-  /* less then half the max in use causes us to shrink */
-  if (op->max > INIT_MAX && op->cur < op->max >> 1) {
-    op->max >>= 1;
-    op->poll = realloc(op->poll, sizeof(*op->poll) * op->max);
-    op->ptodat = realloc(op->ptodat, sizeof(*op->ptodat) * op->max);
-  }
-}
-
-static void
-poll_remove(struct rtsigop *op, struct event *ev, struct rtdata *dat)
-{
-  int pp;
-  if (dat == NULL)
-    dat = ev2dat(op, ev, 0);
-
-  if (dat == NULL) return;
-
-  pp = dat->poll_position;
-  if (pp != -1) {
-    poll_free(op, pp);
-    dat->poll_position = -1;
-  }
-}
-
-static void
-activate(struct event *ev, int flags)
-{
-       /* activate an event, possibly removing one-shot events */
-       if (!(ev->ev_events & EV_PERSIST))
-               event_del(ev);
-       event_active(ev, flags, 1);
-}
-
-#define FD_CLOSEONEXEC(x) do { \
-        if (fcntl(x, F_SETFD, 1) == -1) \
-                event_warn("fcntl(%d, F_SETFD)", x); \
-} while (0)
-
-void *
-rtsig_init(struct event_base *)
-{
-       struct rtsigop *op;
-       int sockets[2];
-       int optarg;
-       struct rtdata *dat;
-       int flags;
-
-       if (getenv("EVENT_NORTSIG"))
-               goto err;
-
-       op = calloc(1, sizeof(*op));
-       if (op == NULL)
-               goto err;
-
-       op->max = INIT_MAX;
-       op->poll = malloc(sizeof(*op->poll) * op->max);
-       if (op->poll == NULL) 
-               goto err_free_op;
-
-       op->signo = find_rt_signal();
-       if (op->signo == 0)
-               goto err_free_poll;
-  
-       op->nonsock = 0;
-
-       if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sockets) != 0)
-               goto err_free_poll;
-
-       FD_CLOSEONEXEC(sockets[0]);
-       FD_CLOSEONEXEC(sockets[1]);
-
-       signal_send_fd[op->signo - 1] = sockets[0];
-       trouble[op->signo - 1] = 0;
-       op->signal_send_fd = sockets[0];
-       op->signal_recv_fd = sockets[1];
-       flags = fcntl(op->signal_recv_fd, F_GETFL);
-       fcntl(op->signal_recv_fd, F_SETFL, flags | O_NONBLOCK);
-
-       optarg = MAXBUFFERSIZE;
-       setsockopt(signal_send_fd[op->signo - 1],
-           SOL_SOCKET, SO_SNDBUF, 
-           &optarg, sizeof(optarg));
-  
-       optarg = MAXBUFFERSIZE;
-       setsockopt(op->signal_recv_fd,
-           SOL_SOCKET, SO_RCVBUF,
-           &optarg, sizeof(optarg));
-
-       op->highestfd = -1;
-       op->fdtodat = NULL;
-       if (grow_fdset(op, 1) == -1)
-               goto err_close_pair;
-
-       op->ptodat = malloc(sizeof(*op->ptodat) * op->max);
-       if (op->ptodat == NULL)
-               goto err_close_pair;
-
-       sigemptyset(&op->sigs);
-       sigaddset(&op->sigs, SIGIO);
-       sigaddset(&op->sigs, op->signo);
-       sigprocmask(SIG_BLOCK, &op->sigs, NULL);
-       set_sigaction(SIGIO);
-       set_sigaction(op->signo);
-
-       event_set(&(op->sigfdev), op->signal_recv_fd, EV_READ|EV_PERSIST,
-           donothing, NULL);
-       op->sigfdev.ev_flags |= EVLIST_DONTDEL;
-       dat = ev2dat(op, &(op->sigfdev), 1);
-       poll_add(op, &(op->sigfdev), dat);
-
-       return (op);
-
- err_close_pair:
-       close(op->signal_recv_fd);
-       close(signal_send_fd[op->signo - 1]);
-
- err_free_poll:
-       free(op->poll);
- 
- err_free_op:
-       free(op);
- err:
-       return (NULL);
-}
-
-int
-rtsig_add(void *arg, struct event *ev)
-{
-       struct rtsigop *op = (struct rtsigop *) arg;
-       int flags, i;
-       struct stat statbuf;
-       struct rtdata *dat;
-
-       if (ev->ev_events & EV_SIGNAL) {
-               int signo = EVENT_SIGNAL(ev);
-  
-               sigaddset(&op->sigs, EVENT_SIGNAL(ev));
-               if (sigprocmask(SIG_BLOCK, &op->sigs, NULL) == -1)
-                       return (-1);
-    
-               set_sigaction(signo);
-    
-               signal_send_fd[signo - 1] = op->signal_send_fd;
-               trouble[signo - 1] = 0;
-
-               return (0);
-       }
-
-       if (!(ev->ev_events & (EV_READ|EV_WRITE))) 
-               return (0);
-
-       if (-1 == fstat(ev->ev_fd, &statbuf))
-               return (-1);
-
-       if (!S_ISSOCK(statbuf.st_mode))
-               ev->ev_flags |= EVLIST_NONSOCK;
-
-       flags = fcntl(ev->ev_fd, F_GETFL);
-       if (flags == -1)
-               return (-1);
-
-       if (!(flags & O_ASYNC)) {
-               if (fcntl(ev->ev_fd, F_SETSIG, op->signo) == -1 ||
-                   fcntl(ev->ev_fd, F_SETOWN, (int) gettid()) == -1)
-                       return (-1);
-    
-               /*
-                * the overhead of always handling writeable edges
-                * isn't going to be that bad...
-                */
-               if (fcntl(ev->ev_fd, F_SETFL, flags | O_ASYNC|O_RDWR)) 
-                       return (-1);
-       }
-
-#ifdef O_ONESIGFD
-       /*
-        * F_SETAUXFL and O_ONESIGFD are defined in a non-standard
-        * linux kernel patch to coalesce events for fds
-        */
-       fcntl(ev->ev_fd, F_SETAUXFL, O_ONESIGFD);
-#endif
-
-       dat = ev2dat(op, ev, 1);
-       if (dat == NULL)
-               return (-1);
-
-       op->total++;
-       if (ev->ev_flags & EVLIST_NONSOCK)
-               op->nonsock++;
-
-       if (poll_add(op, ev, dat) == -1) {
-               /* must check the level of new fd's */
-               i = errno;
-               fcntl(ev->ev_fd, F_SETFL, flags);
-               errno = i;
-               return (-1);
-       }
-
-       return (0);
-}
-
-int
-rtsig_del(void *arg, struct event *ev)
-{
-       struct rtdata *dat;
-       struct rtsigop *op = (struct rtsigop *) arg;
-
-       if (ev->ev_events & EV_SIGNAL) {
-               sigset_t sigs;
-
-               sigdelset(&op->sigs, EVENT_SIGNAL(ev));
-    
-               sigemptyset(&sigs);
-               sigaddset(&sigs, EVENT_SIGNAL(ev));
-               return (sigprocmask(SIG_UNBLOCK, &sigs, NULL));
-       }
-
-       if (!(ev->ev_events & (EV_READ|EV_WRITE)))
-               return (0);
-
-       dat = ev2dat(op, ev, 0);
-       poll_remove(op, ev, dat);
-       dat_del(op, dat);
-       op->total--;
-       if (ev->ev_flags & EVLIST_NONSOCK)
-               op->nonsock--;
-
-       return (0);
-}
-
-int
-rtsig_recalc(struct event_base *base, void *arg, int max)
-{
-       return (0);
-}
-
-/*
- * the following do_X functions implement the different stages of a single
- * eventloop pass: poll(), recv(sigsock), sigtimedwait()
- *
- * do_siginfo_dispatch() is a common factor to both do_sigwait() and
- * do_signals_from_socket().
- */
-
-static inline int
-do_poll(struct rtsigop *op, struct timespec *ts, struct timespec **ts_p)
-{
-       int res = 0;
-       int i = 0;
-  
-       if (op->cur > 1) {
-               /* non-empty poll set (modulo the signalfd) */
-               if (op->nonsock) {
-                       int timeout = -1;
-                       
-                       if (*ts_p != NULL)
-                               timeout = (*ts_p)->tv_nsec / 1000000
-                                         + (*ts_p)->tv_sec * 1000;
-                       
-                       sigprocmask(SIG_UNBLOCK, &(op->sigs), NULL);
-
-                       res = poll(op->poll, op->cur, timeout);
-                       
-                       sigprocmask(SIG_BLOCK, &(op->sigs), NULL);
-                       
-                       ts->tv_sec = 0;
-                       ts->tv_nsec = 0;
-                       *ts_p = ts;
-               } else {
-                       res = poll(op->poll, op->cur, 0);
-               }
-
-               if (res < 0) {
-                       return (errno == EINTR ? 0 : -1);
-               } else if (res) {
-                       ts->tv_sec = 0;
-                       ts->tv_nsec = 0;
-                       *ts_p = ts;
-               }
-
-               i = 0;
-               while (i < op->cur) {
-                       struct rtdata *dat = op->ptodat[i];
-                       struct event *ev = dat->ev;
-
-                       if (op->poll[i].revents) {
-                               int flags = 0;
-       
-                               if (op->poll[i].revents & (POLLIN | POLLERR))
-                                       flags |= EV_READ;
-       
-                               if (op->poll[i].revents & POLLOUT)
-                                       flags |= EV_WRITE;
-       
-                               if (!(ev->ev_events & EV_PERSIST)) {
-                                       poll_remove(op, ev, op->ptodat[i]);
-                                       event_del(ev);
-                               } else {
-                                       i++;
-                               }
-       
-                               event_active(ev, flags, 1);
-                       } else {
-                               if (ev->ev_flags & 
(EVLIST_NONSOCK|EVLIST_DONTDEL)) {
-                                       i++;
-                               } else {
-                                       poll_remove(op, ev, op->ptodat[i]);
-                               }
-                       }
-               }
-       }
-       return (res);
-}
-
-static inline int
-do_siginfo_dispatch(struct event_base *base, struct rtsigop *op,
-    siginfo_t *info)
-{
-       int signum;
-       struct rtdata *dat, *next_dat;
-       struct event *ev, *next_ev;
-
-       if (info == NULL)
-               return (-1);
-
-       signum = info->si_signo;
-       if (signum == op->signo) {
-               int flags, sigok = 0;
-               flags = 0;
-
-               if (info->si_band & (POLLIN|POLLERR))
-                       flags |= EV_READ;
-               if (info->si_band & POLLOUT)
-                       flags |= EV_WRITE;
-
-               if (!flags)
-                       return (0);
-
-               if (info->si_fd > op->highestfd)
-                       return (-1);
-
-               dat = TAILQ_FIRST(op->fdtodat[info->si_fd]);
-               while (dat != TAILQ_END(op->fdtodat[info->si_fd])) {
-                       next_dat = TAILQ_NEXT(dat, next);
-                       if (flags & dat->ev->ev_events) {
-                               ev = dat->ev;
-                               poll_add(op, ev, dat);
-                               activate(ev, flags & ev->ev_events);
-                               sigok = 1;
-                       }
-                       dat = next_dat;
-               }
-       } else if (signum == SIGIO) {
-               TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
-                       if (ev->ev_events & (EV_READ|EV_WRITE))
-                               poll_add(op, ev, NULL);
-               }
-               return (1); /* 1 means the caller should poll() again */
-    
-       } else if (sigismember(&op->sigs, signum)) {
-               /* managed signals are queued */
-               ev = TAILQ_FIRST(&signalqueue);
-               while (ev != TAILQ_END(&signalqueue)) {
-                       next_ev = TAILQ_NEXT(ev, ev_signal_next);
-                       if (EVENT_SIGNAL(ev) == signum)
-                               activate(ev, EV_SIGNAL);
-                       ev = next_ev;
-               }
-       } else {
-               /* dispatch unmanaged signals immediately */
-               struct sigaction sa;
-               if (sigaction(signum, NULL, &sa) == 0) {
-                       if ((sa.sa_flags & SA_SIGINFO) && sa.sa_sigaction) {
-                               (*sa.sa_sigaction)(signum, info, NULL);
-                       } else if (sa.sa_handler) {
-                               if ((int)sa.sa_handler != 1)
-                                       (*sa.sa_handler)(signum);
-                       } else {
-                               if (signum != SIGCHLD) {
-                                       /* non-blocked SIG_DFL */
-                                       kill(gettid(), signum);
-                               }
-                       }
-               }
-       }
-
-       return (0);
-}
-
-/*
- * return 1 if we should poll again
- * return 0 if we are all set
- * return -1 on error
- */
-static inline int
-do_sigwait(struct event_base *base, struct rtsigop *op,
-    struct timespec *ts, struct timespec **ts_p, sigset_t *sigs)
-{
-       for (;;) {
-               siginfo_t info;
-               int signum;
-
-               signum = sigtimedwait(sigs, &info, *ts_p);
-
-               ts->tv_sec = 0;
-               ts->tv_nsec = 0;
-               *ts_p = ts;
-
-               if (signum == -1) {
-                       if (errno == EAGAIN || errno == EINTR)
-                               return (0);
-                       return (-1);
-               } else if (1 == do_siginfo_dispatch(base, op, &info)) {
-                       return (1);
-               }
-       }
-
-       /* NOTREACHED */
-}
-
-static inline int
-do_signals_from_socket(struct event_base *base, struct rtsigop *op,
-    struct timespec *ts, struct timespec **ts_p)
-{
-       int fd = op->signal_recv_fd;
-       siginfo_t info;
-       int res;
-
-       for (;;) {
-               res = recv(fd, &info, sizeof(info), MSG_NOSIGNAL);
-               if (res == -1) {
-                       if (errno == EAGAIN)
-                               return (0);
-                       if (errno == EINTR)
-                               continue;
-                       return (-1);
-               } else {
-                       ts->tv_sec = 0;
-                       ts->tv_nsec = 0;
-                       *ts_p = ts;
-                       if (1 == do_siginfo_dispatch(base, op, &info))
-                               return (1);
-               }
-       }
-       /* NOTREACHED */
-}
-
-int
-rtsig_dispatch(struct event_base *base, void *arg, struct timeval *tv)
-{
-       struct rtsigop *op = (struct rtsigop *) arg;
-       struct timespec ts, *ts_p = NULL;
-       int res;
-       sigset_t sigs;
-
-       if (tv != NULL) {
-               ts.tv_sec = tv->tv_sec;
-               ts.tv_nsec = tv->tv_usec * 1000;
-               *ts_p = ts;
-       }
-
- poll_for_level:
-       /* ts and ts_p can be modified in do_XXX() */
-       res = do_poll(op, &ts, &ts_p);
-
-       res = do_signals_from_socket(base, op, &ts, &ts_p);
-       if (res == 1)
-               goto poll_for_level;
-       else if (res == -1)
-               return (-1);
-
-       /*
-        * the mask = managed_signals | unblocked-signals
-        * MM - if this is not blocking do we need to cast the net this wide?
-        */
-       sigemptyset(&sigs);
-       sigprocmask(SIG_BLOCK, &sigs, &sigs);
-       signotset(&sigs);
-       sigorset(&sigs, &sigs, &op->sigs);
-
-       res = do_sigwait(base, op, &ts, &ts_p, &sigs);
-
-       if (res == 1)
-               goto poll_for_level;
-       else if (res == -1)
-               return (-1);
-
-       return (0);
-}
-
diff --git a/libevent/test/test.sh b/libevent/test/test.sh
index 878d468..00ceec2 100755
--- a/libevent/test/test.sh
+++ b/libevent/test/test.sh
@@ -6,7 +6,6 @@ setup () {
         EVENT_NOPOLL=yes; export EVENT_NOPOLL
         EVENT_NOSELECT=yes; export EVENT_NOSELECT
         EVENT_NOEPOLL=yes; export EVENT_NOEPOLL
-        EVENT_NORTSIG=yes; export EVENT_NORTSIG
 }
 
 test () {
@@ -76,12 +75,6 @@ echo "SELECT"
 test
 
 setup
-unset EVENT_NORTSIG
-export EVENT_NORTSIG
-echo "RTSIG"
-test
-
-setup
 unset EVENT_NOEPOLL
 export EVENT_NOEPOLL
 echo "EPOLL"
-- 
1.5.3.GIT

_______________________________________________
Libevent-users mailing list
Libevent-users@monkey.org
http://monkey.org/mailman/listinfo/libevent-users

Reply via email to