# HG changeset patch # User jbe # Date 1497732224 -7200 # Node ID dd0ec48592e70930fe550a683ea9584060686500 # Parent ce109800ae2dd5ae7ff32ae0f32dd083e7d0246b Bugfix regarding waiting for child processes in moonbridge_io.poll(...) diff -r ce109800ae2d -r dd0ec48592e7 moonbridge_io.c --- a/moonbridge_io.c Sat Jun 17 22:35:44 2017 +0200 +++ b/moonbridge_io.c Sat Jun 17 22:43:44 2017 +0200 @@ -117,6 +117,7 @@ } moonbr_io_child_t; volatile sig_atomic_t moonbr_io_sigterm_flag = 0; +volatile sig_atomic_t moonbr_io_sigchld_flag = 0; static int moonbr_io_yield(lua_State *L) { return lua_yield(L, lua_gettop(L)); @@ -1615,6 +1616,10 @@ moonbr_io_sigterm_flag = 1; } +static void moonbr_io_sigchld_handler(int sig) { + moonbr_io_sigchld_flag = 1; +} + int moonbr_io_catch_sigterm(lua_State *L) { signal(SIGTERM, moonbr_io_sigterm_handler); return 0; @@ -1665,7 +1670,7 @@ int force_wakeup = 0; int use_timeout = 0; // negative for negative timeout int check_sigterm = 0; - int check_child = 0; + int check_sigchld = 0; int childstatus; sigset_t mask, orig_mask; int status; @@ -1698,7 +1703,11 @@ } else { child = luaL_testudata(L, -2, MOONBR_IO_CHILD_MT_REGKEY); if (child) { - check_child = 1; + if (!check_sigchld) { + check_sigchld = 1; + moonbr_io_sigchld_flag = 0; + signal(SIGCHLD, moonbr_io_sigchld_handler); + } if (waitpid(child->pid, &childstatus, WNOHANG|WNOWAIT) != -1) { force_wakeup = 1; } else if (errno != ECHILD && errno != EINTR) { @@ -1758,10 +1767,10 @@ if (use_timeout < 0) force_wakeup = 1; if (!lua_isnoneornil(L, 4)) luaL_checktype(L, 4, LUA_TBOOLEAN); check_sigterm = lua_toboolean(L, 4); - if ((check_sigterm || check_child) && !force_wakeup) { + if ((check_sigterm || check_sigchld) && !force_wakeup) { sigemptyset(&mask); if (check_sigterm) sigaddset(&mask, SIGTERM); - if (check_child) sigaddset(&mask, SIGCHLD); + if (check_sigchld) sigaddset(&mask, SIGCHLD); if (sigprocmask(SIG_BLOCK, &mask, &orig_mask)) abort(); } if (check_sigterm && moonbr_io_sigterm_flag) { @@ -1773,15 +1782,9 @@ lua_pushboolean(L, 1); return 3; } - if (check_child && !force_wakeup) { - if (wait3(&childstatus, WNOHANG|WNOWAIT, NULL) != -1) { - if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort(); - force_wakeup = 1; - } else if (errno != ECHILD && errno != EINTR) { - moonbr_io_prepare_errmsg(); - if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort(); - luaL_error(L, "Error in waitpid call: %s", errmsg); - } + if (check_sigchld && !force_wakeup && moonbr_io_sigchld_flag) { + if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort(); + force_wakeup = 1; } if (use_timeout < 0) { lua_pushboolean(L, 0);