moonbridge

changeset 266:48ffca6443d9

Added moonbridge_io.signalsocket(...) and moonbridge_io.getpid() functions; poll returns true on signal interruption (instead of nil)
author jbe
date Sun Jun 04 16:40:46 2017 +0200 (2017-06-04)
parents 37aaca00941c
children 5f437005e2ef
files moonbridge_io.c reference.txt
line diff
     1.1 --- a/moonbridge_io.c	Sun Jun 04 13:49:12 2017 +0200
     1.2 +++ b/moonbridge_io.c	Sun Jun 04 16:40:46 2017 +0200
     1.3 @@ -55,11 +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 +
    1.11  #define MOONBR_IO_HANDLE_MT_REGKEY "moonbridge_io_handle"
    1.12  #define MOONBR_IO_HANDLE_PUBLIC_MT_REGKEY "moonbridge_io_handle_public"
    1.13  #define MOONBR_IO_LISTENER_MT_REGKEY "moonbridge_io_listener"
    1.14  #define MOONBR_IO_CHILD_MT_REGKEY "moonbridge_io_child"
    1.15  #define MOONBR_IO_CHILD_PT_REGKEY "moonbridge_io_child_pt"
    1.16 +#define MOONBR_IO_SIGNALSOCKET_REGKEY "moonbridge_io_signalsocket"
    1.17  
    1.18  #ifdef MOONBR_IO_USE_TLS
    1.19  
    1.20 @@ -1607,6 +1612,44 @@
    1.21  
    1.22  moonbr_io_yield_wrapper(moonbr_io_wait_yield, moonbr_io_wait_call);
    1.23  
    1.24 +static void moonbr_io_signalhandler(int sig) {
    1.25 +  int errno2 = errno;
    1.26 +  char buf[1] = {sig};
    1.27 +  write(moonbr_io_signalfd_write, buf, 1);
    1.28 +  errno = errno2;
    1.29 +}
    1.30 +
    1.31 +static int moonbr_io_signalsocket(lua_State *L) {
    1.32 +  int i, argc, sig;
    1.33 +  if (moonbr_io_signalfd_read < 0) {
    1.34 +    if (socketpair(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, moonbr_io_signalfds)) {
    1.35 +      luaL_error(L, "Could not create socket pair for signal queueing");
    1.36 +    }
    1.37 +  }
    1.38 +  argc = lua_gettop(L);
    1.39 +  for (i=1; i<=argc; i++) {
    1.40 +    sig = luaL_checkinteger(L, i);
    1.41 +    errno = 0;
    1.42 +    signal(sig, moonbr_io_signalhandler);
    1.43 +    if (errno) luaL_error(L, "Could not install signal handler (invalid signal number?)");
    1.44 +  }
    1.45 +  lua_settop(L, 0);
    1.46 +  lua_getfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKET_REGKEY);
    1.47 +  if (lua_isnil(L, -1)) {
    1.48 +    int fd = dup(moonbr_io_signalfd_read);  /* TODO: determine how mooonbr_io_pushhandle acts in case of error */
    1.49 +    if (fd < 0) luaL_error(L, "Error in dup() system call");
    1.50 +    moonbr_io_pushhandle(L, fd);
    1.51 +    lua_pushvalue(L, -1);
    1.52 +    lua_setfield(L, LUA_REGISTRYINDEX, MOONBR_IO_SIGNALSOCKET_REGKEY);
    1.53 +  }
    1.54 +  return 1;
    1.55 +}
    1.56 +
    1.57 +static int moonbr_io_getpid(lua_State *L) {
    1.58 +  lua_pushinteger(L, getpid());
    1.59 +  return 1;
    1.60 +}
    1.61 +
    1.62  #ifdef MOONBR_IO_USE_TLS
    1.63  
    1.64  #define moonbr_io_poll_tls() \
    1.65 @@ -1724,9 +1767,8 @@
    1.66    }
    1.67    if (status == -1) {
    1.68      if (errno == EINTR) {
    1.69 -      lua_pushnil(L);
    1.70 -      lua_pushliteral(L, "Signal received while polling file descriptors");
    1.71 -      return 2;
    1.72 +      lua_pushboolean(L, 1);
    1.73 +      return 1;
    1.74      } else {
    1.75        moonbr_io_prepare_errmsg();
    1.76        return luaL_error(L, "Unexpected error during \"select\" system call: %s", errmsg);
    1.77 @@ -1957,6 +1999,8 @@
    1.78    {"locallisten", moonbr_io_locallisten},
    1.79    {"tcplisten", moonbr_io_tcplisten},
    1.80    {"exec", moonbr_io_exec},
    1.81 +  {"signalsocket", moonbr_io_signalsocket},
    1.82 +  {"getpid", moonbr_io_getpid},
    1.83    {"poll", moonbr_io_poll},
    1.84    {"timeref", moonbr_io_timeref},
    1.85  #ifdef MOONBR_IO_USE_TLS
    1.86 @@ -1977,6 +2021,8 @@
    1.87  int luaopen_moonbridge_io(lua_State *L) {
    1.88  
    1.89    signal(SIGPIPE, SIG_IGN);  /* generate I/O errors instead of signal 13 */
    1.90 +  moonbr_io_signalfd_read = -1;
    1.91 +  moonbr_io_signalfd_write = -1;
    1.92  
    1.93    lua_newtable(L);  // module
    1.94  
     2.1 --- a/reference.txt	Sun Jun 04 13:49:12 2017 +0200
     2.2 +++ b/reference.txt	Sun Jun 04 16:40:46 2017 +0200
     2.3 @@ -386,9 +386,19 @@
     2.4  nil, it is treated as being empty.
     2.5  
     2.6  Returns true when at least one file descriptor or handle is ready for reading
     2.7 -or writing respectively. Returns false (plus a notice as second return value)
     2.8 -in case of timeout. Returns nil (plus a notice as second return value) if a
     2.9 -signal was received during waiting.
    2.10 +or writing respectively, or if a signal has been received during waiting.
    2.11 +Returns false (plus a notice as second return value) in case of timeout.
    2.12 +
    2.13 +
    2.14 +### moonbridge_io.signalsocket(signal, ...)
    2.15 +
    2.16 +This function installs a signal handler for the signals with the numbers passed
    2.17 +as arguments and returns a socket which receives a byte for each received
    2.18 +signal.
    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  
    2.24  
    2.25  ### moonbridge_io.tcpconnect(hostname, port)

Impressum / About Us