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 +  int sig, fd;
    1.40 +  if (lua_type(L, 1) == LUA_TSTRING) {
    1.41 +    lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALS_REGKEY);
    1.42 +    lua_pushvalue(L, 1);
    1.43 +    lua_gettable(L, -2);
    1.44 +    sig = lua_tointeger(L, -1);
    1.45 +    if (!sig) {
    1.46 +      lua_pushvalue(L, 1);
    1.47 +      luaL_error(L, "Unknown signal \"%s\"", lua_tostring(L, 1));
    1.48 +    }
    1.49 +  } else {
    1.50 +    sig = luaL_checkinteger(L, 1);
    1.51 +  }
    1.52 +  if (sig < 1 || sig > MOONBR_IO_MAXSIGNUM) {
    1.53 +    luaL_error(L, "Signal number %i out of range", sig);
    1.54 +  }
    1.55 +  if (moonbr_io_signalfd_read(sig) < 0) {
    1.56 +    if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, moonbr_io_signalfds+2*sig)) {
    1.57        luaL_error(L, "Could not create socket pair for signal queueing");
    1.58      }
    1.59 -  }
    1.60 -  lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALS_REGKEY);
    1.61 -  lua_insert(L, 1);
    1.62 -  argc = lua_gettop(L);
    1.63 -  for (i=2; i<=argc; i++) {
    1.64 -    if (lua_type(L, i) == LUA_TSTRING) {
    1.65 -      lua_pushvalue(L, i);
    1.66 -      lua_gettable(L, 1);
    1.67 -      sig = lua_tointeger(L, -1);
    1.68 -      lua_pop(L, 1);
    1.69 -      if (!sig) {
    1.70 -        lua_pushvalue(L, i);
    1.71 -        luaL_error(L, "Unknown signal \"%s\"", lua_tostring(L, i));
    1.72 -      }
    1.73 -    } else {
    1.74 -      sig = luaL_checkinteger(L, i);
    1.75 -    }
    1.76      errno = 0;
    1.77      signal(sig, moonbr_io_signalhandler);
    1.78 -    if (errno) luaL_error(L, "Could not install signal handler (invalid signal number?)");
    1.79 +    if (errno) luaL_error(L, "Could not install signal handler (invalid signal number %i?)", sig);
    1.80    }
    1.81 -  lua_settop(L, 0);
    1.82 -  lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKET_REGKEY);
    1.83 -  if (lua_isnil(L, -1)) {
    1.84 -    int fd = dup(moonbr_io_signalfd_read);  /* TODO: determine how mooonbr_io_pushhandle acts in case of error */
    1.85 -    if (fd < 0) luaL_error(L, "Error in dup() system call");
    1.86 -    moonbr_io_pushhandle(L, fd);
    1.87 -    lua_pushvalue(L, -1);
    1.88 -    lua_setfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKET_REGKEY);
    1.89 -  }
    1.90 +  fd = dup(moonbr_io_signalfd_read(sig));
    1.91 +  if (fd < 0) luaL_error(L, "Could not create duplicated file descriptor for signal socket");
    1.92 +  moonbr_io_pushhandle(L, fd);
    1.93    return 1;
    1.94  }
    1.95  
    1.96 @@ -2035,8 +2027,13 @@
    1.97  int luaopen_moonbridge_io(lua_State *L) {
    1.98  
    1.99    signal(SIGPIPE, SIG_IGN);  /* generate I/O errors instead of signal 13 */
   1.100 -  moonbr_io_signalfd_read = -1;
   1.101 -  moonbr_io_signalfd_write = -1;
   1.102 +  {
   1.103 +    int i;
   1.104 +    for (i=0; i<=MOONBR_IO_MAXSIGNUM; i++) {
   1.105 +      moonbr_io_signalfd_read(i) = -1;
   1.106 +      moonbr_io_signalfd_write(i) = -1;
   1.107 +    }
   1.108 +  }
   1.109  
   1.110    lua_newtable(L);  // module
   1.111  
     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 for the signals with the numbers passed
    2.11 -as arguments and returns a socket which receives a byte for each received
    2.12 -signal. Optionally, a string may be used instead of the signal number (e.g.
    2.13 -"KILL" instead of 9, or "TERM" instead of 15).
    2.14 +This function installs a signal handler. As argument, either the signal number
    2.15 +is passed (e.g. 15) or a name (e.g. "TERM").
    2.16  
    2.17 -Subsequent calls of this function can extend the set of signals but will always
    2.18 -return the same socket. If the socket is closed, it is no longer possible to
    2.19 -detect signals until the process is terminated.
    2.20 +The function returns a new socket object that receives a character (".") each
    2.21 +time a signal is received.
    2.22 +
    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)

Impressum / About Us