From: Tobias Ulmer Date: Thu, 16 Jan 2014 17:23:26 +0000 (+0100) Subject: Change and extend e2lib.poll() interface X-Git-Tag: e2factory-2.3.15rc1~260 X-Git-Url: https://git.e2factory.org/?a=commitdiff_plain;h=ac4994e5943bbdb1adde6feb0f8d02ff48295550;p=e2factory.git Change and extend e2lib.poll() interface Instead of a single pos in the fdvec table, return a table of all selected file descriptors. Allows handling more than one active file descriptor in one go. Signed-off-by: Tobias Ulmer --- diff --git a/generic/e2lib.lua b/generic/e2lib.lua index eb6e540..3f40738 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -213,16 +213,27 @@ function e2lib.wait(pid) return rc, childpid, sig end ---- Poll input output multiplexing. --- Only indicates first selected file descriptor. +--- Poll input output multiplexing. See poll(2) for details on flags etc. -- @param timeout Timeout in milliseconds (number). --- @param fdvec Vector of file descriptors (table of numbers). --- @return Returns 0 on timeout, < 0 on error and > 0 for the position in fdvec --- that has an event waiting. --- @return True if it's a POLLIN event. --- @return True if it's a POLLOUT event. +-- @param fdvec Vector of file descriptors. This wrapper listens for +-- POLLIN and POLLOUT events on every fd. +-- @return False on error, empty table on timeout, or a vector of tables for +-- each selected file descriptor. The tables looks like this: +-- { fd=(file descriptor number), fdvecpos=(index number), +-- POLLIN=boolean, POLLOUT=boolean }. +-- If a file descriptor is selected but neither POLLIN nor POLLOUT are +-- set, the file descriptor was closed. fdvecpos is the position of the +-- fd in the fdvec table. +-- @return Error object on failure. function e2lib.poll(timeout, fdvec) - return le2lib.poll(timeout, fdvec) + local pollvec, errstring + + pollvec, errstring = le2lib.poll(timeout, fdvec) + if not pollvec then + return false, err.new("poll() failed: %s", errstring) + end + + return pollvec end --- Set file descriptor in non-blocking mode. diff --git a/generic/le2lib.c b/generic/le2lib.c index 981f054..d000708 100644 --- a/generic/le2lib.c +++ b/generic/le2lib.c @@ -315,7 +315,7 @@ static int poll_fd(lua_State *lua) { int tmo = luaL_checkinteger(lua, 1); - int nfds = 0, f; + int nfds = 0, f, index = 0; struct pollfd *fds = NULL; luaL_checktype(lua, 2, LUA_TTABLE); @@ -334,20 +334,49 @@ poll_fd(lua_State *lua) nfds += 1; } f = poll(fds, nfds, tmo); + if (f < 0) { + lua_pushboolean(lua, 0); + lua_pushstring(lua, strerror(errno)); + return 2; + } - if (f > 0) { - while (--nfds >= 0) { - if (fds[nfds].revents) { - lua_pushnumber(lua, nfds+1); - lua_pushboolean(lua, fds[nfds].revents & POLLIN); - lua_pushboolean(lua, fds[nfds].revents & POLLOUT); - free(fds); - return 3; - } + /* We want to return a table containing all selected fds looking like + * this: + * { + * { fd = 3, fdvecpos=1, POLLIN = true, POLLOUT = false }, + * { fd = 5, fdvecpos=2, POLLIN = false, POLLOUT = false }, + * ... + * } + */ + + lua_newtable(lua); + + while (index < f && --nfds >= 0) { + if (fds[nfds].revents) { + lua_createtable(lua, 0, 4); /* 4 elements */ + + lua_pushliteral(lua, "fd"); + lua_pushnumber(lua, fds[nfds].fd); + lua_rawset(lua, -3); + + lua_pushliteral(lua, "fdvecpos"); + lua_pushnumber(lua, nfds+1); + lua_rawset(lua, -3); + + lua_pushliteral(lua, "POLLIN"); + lua_pushboolean(lua, fds[nfds].revents & POLLIN); + lua_rawset(lua, -3); + + lua_pushliteral(lua, "POLLOUT"); + lua_pushboolean(lua, fds[nfds].revents & POLLOUT); + lua_rawset(lua, -3); + + /* commit table to newtable at index */ + lua_rawseti(lua, -2, ++index); } } + free(fds); - lua_pushnumber(lua, f); return 1; }