#include <stdio.h>
#endif
+#define ELOOP_NSIGNALS 5 /* Allow a backlog of signals */
+
/*
* time_t is a signed integer of an unspecified size.
* To adjust for time_t wrapping, we need to work the maximum signed
TAILQ_HEAD (timeout_head, eloop_timeout) timeouts;
struct timeout_head free_timeouts;
- void (*timeout0)(void *);
- void *timeout0_arg;
const int *signals;
size_t signals_len;
void (*signal_cb)(int, void *);
(unsigned int)seconds, (unsigned int)nseconds, callback, arg);
}
-static int
-eloop_timeout_add_now(struct eloop *eloop,
- void (*callback)(void *), void *arg)
-{
-
- assert(eloop->timeout0 == NULL);
- eloop->timeout0 = callback;
- eloop->timeout0_arg = arg;
- return 0;
-}
-
int
eloop_q_timeout_delete(struct eloop *eloop, int queue,
void (*callback)(void *), void *arg)
eloop->signal_cb_ctx = signal_cb_ctx;
}
-struct eloop_siginfo {
- int sig;
- struct eloop *eloop;
-};
-static struct eloop_siginfo _eloop_siginfo;
-static struct eloop *_eloop;
-
-static void
-eloop_signal1(void *arg)
-{
- struct eloop_siginfo *si = arg;
-
- si->eloop->signal_cb(si->sig, si->eloop->signal_cb_ctx);
-}
+static volatile int _eloop_sig[ELOOP_NSIGNALS];
+static volatile size_t _eloop_nsig;
static void
eloop_signal3(int sig, __unused siginfo_t *siginfo, __unused void *arg)
{
- /* So that we can operate safely under a signal we instruct
- * eloop to pass a copy of the siginfo structure to handle_signal1
- * as the very first thing to do. */
- _eloop_siginfo.eloop = _eloop;
- _eloop_siginfo.sig = sig;
- eloop_timeout_add_now(_eloop_siginfo.eloop,
- eloop_signal1, &_eloop_siginfo);
+ if (_eloop_nsig == __arraycount(_eloop_sig)) {
+ fprintf(stderr, "%s: signal storm, discarding signal %d",
+ __func__, sig);
+ return;
+ }
+
+ _eloop_sig[_eloop_nsig++] = sig;
}
int
if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
return -1;
- _eloop = eloop;
sigemptyset(&sa.sa_mask);
for (i = 0; i < eloop->signals_len; i++) {
int n;
struct eloop_event *e;
struct eloop_timeout *t;
- void (*t0)(void *);
struct timespec ts, *tsp;
assert(eloop != NULL);
if (eloop->exitnow)
break;
- /* Run all timeouts first. */
- if (eloop->timeout0) {
- t0 = eloop->timeout0;
- eloop->timeout0 = NULL;
- t0(eloop->timeout0_arg);
+ if (_eloop_nsig != 0 && eloop->signal_cb != NULL) {
+ n = _eloop_sig[--_eloop_nsig];
+ eloop->signal_cb(n, eloop->signal_cb_ctx);
continue;
}