moonbridge

diff moonbridge_io.c @ 296:ce109800ae2d

Extend moonbridge_io.poll(...) to support waiting for child process termination
author jbe
date Sat Jun 17 22:35:44 2017 +0200 (2017-06-17)
parents 1eef86d3b925
children dd0ec48592e7
line diff
     1.1 --- a/moonbridge_io.c	Sat Jun 17 20:07:03 2017 +0200
     1.2 +++ b/moonbridge_io.c	Sat Jun 17 22:35:44 2017 +0200
     1.3 @@ -1657,6 +1657,7 @@
     1.4  static int moonbr_io_poll(lua_State *L) {
     1.5    moonbr_io_handle_t *handle;
     1.6    moonbr_io_listener_t *listener;
     1.7 +  moonbr_io_child_t *child;
     1.8    int fd, isnum;
     1.9    int nfds = 0;
    1.10    fd_set readfds, writefds, exceptfds;
    1.11 @@ -1664,6 +1665,8 @@
    1.12    int force_wakeup = 0;
    1.13    int use_timeout = 0;  // negative for negative timeout
    1.14    int check_sigterm = 0;
    1.15 +  int check_child = 0;
    1.16 +  int childstatus;
    1.17    sigset_t mask, orig_mask;
    1.18    int status;
    1.19    FD_ZERO(&readfds);
    1.20 @@ -1693,8 +1696,20 @@
    1.21              fd = listener->fd;
    1.22              if (fd < 0) luaL_error(L, "Attempt to poll a closed listener");
    1.23            } else {
    1.24 -            fd = lua_tointegerx(L, -2, &isnum);
    1.25 -            if (!isnum) luaL_error(L, "Expected integer (file descriptor), I/O handle, or listener in table key");
    1.26 +            child = luaL_testudata(L, -2, MOONBR_IO_CHILD_MT_REGKEY);
    1.27 +            if (child) {
    1.28 +              check_child = 1;
    1.29 +              if (waitpid(child->pid, &childstatus, WNOHANG|WNOWAIT) != -1) {
    1.30 +                force_wakeup = 1;
    1.31 +              } else if (errno != ECHILD && errno != EINTR) {
    1.32 +                moonbr_io_prepare_errmsg();
    1.33 +                luaL_error(L, "Error in waitpid call: %s", errmsg);
    1.34 +              }
    1.35 +              continue;
    1.36 +            } else {
    1.37 +              fd = lua_tointegerx(L, -2, &isnum);
    1.38 +              if (!isnum) luaL_error(L, "Expected integer (file descriptor), I/O handle, or listener in table key");
    1.39 +            }
    1.40            }
    1.41          }
    1.42          if (fd < 0 || fd >= FD_SETSIZE) luaL_error(L, "File descriptor out of valid range");
    1.43 @@ -1743,20 +1758,29 @@
    1.44    if (use_timeout < 0) force_wakeup = 1;
    1.45    if (!lua_isnoneornil(L, 4)) luaL_checktype(L, 4, LUA_TBOOLEAN);
    1.46    check_sigterm = lua_toboolean(L, 4);
    1.47 -  if (check_sigterm) {
    1.48 +  if ((check_sigterm || check_child) && !force_wakeup) {
    1.49 +    sigemptyset(&mask);
    1.50 +    if (check_sigterm) sigaddset(&mask, SIGTERM);
    1.51 +    if (check_child) sigaddset(&mask, SIGCHLD);
    1.52 +    if (sigprocmask(SIG_BLOCK, &mask, &orig_mask)) abort();
    1.53 +  }
    1.54 +  if (check_sigterm && moonbr_io_sigterm_flag) {
    1.55      if (!force_wakeup) {
    1.56 -      sigemptyset(&mask);
    1.57 -      sigaddset(&mask, SIGTERM);
    1.58 -      if (sigprocmask(SIG_BLOCK, &mask, &orig_mask)) abort();
    1.59 +      if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort();
    1.60      }
    1.61 -    if (moonbr_io_sigterm_flag) {
    1.62 -      if (!force_wakeup) {
    1.63 -        if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort();
    1.64 -      }
    1.65 -      lua_pushboolean(L, 0);
    1.66 -      lua_pushliteral(L, "SIGTERM received");
    1.67 -      lua_pushboolean(L, 1);
    1.68 -      return 3;
    1.69 +    lua_pushboolean(L, 0);
    1.70 +    lua_pushliteral(L, "SIGTERM received");
    1.71 +    lua_pushboolean(L, 1);
    1.72 +    return 3;
    1.73 +  }
    1.74 +  if (check_child && !force_wakeup) {
    1.75 +    if (wait3(&childstatus, WNOHANG|WNOWAIT, NULL) != -1) {
    1.76 +      if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort();
    1.77 +      force_wakeup = 1;
    1.78 +    } else if (errno != ECHILD && errno != EINTR) {
    1.79 +      moonbr_io_prepare_errmsg();
    1.80 +      if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort();
    1.81 +      luaL_error(L, "Error in waitpid call: %s", errmsg);
    1.82      }
    1.83    }
    1.84    if (use_timeout < 0) {

Impressum / About Us