[vlc-devel] commit: Add vlc.net.poll() and use in modules/host.lua. (Antoine Cellerier )

git version control git at videolan.org
Sat Jan 9 01:49:48 CET 2010


vlc | branch: master | Antoine Cellerier <dionoea at videolan.org> | Sat Jan  9 01:49:54 2010 +0100| [8bbd4a3154744c8604da6940356aef508c214586] | committer: Antoine Cellerier 

Add vlc.net.poll() and use in modules/host.lua.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8bbd4a3154744c8604da6940356aef508c214586
---

 modules/misc/lua/libs/net.c     |   49 ++++++++++++++++++++++++++++++++++++++-
 share/lua/README.txt            |    7 ++++-
 share/lua/intf/modules/host.lua |   45 ++++++++++++++---------------------
 3 files changed, 71 insertions(+), 30 deletions(-)

diff --git a/modules/misc/lua/libs/net.c b/modules/misc/lua/libs/net.c
index f714e86..fa6e081 100644
--- a/modules/misc/lua/libs/net.c
+++ b/modules/misc/lua/libs/net.c
@@ -125,7 +125,6 @@ static int vlclua_net_listen_close( lua_State *L )
 
 static int vlclua_net_fds( lua_State *L )
 {
-    vlc_object_t *p_this = vlclua_get_this( L );
     int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
     int *pi_fd = *ppi_fd;
 
@@ -208,6 +207,43 @@ static int vlclua_net_recv( lua_State *L )
 /*****************************************************************************
  *
  *****************************************************************************/
+/* Takes a { fd : events } table as first arg and modifies it to { fd : revents } */
+static int vlclua_net_poll( lua_State *L )
+{
+    luaL_checktype( L, 1, LUA_TTABLE );
+    double f_timeout = luaL_optnumber( L, 2, -1. );
+
+    int i_fds = 0;
+    lua_pushnil( L );
+    while( lua_next( L, 1 ) )
+    {
+        i_fds++;
+        lua_pop( L, 1 );
+    }
+    struct pollfd *p_fds = malloc( i_fds * sizeof( struct pollfd ) );
+    lua_pushnil( L );
+    int i = 0;
+    while( lua_next( L, 1 ) )
+    {
+        p_fds[i].fd = luaL_checkinteger( L, -2 );
+        p_fds[i].events = luaL_checkinteger( L, -1 );
+        p_fds[i].revents = 0;
+        lua_pop( L, 1 );
+        i++;
+    }
+
+    int i_ret = poll( p_fds, i_fds, f_timeout < 0. ? -1 : (int)(f_timeout*1000) );
+    for( i = 0; i < i_fds; i++ )
+    {
+        lua_pushinteger( L, p_fds[i].fd );
+        lua_pushinteger( L, p_fds[i].revents );
+        lua_settable( L, 1 );
+    }
+    free( p_fds );
+    lua_pushinteger( L, i_ret );
+    return 1;
+}
+
 static int vlclua_net_select( lua_State *L )
 {
     int i_ret;
@@ -423,6 +459,7 @@ static const luaL_Reg vlclua_net_reg[] = {
     { "close", vlclua_net_close },
     { "send", vlclua_net_send },
     { "recv", vlclua_net_recv },
+    { "poll", vlclua_net_poll },
     { "select", vlclua_net_select },
     { "fd_set_new", vlclua_fd_set_new },
     { "read", vlclua_fd_read },
@@ -436,5 +473,15 @@ void luaopen_net( lua_State *L )
 {
     lua_newtable( L );
     luaL_register( L, NULL, vlclua_net_reg );
+#define ADD_CONSTANT( name, value )    \
+    lua_pushinteger( L, value ); \
+    lua_setfield( L, -2, name );
+    ADD_CONSTANT( "POLLIN", POLLIN )
+    ADD_CONSTANT( "POLLPRI", POLLPRI )
+    ADD_CONSTANT( "POLLOUT", POLLOUT )
+    ADD_CONSTANT( "POLLRDHUP", POLLRDHUP )
+    ADD_CONSTANT( "POLLERR", POLLERR )
+    ADD_CONSTANT( "POLLHUP", POLLHUP )
+    ADD_CONSTANT( "POLLNVAL", POLLNVAL )
     lua_setfield( L, -2, "net" );
 }
diff --git a/share/lua/README.txt b/share/lua/README.txt
index e8e279b..bcafa1b 100644
--- a/share/lua/README.txt
+++ b/share/lua/README.txt
@@ -126,9 +126,12 @@ end
 net.close( fd ): Close file descriptor.
 net.send( fd, string, [length] ): Send data on fd.
 net.recv( fd, [max length] ): Receive data from fd.
+net.poll( { fd = events }, [timeout in seconds] ): Implement poll function.
+  Retruns the numbers of file descriptors with a non 0 revent. The function
+  modifies the input table to { fd = revents }. See "man poll".
+net.POLLIN/POLLPRI/POLLOUT/POLLRDHUP/POLLERR/POLLHUP/POLLNVAL: poll event flags
 net.select( nfds, fds_read, fds_write, timeout ): Monitor a bunch of file
-  descriptors. Returns number of fds to handle and the amount of time not
-  slept. See "man select".
+  descriptors. Returns number of fds to handle. See "man select".
 net.fd_set_new(): Create a new fd_set.
 local fds = vlc.net.fd_set_new()
 fds:clr( fd ) -- remove fd from set
diff --git a/share/lua/intf/modules/host.lua b/share/lua/intf/modules/host.lua
index 747ff45..5f3da6c 100644
--- a/share/lua/intf/modules/host.lua
+++ b/share/lua/intf/modules/host.lua
@@ -72,10 +72,6 @@ function host()
     local listeners = {}
     local status_callbacks = {}
 
-    -- private data
-    local fds_read = vlc.net.fd_set_new()
-    local fds_write = vlc.net.fd_set_new()
-
     -- private methods
     local function fd_client( client )
         if client.status == status.read then
@@ -177,18 +173,6 @@ function host()
         client:switch_status(status.password)
     end
 
-    function filter_client( fd, status, status2 )
-        local l = 0
-        fd:zero()
-        for _, client in pairs(clients) do
-            if client.status == status or client.status == status2 then
-                fd:set( client:fd() )
-                l = math.max( l, client:fd() )
-            end
-        end
-        return l
-    end
-
     -- public methods
     local function _listen_tcp( h, host, port )
         if listeners.tcp and listeners.tcp[host]
@@ -238,36 +222,42 @@ function host()
     end
 
     local function _accept_and_select( h, timeout )
-        local nfds = math.max( filter_client( fds_read, status.read, status.password ),
-                               filter_client( fds_write, status.write ) ) + 1
+        local function filter_client( fds, status, event )
+            for _, client in pairs(clients) do
+                if client.status == status then
+                    fds[client:fd()] = event
+                end
+            end
+        end
+
+        local pollfds = {}
+        filter_client( pollfds, status.read, vlc.net.POLLIN )
+        filter_client( pollfds, status.password, vlc.net.POLLIN )
+        filter_client( pollfds, status.write, vlc.net.POLLOUT )
         if listeners.tcp then
             for _, listener in pairs(listeners.tcp.list) do
                 for _, fd in pairs({listener:fds()}) do
-                    fds_read:set(fd)
-                    if fd >= nfds then
-                        nfds = fd + 1
-                    end
+                    pollfds[fd] = vlc.net.POLLIN
                 end
             end
         end
 
-        local ret = vlc.net.select( nfds, fds_read, fds_write,
-                                    timeout or -1 )
+        local ret = vlc.net.poll( pollfds, timeout or -1 )
         local wclients = {}
         local rclients = {}
         if ret > 0 then
             for _, client in pairs(clients) do
-                if fds_write:isset( client:fd() ) then
+                if pollfds[client:fd()] == vlc.net.POLLOUT then
                     table.insert(wclients,client)
                 end
-                if fds_read:isset( client:fd() ) then
+                if pollfds[client:fd()] == vlc.net.POLLIN then
                     table.insert(rclients,client)
                 end
             end
             if listeners.tcp then
                 for _, listener in pairs(listeners.tcp.list) do
                     for _, fd in pairs({listener:fds()}) do
-                        if fds_read:isset(fd) then
+                        if pollfds[fd] == vlc.net.POLLIN then
                             local afd = listener:accept(0)
                             new_client( h, afd, afd, client_type.net )
                             break
@@ -276,6 +266,7 @@ function host()
                 end
             end
         end
+
         return wclients, rclients
     end
 




More information about the vlc-devel mailing list