From 8bbd4a3154744c8604da6940356aef508c214586 Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sat, 9 Jan 2010 01:49:54 +0100 Subject: [PATCH] Add vlc.net.poll() and use in modules/host.lua. --- 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 f714e86763..fa6e081197 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 e8e279b2f9..bcafa1b8b9 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 747ff45b3a..5f3da6c39c 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 -- 2.39.2