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