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