Browse Source

*** empty log message ***

master
Marc Alexander Lehmann 12 years ago
parent
commit
8761b2c217
3 changed files with 84 additions and 92 deletions
  1. +2
    -2
      Changes
  2. +79
    -90
      ev.c
  3. +3
    -0
      ev.h

+ 2
- 2
Changes View File

@ -2,8 +2,8 @@ Revision history for libev, a high-performance and full-featured event loop.
TODO: ev_walk
TODO: signal handling per loop
TODO: nsig
TODO: NSIG etc.
TODO: NOSIGFD/NOEVTFD/NOINOTIFY?
- 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,


+ 79
- 90
ev.c View File

@ -189,6 +189,7 @@ 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)
@ -212,16 +213,9 @@ extern "C" {
#else
# error "unable to find value for NSIG, please report"
/* to make it compile regardless, just remove the above line */
# define EV_NSIG 64
# define EV_NSIG 65
#endif
/* Default to some arbitrary number that's big enough to get most
of the common signals.
*/
#ifndef NSIG
# define NSIG 50
#endif
/* <-- NSIG logic from Configure */
#ifndef EV_USE_CLOCK_SYSCALL
# if __linux && __GLIBC__ >= 2
# define EV_USE_CLOCK_SYSCALL 1
@ -1135,13 +1129,14 @@ reheap (ANHE *heap, int N)
/* associate signal watchers to a signal signal */
typedef struct
{
#if EV_MULTIPLICITY
EV_P;
#endif
WL head;
EV_ATOMIC_T gotsig;
} ANSIG;
static ANSIG *signals;
static int signalmax;
static ANSIG signals [EV_NSIG - 1];
static EV_ATOMIC_T gotsig;
/*****************************************************************************/
@ -1238,7 +1233,7 @@ pipecb (EV_P_ ev_io *iow, int revents)
int signum;
gotsig = 0;
for (signum = signalmax; signum--; )
for (signum = EV_NSIG - 1; signum--; )
if (signals [signum].gotsig)
ev_feed_signal_event (EV_A_ signum + 1);
}
@ -1265,7 +1260,7 @@ static void
ev_sighandler (int signum)
{
#if EV_MULTIPLICITY
struct ev_loop *loop = &default_loop_struct;
EV_P = signals [signum - 1].loop;
#endif
#if _WIN32
@ -1285,11 +1280,11 @@ ev_feed_signal_event (EV_P_ int signum)
assert (("libev: feeding signal events is only supported in the default loop", loop == ev_default_loop_ptr));
#endif
--signum;
if (signum < 0 || signum >= signalmax)
if (signum <= 0 || signum > EV_NSIG)
return;
--signum;
signals [signum].gotsig = 0;
for (w = signals [signum].head; w; w = w->next)
@ -1300,7 +1295,7 @@ ev_feed_signal_event (EV_P_ int signum)
static void
sigfdcb (EV_P_ ev_io *iow, int revents)
{
struct signalfd_siginfo si[4], *sip;
struct signalfd_siginfo si[2], *sip; /* these structs are big */
for (;;)
{
@ -1544,6 +1539,17 @@ loop_init (EV_P_ unsigned int flags)
}
#endif
/* pid check not overridable via env */
#ifndef _WIN32
if (flags & EVFLAG_FORKCHECK)
curpid = getpid ();
#endif
if (!(flags & EVFLAG_NOENV)
&& !enable_secure ()
&& getenv ("LIBEV_FLAGS"))
flags = atoi (getenv ("LIBEV_FLAGS"));
ev_rt_now = ev_time ();
mn_now = get_clock ();
now_floor = mn_now;
@ -1558,23 +1564,12 @@ loop_init (EV_P_ unsigned int flags)
backend_fd = -1;
gotasync = 0;
#if EV_USE_INOTIFY
fs_fd = -2;
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
#endif
#if EV_USE_SIGNALFD
sigfd = -2;
sigfd = flags & EVFLAG_NOSIGFD ? -1 : -2;
#endif
/* pid check not overridable via env */
#ifndef _WIN32
if (flags & EVFLAG_FORKCHECK)
curpid = getpid ();
#endif
if (!(flags & EVFLAG_NOENV)
&& !enable_secure ()
&& getenv ("LIBEV_FLAGS"))
flags = atoi (getenv ("LIBEV_FLAGS"));
if (!(flags & 0x0000ffffU))
flags |= ev_recommended_backends ();
@ -1743,13 +1738,13 @@ loop_fork (EV_P)
struct ev_loop *
ev_loop_new (unsigned int flags)
{
struct ev_loop *loop = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
memset (loop, 0, sizeof (struct ev_loop));
memset (EV_A, 0, sizeof (struct ev_loop));
loop_init (EV_A_ flags);
if (ev_backend (EV_A))
return loop;
return EV_A;
return 0;
}
@ -1863,7 +1858,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 = signalmax; signum--; ) if (signals [signum].gotsig)
for (signum = EV_NSIG; signum--; ) if (signals [signum].gotsig)
# endif
#endif
}
@ -1880,7 +1875,7 @@ ev_default_loop (unsigned int flags)
if (!ev_default_loop_ptr)
{
#if EV_MULTIPLICITY
struct ev_loop *loop = ev_default_loop_ptr = &default_loop_struct;
EV_P = ev_default_loop_ptr = &default_loop_struct;
#else
ev_default_loop_ptr = 1;
#endif
@ -1907,7 +1902,7 @@ void
ev_default_destroy (void)
{
#if EV_MULTIPLICITY
struct ev_loop *loop = ev_default_loop_ptr;
EV_P = ev_default_loop_ptr;
#endif
ev_default_loop_ptr = 0;
@ -1924,7 +1919,7 @@ void
ev_default_fork (void)
{
#if EV_MULTIPLICITY
struct ev_loop *loop = ev_default_loop_ptr;
EV_P = ev_default_loop_ptr;
#endif
postfork = 1; /* must be in line with ev_loop_fork */
@ -2667,13 +2662,17 @@ ev_periodic_again (EV_P_ ev_periodic *w)
void noinline
ev_signal_start (EV_P_ ev_signal *w)
{
#if EV_MULTIPLICITY
assert (("libev: signal watchers are only supported in the default loop", loop == ev_default_loop_ptr));
#endif
if (expect_false (ev_is_active (w)))
return;
assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0));
assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG));
#if EV_MULTIPLICITY
assert (("libev: tried to attach to a signal from two different loops",
!signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop));
signals [w->signum - 1].loop = EV_A;
#endif
EV_FREQUENT_CHECK;
@ -2705,48 +2704,33 @@ ev_signal_start (EV_P_ ev_signal *w)
signalfd (sigfd, &sigfd_set, 0);
}
else
#endif
evpipe_init (EV_A);
{
#ifndef _WIN32
sigset_t full, prev;
sigfillset (&full);
sigprocmask (SIG_SETMASK, &full, &prev);
#endif
array_needsize (ANSIG, signals, signalmax, w->signum, array_init_zero);
#ifndef _WIN32
# if EV_USE_SIGNALFD
if (sigfd < 0)/*TODO*/
# endif
sigdelset (&prev, w->signum);
sigprocmask (SIG_SETMASK, &prev, 0);
#endif
}
ev_start (EV_A_ (W)w, 1);
wlist_add (&signals [w->signum - 1].head, (WL)w);
if (!((WL)w)->next)
{
#if _WIN32
signal (w->signum, ev_sighandler);
#else
# if EV_USE_SIGNALFD
if (sigfd < 0) /*TODO*/
if (sigfd < 0) /*TODO*/
# endif
{
struct sigaction sa = { };
sa.sa_handler = ev_sighandler;
sigfillset (&sa.sa_mask);
sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
sigaction (w->signum, &sa, 0);
}
{
# if _WIN32
signal (w->signum, ev_sighandler);
# else
struct sigaction sa;
evpipe_init (EV_A);
sa.sa_handler = ev_sighandler;
sigfillset (&sa.sa_mask);
sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
sigaction (w->signum, &sa, 0);
sigemptyset (&sa.sa_mask);
sigaddset (&sa.sa_mask, w->signum);
sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
#endif
}
}
EV_FREQUENT_CHECK;
}
@ -2764,18 +2748,23 @@ ev_signal_stop (EV_P_ ev_signal *w)
ev_stop (EV_A_ (W)w);
if (!signals [w->signum - 1].head)
#if EV_USE_SIGNALFD
if (sigfd >= 0)
{
sigprocmask (SIG_UNBLOCK, &sigfd_set, 0);//D
sigdelset (&sigfd_set, w->signum);
signalfd (sigfd, &sigfd_set, 0);
sigprocmask (SIG_BLOCK, &sigfd_set, 0);//D
/*TODO: maybe unblock signal? */
}
else
#endif
signal (w->signum, SIG_DFL);
{
#if EV_MULTIPLICITY
signals [w->signum - 1].loop = 0; /* unattach from signal */
#endif
#if EV_USE_SIGNALFD
if (sigfd >= 0)
{
sigprocmask (SIG_UNBLOCK, &sigfd_set, 0);//D
sigdelset (&sigfd_set, w->signum);
signalfd (sigfd, &sigfd_set, 0);
sigprocmask (SIG_BLOCK, &sigfd_set, 0);//D
/*TODO: maybe unblock signal? */
}
else
#endif
signal (w->signum, SIG_DFL);
}
EV_FREQUENT_CHECK;
}
@ -3265,7 +3254,7 @@ embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare));
{
struct ev_loop *loop = w->other;
EV_P = w->other;
while (fdchangecnt)
{
@ -3283,7 +3272,7 @@ embed_fork_cb (EV_P_ ev_fork *fork_w, int revents)
ev_embed_stop (EV_A_ w);
{
struct ev_loop *loop = w->other;
EV_P = w->other;
ev_loop_fork (EV_A);
ev_loop (EV_A_ EVLOOP_NONBLOCK);
@ -3307,7 +3296,7 @@ ev_embed_start (EV_P_ ev_embed *w)
return;
{
struct ev_loop *loop = w->other;
EV_P = w->other;
assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
}
@ -3588,7 +3577,7 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
cb (EV_A_ EV_CHECK, checks [i]);
if (types & EV_SIGNAL)
for (i = 0; i < signalmax; ++i)
for (i = 0; i < EV_NSIG - 1; ++i)
for (wl = signals [i].head; wl; )
{
wn = wl->next;


+ 3
- 0
ev.h View File

@ -404,6 +404,9 @@ union ev_any_watcher
/* flag bits */
#define EVFLAG_NOENV 0x01000000U /* do NOT consult environment */
#define EVFLAG_FORKCHECK 0x02000000U /* check for a fork in each iteration */
/* debugging/feature disable */
#define EVFLAG_NOINOTIFY 0x00100000U /* do not attempt to use inotify */
#define EVFLAG_NOSIGFD 0x00200000U /* do not attempt to use signalfd */
/* method bits to be ored together */
#define EVBACKEND_SELECT 0x00000001U /* about anywhere */
#define EVBACKEND_POLL 0x00000002U /* !win */


Loading…
Cancel
Save