]> git.e2factory.org Git - e2factory.git/commitdiff
Change and extend e2lib.poll() interface
authorTobias Ulmer <tu@emlix.com>
Thu, 16 Jan 2014 17:23:26 +0000 (18:23 +0100)
committerTobias Ulmer <tu@emlix.com>
Wed, 16 Nov 2016 14:41:17 +0000 (15:41 +0100)
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 <tu@emlix.com>
generic/e2lib.lua
generic/le2lib.c

index eb6e54073723f9dffdee36bb997dee42b6f88ffd..3f40738429a2aa2edc145174bc71857e267e06d7 100644 (file)
@@ -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.
index 981f054afee9cdcbdcd291f993d364b368536354..d00070889fbacf5f053c04f954abffe94766f466 100644 (file)
@@ -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;
 }