summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes1
-rw-r--r--ev.c69
-rw-r--r--ev_vars.h3
-rw-r--r--ev_wrap.h6
4 files changed, 44 insertions, 35 deletions
diff --git a/Changes b/Changes
index d903d39..ffe9d9e 100644
--- a/Changes
+++ b/Changes
@@ -4,6 +4,7 @@ TODO: ev_walk
TODO: signal handling per loop
TODO: NSIG etc.
TODO: NOSIGFD/NOEVTFD/NOINOTIFY?
+TODO: gotsig per-loop
- incompatible change: do not necessarily reset signal handler
to SIG_DFL when a sighandler is stopped.
- ev_default_destroy did not properly free or zero some members,
diff --git a/ev.c b/ev.c
index a3443d2..20e0a43 100644
--- a/ev.c
+++ b/ev.c
@@ -189,7 +189,6 @@ extern "C" {
/* this block tries to deduce configuration from header-defined symbols and defaults */
/* try to deduce the maximum number of signals on this platform */
-/* one some platforms, NSIG is one too large. we do not bother */
#if defined (EV_NSIG)
/* use what's provided */
#elif defined (NSIG)
@@ -960,7 +959,7 @@ fd_enomem (EV_P)
if (anfds [fd].events)
{
fd_kill (EV_A_ fd);
- return;
+ break;
}
}
@@ -1129,15 +1128,14 @@ reheap (ANHE *heap, int N)
/* associate signal watchers to a signal signal */
typedef struct
{
+ EV_ATOMIC_T pending;
#if EV_MULTIPLICITY
EV_P;
#endif
WL head;
- EV_ATOMIC_T gotsig;
} ANSIG;
static ANSIG signals [EV_NSIG - 1];
-static EV_ATOMIC_T gotsig;
/*****************************************************************************/
@@ -1215,6 +1213,8 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
static void
pipecb (EV_P_ ev_io *iow, int revents)
{
+ int i;
+
#if EV_USE_EVENTFD
if (evfd >= 0)
{
@@ -1228,21 +1228,19 @@ pipecb (EV_P_ ev_io *iow, int revents)
read (evpipe [0], &dummy, 1);
}
- if (gotsig && ev_is_default_loop (EV_A))
+ if (sig_pending)
{
- int signum;
- gotsig = 0;
+ sig_pending = 0;
- for (signum = EV_NSIG - 1; signum--; )
- if (signals [signum].gotsig)
- ev_feed_signal_event (EV_A_ signum + 1);
+ for (i = EV_NSIG - 1; i--; )
+ if (expect_false (signals [i].pending))
+ ev_feed_signal_event (EV_A_ i + 1);
}
#if EV_ASYNC_ENABLE
- if (gotasync)
+ if (async_pending)
{
- int i;
- gotasync = 0;
+ async_pending = 0;
for (i = asynccnt; i--; )
if (asyncs [i]->sent)
@@ -1267,8 +1265,8 @@ ev_sighandler (int signum)
signal (signum, ev_sighandler);
#endif
- signals [signum - 1].gotsig = 1;
- evpipe_write (EV_A_ &gotsig);
+ signals [signum - 1].pending = 1;
+ evpipe_write (EV_A_ &sig_pending);
}
void noinline
@@ -1276,16 +1274,20 @@ ev_feed_signal_event (EV_P_ int signum)
{
WL w;
-#if EV_MULTIPLICITY
- assert (("libev: feeding signal events is only supported in the default loop", loop == ev_default_loop_ptr));
-#endif
-
- if (signum <= 0 || signum > EV_NSIG)
+ if (expect_false (signum <= 0 || signum > EV_NSIG))
return;
--signum;
- signals [signum].gotsig = 0;
+#if EV_MULTIPLICITY
+ /* it is permissible to try to feed a signal to the wrong loop */
+ /* or, likely more useful, feeding a signal nobody is waiting for */
+
+ if (expect_false (signals [signum].loop != EV_A))
+ return;
+#endif
+
+ signals [signum].pending = 0;
for (w = signals [signum].head; w; w = w->next)
ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
@@ -1562,7 +1564,10 @@ loop_init (EV_P_ unsigned int flags)
timeout_blocktime = 0.;
backend = 0;
backend_fd = -1;
- gotasync = 0;
+ sig_pending = 0;
+#if EV_ASYNC_ENABLE
+ async_pending = 0;
+#endif
#if EV_USE_INOTIFY
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
#endif
@@ -1706,9 +1711,9 @@ loop_fork (EV_P)
{
/* this "locks" the handlers against writing to the pipe */
/* while we modify the fd vars */
- gotsig = 1;
+ sig_pending = 1;
#if EV_ASYNC_ENABLE
- gotasync = 1;
+ async_pending = 1;
#endif
ev_ref (EV_A);
@@ -1858,7 +1863,7 @@ ev_loop_verify (EV_P)
# if 0
for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
- for (signum = EV_NSIG; signum--; ) if (signals [signum].gotsig)
+ for (signum = EV_NSIG; signum--; ) if (signals [signum].pending)
# endif
#endif
}
@@ -2395,10 +2400,10 @@ wlist_del (WL *head, WL elem)
{
while (*head)
{
- if (*head == elem)
+ if (expect_true (*head == elem))
{
*head = elem->next;
- return;
+ break;
}
head = &(*head)->next;
@@ -2749,10 +2754,10 @@ ev_signal_stop (EV_P_ ev_signal *w)
if (!signals [w->signum - 1].head)
{
- #if EV_MULTIPLICITY
+#if EV_MULTIPLICITY
signals [w->signum - 1].loop = 0; /* unattach from signal */
- #endif
- #if EV_USE_SIGNALFD
+#endif
+#if EV_USE_SIGNALFD
if (sigfd >= 0)
{
sigprocmask (SIG_UNBLOCK, &sigfd_set, 0);//D
@@ -2762,7 +2767,7 @@ ev_signal_stop (EV_P_ ev_signal *w)
/*TODO: maybe unblock signal? */
}
else
- #endif
+#endif
signal (w->signum, SIG_DFL);
}
@@ -3418,7 +3423,7 @@ void
ev_async_send (EV_P_ ev_async *w)
{
w->sent = 1;
- evpipe_write (EV_A_ &gotasync);
+ evpipe_write (EV_A_ &async_pending);
}
#endif
diff --git a/ev_vars.h b/ev_vars.h
index 4e118d7..da53ee8 100644
--- a/ev_vars.h
+++ b/ev_vars.h
@@ -152,8 +152,8 @@ VARx(int, forkmax)
VARx(int, forkcnt)
#endif
-VARx(EV_ATOMIC_T, gotasync)
#if EV_ASYNC_ENABLE || EV_GENWRAP
+VARx(EV_ATOMIC_T, async_pending)
VARx(struct ev_async **, asyncs)
VARx(int, asyncmax)
VARx(int, asynccnt)
@@ -166,6 +166,7 @@ VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */
VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
#endif
+VARx(EV_ATOMIC_T, sig_pending)
#if EV_USE_SIGNALFD || EV_GENWRAP
VARx(int, sigfd)
VARx(ev_io, sigfd_w)
diff --git a/ev_wrap.h b/ev_wrap.h
index d5b0178..ee3603d 100644
--- a/ev_wrap.h
+++ b/ev_wrap.h
@@ -69,7 +69,8 @@
#define forks ((loop)->forks)
#define forkmax ((loop)->forkmax)
#define forkcnt ((loop)->forkcnt)
-#define gotasync ((loop)->gotasync)
+#define sig_pending ((loop)->sig_pending)
+#define async_pending ((loop)->async_pending)
#define asyncs ((loop)->asyncs)
#define asyncmax ((loop)->asyncmax)
#define asynccnt ((loop)->asynccnt)
@@ -156,7 +157,8 @@
#undef forks
#undef forkmax
#undef forkcnt
-#undef gotasync
+#undef sig_pending
+#undef async_pending
#undef asyncs
#undef asyncmax
#undef asynccnt