fix signal usage

svn:r45
This commit is contained in:
Niels Provos 2003-03-08 06:37:56 +00:00
parent ea1d95d2fb
commit cde7a3528d
5 changed files with 60 additions and 39 deletions

10
epoll.c
View File

@ -58,6 +58,7 @@
#endif #endif
#include "event.h" #include "event.h"
#include "evsignal.h"
extern struct event_list eventqueue; extern struct event_list eventqueue;
@ -80,13 +81,6 @@ struct epollop {
sigset_t evsigmask; sigset_t evsigmask;
} epollop; } epollop;
void evsignal_init(sigset_t *);
void evsignal_process(void);
int evsignal_recalc(sigset_t *);
int evsignal_deliver(void);
int evsignal_add(sigset_t *, struct event *);
int evsignal_del(sigset_t *, struct event *);
void *epoll_init (void); void *epoll_init (void);
int epoll_add (void *, struct event *); int epoll_add (void *, struct event *);
int epoll_del (void *, struct event *); int epoll_del (void *, struct event *);
@ -178,7 +172,7 @@ epoll_dispatch(void *arg, struct timeval *tv)
struct event *ev; struct event *ev;
int i, res, timeout; int i, res, timeout;
if (evsignal_deliver() == -1) if (evsignal_deliver(&epollop->evsigmask) == -1)
return (-1); return (-1);
timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000;

40
evsignal.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright 2000-2002 Niels Provos <provos@citi.umich.edu>
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Niels Provos.
* 4. 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.
*/
#ifndef _EVSIGNAL_H_
#define _EVSIGNAL_H_
void evsignal_init(sigset_t *);
void evsignal_process(void);
int evsignal_recalc(sigset_t *);
int evsignal_deliver(sigset_t *);
int evsignal_add(sigset_t *, struct event *);
int evsignal_del(sigset_t *, struct event *);
#endif /* _EVSIGNAL_H_ */

10
poll.c
View File

@ -57,6 +57,7 @@
#endif #endif
#include "event.h" #include "event.h"
#include "evsignal.h"
extern struct event_list eventqueue; extern struct event_list eventqueue;
@ -69,13 +70,6 @@ struct pollop {
sigset_t evsigmask; sigset_t evsigmask;
} pop; } pop;
void evsignal_init(sigset_t *);
void evsignal_process(void);
int evsignal_recalc(sigset_t *);
int evsignal_deliver(void);
int evsignal_add(sigset_t *, struct event *);
int evsignal_del(sigset_t *, struct event *);
void *poll_init (void); void *poll_init (void);
int poll_add (void *, struct event *); int poll_add (void *, struct event *);
int poll_del (void *, struct event *); int poll_del (void *, struct event *);
@ -172,7 +166,7 @@ poll_dispatch(void *arg, struct timeval *tv)
} }
} }
if (evsignal_deliver() == -1) if (evsignal_deliver(&pop->evsigmask) == -1)
return (-1); return (-1);
sec = tv->tv_sec * 1000 + tv->tv_usec / 1000; sec = tv->tv_sec * 1000 + tv->tv_usec / 1000;

View File

@ -56,6 +56,7 @@
#endif #endif
#include "event.h" #include "event.h"
#include "evsignal.h"
extern struct event_list eventqueue; extern struct event_list eventqueue;
@ -73,13 +74,6 @@ struct selectop {
sigset_t evsigmask; sigset_t evsigmask;
} sop; } sop;
void evsignal_init(sigset_t *);
void evsignal_process(void);
int evsignal_recalc(sigset_t *);
int evsignal_deliver(void);
int evsignal_add(sigset_t *, struct event *);
int evsignal_del(sigset_t *, struct event *);
void *select_init (void); void *select_init (void);
int select_add (void *, struct event *); int select_add (void *, struct event *);
int select_del (void *, struct event *); int select_del (void *, struct event *);
@ -174,7 +168,7 @@ select_dispatch(void *arg, struct timeval *tv)
FD_SET(ev->ev_fd, sop->event_readset); FD_SET(ev->ev_fd, sop->event_readset);
} }
if (evsignal_deliver() == -1) if (evsignal_deliver(&sop->evsigmask) == -1)
return (-1); return (-1);
res = select(sop->event_fds + 1, sop->event_readset, res = select(sop->event_fds + 1, sop->event_readset,

View File

@ -55,24 +55,15 @@
#include "event.h" #include "event.h"
extern struct event_list timequeue;
extern struct event_list eventqueue;
extern struct event_list signalqueue; extern struct event_list signalqueue;
short evsigcaught[NSIG]; static short evsigcaught[NSIG];
static int needrecalc;
volatile sig_atomic_t evsignal_caught = 0; volatile sig_atomic_t evsignal_caught = 0;
struct selectop {
int event_fds; /* Highest fd in fd set */
int event_fdsz;
fd_set *event_readset;
fd_set *event_writeset;
sigset_t evsigmask;
} sop;
void evsignal_process(void); void evsignal_process(void);
int evsignal_recalc(sigset_t *); int evsignal_recalc(sigset_t *);
int evsignal_deliver(void); int evsignal_deliver(sigset_t *);
void void
evsignal_init(sigset_t *evsigmask) evsignal_init(sigset_t *evsigmask)
@ -104,6 +95,7 @@ evsignal_del(sigset_t *evsigmask, struct event *ev)
signal = EVENT_SIGNAL(ev); signal = EVENT_SIGNAL(ev);
sigdelset(evsigmask, signal); sigdelset(evsigmask, signal);
needrecalc = 1;
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL)); return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
} }
@ -121,13 +113,17 @@ evsignal_recalc(sigset_t *evsigmask)
struct sigaction sa; struct sigaction sa;
struct event *ev; struct event *ev;
if (TAILQ_FIRST(&signalqueue) == NULL && !needrecalc)
return (0);
needrecalc = 0;
if (sigprocmask(SIG_BLOCK, evsigmask, NULL) == -1) if (sigprocmask(SIG_BLOCK, evsigmask, NULL) == -1)
return (-1); return (-1);
/* Reinstall our signal handler. */ /* Reinstall our signal handler. */
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
sa.sa_handler = evsignal_handler; sa.sa_handler = evsignal_handler;
sa.sa_mask = sop.evsigmask; sa.sa_mask = *evsigmask;
sa.sa_flags |= SA_RESTART; sa.sa_flags |= SA_RESTART;
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) { TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
@ -138,9 +134,12 @@ evsignal_recalc(sigset_t *evsigmask)
} }
int int
evsignal_deliver(void) evsignal_deliver(sigset_t *evsigmask)
{ {
return (sigprocmask(SIG_UNBLOCK, &sop.evsigmask, NULL)); if (TAILQ_FIRST(&signalqueue) == NULL)
return (0);
return (sigprocmask(SIG_UNBLOCK, evsigmask, NULL));
/* XXX - pending signals handled here */ /* XXX - pending signals handled here */
} }