moonbridge
changeset 278:d4c82c90d244
Make moonbridge_io.signalsocket(...) return a new socket each time it is called
author | jbe |
---|---|
date | Tue Jun 06 20:01:29 2017 +0200 (2017-06-06) |
parents | 4f965eda4c2f |
children | dec24bd2592c |
files | moonbridge_io.c reference.txt |
line diff
1.1 --- a/moonbridge_io.c Tue Jun 06 18:00:30 2017 +0200 1.2 +++ b/moonbridge_io.c Tue Jun 06 20:01:29 2017 +0200 1.3 @@ -55,16 +55,16 @@ 1.4 moonbr_io_return_prepared_errmsg(); \ 1.5 } while (0) 1.6 1.7 -static int moonbr_io_signalfds[2]; 1.8 -#define moonbr_io_signalfd_read moonbr_io_signalfds[0] 1.9 -#define moonbr_io_signalfd_write moonbr_io_signalfds[1] 1.10 +#define MOONBR_IO_MAXSIGNUM 127 1.11 +static int moonbr_io_signalfds[2*(MOONBR_IO_MAXSIGNUM+1)]; 1.12 +#define moonbr_io_signalfd_read(x) moonbr_io_signalfds[2*(x)+0] 1.13 +#define moonbr_io_signalfd_write(x) moonbr_io_signalfds[2*(x)+1] 1.14 1.15 #define MOONBR_IO_HANDLE_MT_REGKEY "moonbridge_io_handle" 1.16 #define MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY "moonbridge_io_handle_public" 1.17 #define MOONBR_IO_LISTENER_MT_REGKEY "moonbridge_io_listener" 1.18 #define MOONBR_IO_CHILD_MT_REGKEY "moonbridge_io_child" 1.19 #define MOONBR_IO_CHILD_PT_REGKEY "moonbridge_io_child_pt" 1.20 -#define MOONBR_IO_SIGNALSOCKET_REGKEY "moonbridge_io_signalsocket" 1.21 #define MOONBR_IO_SIGNALS_REGKEY "moonbridge_io_signals" 1.22 1.23 #ifdef MOONBR_IO_USE_TLS 1.24 @@ -1615,47 +1615,39 @@ 1.25 1.26 static void moonbr_io_signalhandler(int sig) { 1.27 int errno2 = errno; 1.28 - char buf[1] = {sig}; 1.29 - write(moonbr_io_signalfd_write, buf, 1); 1.30 + char buf[1] = {'.'}; 1.31 + write(moonbr_io_signalfd_write(sig), buf, 1); 1.32 errno = errno2; 1.33 } 1.34 1.35 static int moonbr_io_signalsocket(lua_State *L) { 1.36 - int i, argc, sig; 1.37 - if (moonbr_io_signalfd_read < 0) { 1.38 - if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, moonbr_io_signalfds)) { 1.39 - luaL_error(L, "Could not create socket pair for signal queueing"); 1.40 + int sig, fd; 1.41 + if (lua_type(L, 1) == LUA_TSTRING) { 1.42 + lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALS_REGKEY); 1.43 + lua_pushvalue(L, 1); 1.44 + lua_gettable(L, -2); 1.45 + sig = lua_tointeger(L, -1); 1.46 + if (!sig) { 1.47 + lua_pushvalue(L, 1); 1.48 + luaL_error(L, "Unknown signal \"%s\"", lua_tostring(L, 1)); 1.49 } 1.50 + } else { 1.51 + sig = luaL_checkinteger(L, 1); 1.52 } 1.53 - lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALS_REGKEY); 1.54 - lua_insert(L, 1); 1.55 - argc = lua_gettop(L); 1.56 - for (i=2; i<=argc; i++) { 1.57 - if (lua_type(L, i) == LUA_TSTRING) { 1.58 - lua_pushvalue(L, i); 1.59 - lua_gettable(L, 1); 1.60 - sig = lua_tointeger(L, -1); 1.61 - lua_pop(L, 1); 1.62 - if (!sig) { 1.63 - lua_pushvalue(L, i); 1.64 - luaL_error(L, "Unknown signal \"%s\"", lua_tostring(L, i)); 1.65 - } 1.66 - } else { 1.67 - sig = luaL_checkinteger(L, i); 1.68 + if (sig < 1 || sig > MOONBR_IO_MAXSIGNUM) { 1.69 + luaL_error(L, "Signal number %i out of range", sig); 1.70 + } 1.71 + if (moonbr_io_signalfd_read(sig) < 0) { 1.72 + if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, moonbr_io_signalfds+2*sig)) { 1.73 + luaL_error(L, "Could not create socket pair for signal queueing"); 1.74 } 1.75 errno = 0; 1.76 signal(sig, moonbr_io_signalhandler); 1.77 - if (errno) luaL_error(L, "Could not install signal handler (invalid signal number?)"); 1.78 + if (errno) luaL_error(L, "Could not install signal handler (invalid signal number %i?)", sig); 1.79 } 1.80 - lua_settop(L, 0); 1.81 - lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKET_REGKEY); 1.82 - if (lua_isnil(L, -1)) { 1.83 - int fd = dup(moonbr_io_signalfd_read); /* TODO: determine how mooonbr_io_pushhandle acts in case of error */ 1.84 - if (fd < 0) luaL_error(L, "Error in dup() system call"); 1.85 - moonbr_io_pushhandle(L, fd); 1.86 - lua_pushvalue(L, -1); 1.87 - lua_setfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKET_REGKEY); 1.88 - } 1.89 + fd = dup(moonbr_io_signalfd_read(sig)); 1.90 + if (fd < 0) luaL_error(L, "Could not create duplicated file descriptor for signal socket"); 1.91 + moonbr_io_pushhandle(L, fd); 1.92 return 1; 1.93 } 1.94 1.95 @@ -2035,8 +2027,13 @@ 1.96 int luaopen_moonbridge_io(lua_State *L) { 1.97 1.98 signal(SIGPIPE, SIG_IGN); /* generate I/O errors instead of signal 13 */ 1.99 - moonbr_io_signalfd_read = -1; 1.100 - moonbr_io_signalfd_write = -1; 1.101 + { 1.102 + int i; 1.103 + for (i=0; i<=MOONBR_IO_MAXSIGNUM; i++) { 1.104 + moonbr_io_signalfd_read(i) = -1; 1.105 + moonbr_io_signalfd_write(i) = -1; 1.106 + } 1.107 + } 1.108 1.109 lua_newtable(L); // module 1.110
2.1 --- a/reference.txt Tue Jun 06 18:00:30 2017 +0200 2.2 +++ b/reference.txt Tue Jun 06 20:01:29 2017 +0200 2.3 @@ -396,16 +396,18 @@ 2.4 number (e.g. 9 or 15, respectively). 2.5 2.6 2.7 -### moonbridge_io.signalsocket(signal1, signal2, ...) 2.8 +### moonbridge_io.signalsocket(signal) 2.9 + 2.10 +This function installs a signal handler. As argument, either the signal number 2.11 +is passed (e.g. 15) or a name (e.g. "TERM"). 2.12 2.13 -This function installs a signal handler for the signals with the numbers passed 2.14 -as arguments and returns a socket which receives a byte for each received 2.15 -signal. Optionally, a string may be used instead of the signal number (e.g. 2.16 -"KILL" instead of 9, or "TERM" instead of 15). 2.17 +The function returns a new socket object that receives a character (".") each 2.18 +time a signal is received. 2.19 2.20 -Subsequent calls of this function can extend the set of signals but will always 2.21 -return the same socket. If the socket is closed, it is no longer possible to 2.22 -detect signals until the process is terminated. 2.23 +Note that each socket object has an independent buffer. It is thus recommended 2.24 +to always read all bytes, e.g. by using the expression: 2.25 + 2.26 +#(assert(sigsock:read_nb())) > 0 -- true if signal occurred 2.27 2.28 2.29 ### moonbridge_io.tcpconnect(hostname, port)