diff options
| author | root <root> | 2007-11-03 11:44:44 +0000 | 
|---|---|---|
| committer | root <root> | 2007-11-03 11:44:44 +0000 | 
| commit | 1c33c678365888dfd0e9ba9271dc55d6093d490d (patch) | |
| tree | 24b8666dd0e4f9d785c5b86fdd66b02e1ecc3e03 | |
| parent | e3cb88fa576a8f24145df1c6962db20c8013700f (diff) | |
rework signal and child handling
| -rw-r--r-- | ev.c | 42 | ||||
| -rw-r--r-- | ev.h | 1 | ||||
| -rw-r--r-- | ev_epoll.c | 2 | 
3 files changed, 34 insertions, 11 deletions
@@ -478,19 +478,35 @@ static struct ev_signal childev;  #endif  static void -childcb (struct ev_signal *sw, int revents) +child_reap (struct ev_signal *sw, int chain, int pid, int status)  {    struct ev_child *w; + +  for (w = childs [chain & (PID_HASHSIZE - 1)]; w; w = w->next) +    if (w->pid == pid || !w->pid) +      { +        w->priority = sw->priority; /* need to do it *now* */ +        w->rpid     = pid; +        w->rstatus  = status; +        printf ("rpid %p %d %d\n", w, pid, w->pid);//D +        event ((W)w, EV_CHILD); +      } +} + +static void +childcb (struct ev_signal *sw, int revents) +{    int pid, status; -  while ((pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)) != -1) -    for (w = childs [pid & (PID_HASHSIZE - 1)]; w; w = w->next) -      if (w->pid == pid || !w->pid) -        { -          w->rpid    = pid; -          w->rstatus = status; -          event ((W)w, EV_CHILD); -        } +            printf ("chld %x\n", revents);//D +  if (0 < (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED))) +    { +      /* make sure we are called again until all childs have been reaped */ +      event ((W)sw, EV_SIGNAL); + +      child_reap (sw, pid, pid, status); +      child_reap (sw,   0, pid, status); /* this might trigger a watcher twice, but event catches that */ +    }  }  #endif @@ -573,10 +589,12 @@ int ev_init (int methods)        if (ev_method)          {            ev_watcher_init (&sigev, sigcb); +          ev_set_priority (&sigev, EV_MAXPRI);            siginit ();  #ifndef WIN32            ev_signal_init (&childev, childcb, SIGCHLD); +          ev_set_priority (&childev, EV_MAXPRI);            ev_signal_start (&childev);  #endif          } @@ -1010,6 +1028,10 @@ ev_periodic_stop (struct ev_periodic *w)    ev_stop ((W)w);  } +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif +  void  ev_signal_start (struct ev_signal *w)  { @@ -1027,7 +1049,7 @@ ev_signal_start (struct ev_signal *w)        struct sigaction sa;        sa.sa_handler = sighandler;        sigfillset (&sa.sa_mask); -      sa.sa_flags = 0; +      sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */        sigaction (w->signum, &sa, 0);      }  } @@ -168,6 +168,7 @@ struct ev_check  /* invoked when sigchld is received and waitpid indicates the givne pid */  /* revent EV_CHILD */ +/* does not support priorities */  struct ev_child  {    EV_WATCHER_LIST (ev_child); @@ -75,7 +75,7 @@ epoll_poll (ev_tstamp timeout)    for (i = 0; i < eventcnt; ++i)      fd_event ( -      events [i].data.fd, +      events [i].data.u64,        (events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)        | (events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0)      );  | 
