moonbridge

diff moonbridge_io.c @ 284:28aab22e68b6

New implementation of SIGTERM handling
author jbe
date Sun Jun 11 00:02:43 2017 +0200 (2017-06-11)
parents 6bb191b6ead5
children a7395fb91ec3
line diff
     1.1 --- a/moonbridge_io.c	Fri Jun 09 18:33:57 2017 +0200
     1.2 +++ b/moonbridge_io.c	Sun Jun 11 00:02:43 2017 +0200
     1.3 @@ -55,18 +55,12 @@
     1.4      moonbr_io_return_prepared_errmsg(); \
     1.5    } while (0)
     1.6  
     1.7 -#define MOONBR_IO_MAXSIGNUM 127
     1.8 -static int moonbr_io_signalfds[2*(MOONBR_IO_MAXSIGNUM+1)];
     1.9 -#define moonbr_io_signalfd_read(x) moonbr_io_signalfds[2*(x)+0]
    1.10 -#define moonbr_io_signalfd_write(x) moonbr_io_signalfds[2*(x)+1]
    1.11 -
    1.12  #define MOONBR_IO_HANDLE_MT_REGKEY "moonbridge_io_handle"
    1.13  #define MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY "moonbridge_io_handle_public"
    1.14  #define MOONBR_IO_LISTENER_MT_REGKEY "moonbridge_io_listener"
    1.15  #define MOONBR_IO_CHILD_MT_REGKEY "moonbridge_io_child"
    1.16  #define MOONBR_IO_CHILD_PT_REGKEY "moonbridge_io_child_pt"
    1.17  #define MOONBR_IO_SIGNALS_REGKEY "moonbridge_io_signals"
    1.18 -#define MOONBR_IO_SIGNALSOCKETS_REGKEY "moonbridge_io_signalsockets"
    1.19  
    1.20  #ifdef MOONBR_IO_USE_TLS
    1.21  
    1.22 @@ -123,6 +117,8 @@
    1.23    pid_t pid;
    1.24  } moonbr_io_child_t;
    1.25  
    1.26 +static volatile sig_atomic_t moonbr_io_sigterm_flag = 0;
    1.27 +
    1.28  static int moonbr_io_yield(lua_State *L) {
    1.29    return lua_yield(L, lua_gettop(L));
    1.30  }
    1.31 @@ -1627,48 +1623,17 @@
    1.32  
    1.33  moonbr_io_yield_wrapper(moonbr_io_wait_yield, moonbr_io_wait_call);
    1.34  
    1.35 -static void moonbr_io_signalhandler(int sig) {
    1.36 -  int errno2 = errno;
    1.37 -  char buf[1] = {'.'};
    1.38 -  write(moonbr_io_signalfd_write(sig), buf, 1);
    1.39 -  errno = errno2;
    1.40 +static void moonbr_io_sigterm_handler(int sig) {
    1.41 +  moonbr_io_sigterm_flag = 1;
    1.42  }
    1.43  
    1.44 -static int moonbr_io_signalsocket(lua_State *L) {
    1.45 -  int sig, fd;
    1.46 -  if (lua_type(L, 1) == LUA_TSTRING) {
    1.47 -    lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALS_REGKEY);
    1.48 -    lua_pushvalue(L, 1);
    1.49 -    lua_gettable(L, -2);
    1.50 -    sig = lua_tointeger(L, -1);
    1.51 -    if (!sig) {
    1.52 -      lua_pushvalue(L, 1);
    1.53 -      luaL_error(L, "Unknown signal \"%s\"", lua_tostring(L, 1));
    1.54 -    }
    1.55 -  } else {
    1.56 -    sig = luaL_checkinteger(L, 1);
    1.57 -  }
    1.58 -  if (sig < 1 || sig > MOONBR_IO_MAXSIGNUM) {
    1.59 -    luaL_error(L, "Signal number %i out of range", sig);
    1.60 -  }
    1.61 -  if (moonbr_io_signalfd_read(sig) < 0) {
    1.62 -    if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, moonbr_io_signalfds+2*sig)) {
    1.63 -      luaL_error(L, "Could not create socket pair for signal queueing");
    1.64 -    }
    1.65 -  }
    1.66 -  errno = 0;
    1.67 -  signal(sig, moonbr_io_signalhandler);
    1.68 -  if (errno) luaL_error(L, "Could not install signal handler (invalid signal number %i?)", sig);
    1.69 -  lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKETS_REGKEY);
    1.70 -  lua_pushinteger(L, sig);
    1.71 -  lua_gettable(L, -2);
    1.72 -  if (!lua_isnil(L, -1)) return 1;
    1.73 -  fd = dup(moonbr_io_signalfd_read(sig));  /* avoid close on Lua error */
    1.74 -  if (fd < 0) luaL_error(L, "Could not create duplicated file descriptor for signal socket");
    1.75 -  moonbr_io_pushhandle(L, fd);
    1.76 -  lua_pushinteger(L, sig);
    1.77 -  lua_pushvalue(L, -2);
    1.78 -  lua_settable(L, -5);  /* store reference to signal socket in cache table */
    1.79 +int moonbr_io_sigterm_setup(lua_State *L) {
    1.80 +  signal(SIGTERM, moonbr_io_sigterm_handler);
    1.81 +  return 0;
    1.82 +}
    1.83 +
    1.84 +static int moonbr_io_sigterm_received(lua_State *L) {
    1.85 +  lua_pushboolean(L, moonbr_io_sigterm_flag);
    1.86    return 1;
    1.87  }
    1.88  
    1.89 @@ -1712,7 +1677,10 @@
    1.90    int fd, isnum;
    1.91    int nfds = 0;
    1.92    fd_set readfds, writefds, exceptfds;
    1.93 -  struct timeval timeout = {0, };
    1.94 +  struct timespec timeout = {0, };
    1.95 +  int use_timeout = 0;
    1.96 +  int check_sigterm = 0;
    1.97 +  sigset_t mask, orig_mask;
    1.98    int status;
    1.99    FD_ZERO(&readfds);
   1.100    FD_ZERO(&writefds);
   1.101 @@ -1784,13 +1752,31 @@
   1.102        return 2;
   1.103      } else if (isnum && n>=0 && n<100000000) {
   1.104        timeout.tv_sec = n;
   1.105 -      timeout.tv_usec = 1e6 * (n - timeout.tv_sec);
   1.106 +      timeout.tv_nsec = 1e9 * (n - timeout.tv_sec);
   1.107      } else {
   1.108        luaL_argcheck(L, 0, 3, "not a valid timeout");
   1.109      }
   1.110 -    status = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
   1.111 -  } else {
   1.112 -    status = select(nfds, &readfds, &writefds, &exceptfds, NULL);
   1.113 +    use_timeout = 1;
   1.114 +  }
   1.115 +  if (!lua_isnoneornil(L, 4)) luaL_checktype(L, 4, LUA_TBOOLEAN);
   1.116 +  check_sigterm = lua_toboolean(L, 4);
   1.117 +  if (check_sigterm) {
   1.118 +    sigemptyset(&mask);
   1.119 +    sigaddset(&mask, SIGTERM);
   1.120 +    sigprocmask(SIG_BLOCK, &mask, &orig_mask);
   1.121 +    if (moonbr_io_sigterm_flag) {
   1.122 +      if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort();
   1.123 +      lua_pushboolean(L, 0);
   1.124 +      lua_pushliteral(L, "SIGTERM received");
   1.125 +      return 2;
   1.126 +    }
   1.127 +  }
   1.128 +  status = pselect(nfds, &readfds, &writefds, &exceptfds, use_timeout ? &timeout : NULL, check_sigterm ? &orig_mask : NULL);
   1.129 +  if (sigprocmask(SIG_SETMASK, &orig_mask, NULL)) abort();
   1.130 +  if (moonbr_io_sigterm_flag) {
   1.131 +    lua_pushboolean(L, 0);
   1.132 +    lua_pushliteral(L, "SIGTERM received");
   1.133 +    return 2;
   1.134    }
   1.135    if (status == -1) {
   1.136      if (errno == EINTR) {
   1.137 @@ -2026,7 +2012,8 @@
   1.138    {"locallisten", moonbr_io_locallisten},
   1.139    {"tcplisten", moonbr_io_tcplisten},
   1.140    {"exec", moonbr_io_exec},
   1.141 -  {"signalsocket", moonbr_io_signalsocket},
   1.142 +  {"sigterm_setup", moonbr_io_sigterm_setup},
   1.143 +  {"sigterm_received", moonbr_io_sigterm_received},
   1.144    {"getpid", moonbr_io_getpid},
   1.145    {"poll", moonbr_io_poll},
   1.146    {"timeref", moonbr_io_timeref},
   1.147 @@ -2048,13 +2035,6 @@
   1.148  int luaopen_moonbridge_io(lua_State *L) {
   1.149  
   1.150    signal(SIGPIPE, SIG_IGN);  /* generate I/O errors instead of signal 13 */
   1.151 -  {
   1.152 -    int i;
   1.153 -    for (i=0; i<=MOONBR_IO_MAXSIGNUM; i++) {
   1.154 -      moonbr_io_signalfd_read(i) = -1;
   1.155 -      moonbr_io_signalfd_write(i) = -1;
   1.156 -    }
   1.157 -  }
   1.158  
   1.159    lua_newtable(L);  // module
   1.160  
   1.161 @@ -2132,9 +2112,6 @@
   1.162    lua_setfield(L, -3, "signals");
   1.163    lua_setfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALS_REGKEY);
   1.164  
   1.165 -  lua_newtable(L);  // signal sockets
   1.166 -  lua_setfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKETS_REGKEY);
   1.167 -  
   1.168    luaL_setfuncs(L, moonbr_io_module_funcs, 0);
   1.169    return 1;
   1.170  

Impressum / About Us