diff options
| -rw-r--r-- | Changes | 4 | ||||
| -rw-r--r-- | ev.c | 169 | ||||
| -rw-r--r-- | ev.h | 3 | 
3 files changed, 84 insertions, 92 deletions
| @@ -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, @@ -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; @@ -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 */ | 
