moonbridge

changeset 106:8fce76ef321f

Added moonbridge_io.poll(...)
author jbe
date Wed Apr 08 20:38:18 2015 +0200 (2015-04-08)
parents 11d03470ef19
children 06d965df8a0c
files moonbridge_io.c reference.txt
line diff
     1.1 --- a/moonbridge_io.c	Wed Apr 08 19:37:09 2015 +0200
     1.2 +++ b/moonbridge_io.c	Wed Apr 08 20:38:18 2015 +0200
     1.3 @@ -591,6 +591,82 @@
     1.4    return moonbr_io_tcpconnect_impl(L, 1);
     1.5  }
     1.6  
     1.7 +static int moonbr_io_poll(lua_State *L) {
     1.8 +  moonbr_io_handle_t *handle;
     1.9 +  int fd, isnum;
    1.10 +  int nfds = 0;
    1.11 +  fd_set readfds, writefds, exceptfds;
    1.12 +  struct timeval timeout = {0, };
    1.13 +  int status;
    1.14 +  FD_ZERO(&readfds);
    1.15 +  FD_ZERO(&writefds);
    1.16 +  FD_ZERO(&exceptfds);
    1.17 +  if (!lua_isnoneornil(L, 1)) {
    1.18 +    luaL_checktype(L, 1, LUA_TTABLE);
    1.19 +    for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1)) {
    1.20 +      if (lua_toboolean(L, -1)) {
    1.21 +        handle = luaL_testudata(L, -2, MOONBR_IO_HANDLE_MT_REGKEY);
    1.22 +        if (handle) {
    1.23 +          fd = handle->fd;
    1.24 +          if (fd < 0) luaL_error(L, "Handle in illegal state");
    1.25 +        } else {
    1.26 +          fd = lua_tointegerx(L, -2, &isnum);
    1.27 +          if (!isnum) luaL_error(L, "File descriptor is not an integer");
    1.28 +        }
    1.29 +        FD_SET(fd, &readfds);
    1.30 +        if (fd+1 > nfds) nfds = fd+1;
    1.31 +      }
    1.32 +    }
    1.33 +  }
    1.34 +  if (!lua_isnoneornil(L, 2)) {
    1.35 +    luaL_checktype(L, 2, LUA_TTABLE);
    1.36 +    for (lua_pushnil(L); lua_next(L, 2); lua_pop(L, 1)) {
    1.37 +      if (lua_toboolean(L, -1)) {
    1.38 +        handle = luaL_testudata(L, -2, MOONBR_IO_HANDLE_MT_REGKEY);
    1.39 +        if (handle) {
    1.40 +          fd = handle->fd;
    1.41 +          if (fd < 0) luaL_error(L, "Handle in illegal state");
    1.42 +        } else {
    1.43 +          fd = lua_tointegerx(L, -2, &isnum);
    1.44 +          if (!isnum) luaL_error(L, "File descriptor is not an integer");
    1.45 +        }
    1.46 +        FD_SET(fd, &writefds);
    1.47 +        if (fd+1 > nfds) nfds = fd+1;
    1.48 +      }
    1.49 +    }
    1.50 +  }
    1.51 +  if (!lua_isnoneornil(L, 3)) {
    1.52 +    lua_Number n;
    1.53 +    n = lua_tonumberx(L, 3, &isnum);
    1.54 +    if (isnum && n>=0 && n<100000000) {
    1.55 +      timeout.tv_sec = n;
    1.56 +      timeout.tv_usec = 1e6 * (n - timeout.tv_sec);
    1.57 +    } else {
    1.58 +      luaL_argcheck(L, 0, 3, "not a valid timeout");
    1.59 +    }
    1.60 +    status = select(nfds, &readfds, &writefds, &exceptfds, &timeout);
    1.61 +  } else {
    1.62 +    status = select(nfds, &readfds, &writefds, &exceptfds, NULL);
    1.63 +  }
    1.64 +  if (status == -1) {
    1.65 +    if (errno == EINTR) {
    1.66 +      lua_pushboolean(L, 0);
    1.67 +      lua_pushliteral(L, "Signal received while polling file descriptors");
    1.68 +      return 2;
    1.69 +    } else {
    1.70 +      moonbr_io_errmsg();
    1.71 +      return luaL_error(L, "Unexpected error during \"select\" system call: %s", errmsg);
    1.72 +    }
    1.73 +  } else if (status == 0) {
    1.74 +    lua_pushboolean(L, 0);
    1.75 +    lua_pushliteral(L, "Timeout while polling file descriptors");
    1.76 +    return 2;
    1.77 +  } else {
    1.78 +    lua_pushboolean(L, 1);
    1.79 +    return 1;
    1.80 +  }
    1.81 +}
    1.82 +
    1.83  static const struct luaL_Reg moonbr_io_handle_methods[] = {
    1.84    {"read", moonbr_io_read},
    1.85    {"read_nb", moonbr_io_read_nb},
    1.86 @@ -616,6 +692,7 @@
    1.87  static const struct luaL_Reg moonbr_io_module_funcs[] = {
    1.88    {"tcpconnect", moonbr_io_tcpconnect},
    1.89    {"tcpconnect_nb", moonbr_io_tcpconnect_nb},
    1.90 +  {"poll", moonbr_io_poll},
    1.91    {NULL, NULL}
    1.92  };
    1.93  
     2.1 --- a/reference.txt	Wed Apr 08 19:37:09 2015 +0200
     2.2 +++ b/reference.txt	Wed Apr 08 20:38:18 2015 +0200
     2.3 @@ -236,6 +236,19 @@
     2.4  library to support blocking as well as nonblocking I/O operations.
     2.5  
     2.6  
     2.7 +### moonbridge_io.poll(input_set, output_set, timeout)
     2.8 +
     2.9 +This function waits for at least one of the given file descriptors and/or
    2.10 +I/O handles to be ready for input or output. The two sets of file descriptors
    2.11 +and/or handles must contain the file descriptor or handle as a key, and a value
    2.12 +which does evaluate to true. If a set is nil, it is treated as being empty.
    2.13 +
    2.14 +Returns true when at least one file descriptor or handle is ready for reading
    2.15 +or writing respectively. Returns false (as first return value) plus a status
    2.16 +message (as second return value) in case of timeout or when a signal was
    2.17 +received.
    2.18 +
    2.19 +
    2.20  ### moonbridge_io.tcpconnect(hostname, port)
    2.21  
    2.22  Tries to open a TCP connection with the given host and TCP port number. Returns

Impressum / About Us