Commit 8bbd4a31 authored by Antoine Cellerier's avatar Antoine Cellerier

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

parent 92432bcb
...@@ -125,7 +125,6 @@ static int vlclua_net_listen_close( lua_State *L ) ...@@ -125,7 +125,6 @@ static int vlclua_net_listen_close( lua_State *L )
static int vlclua_net_fds( 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 **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
int *pi_fd = *ppi_fd; int *pi_fd = *ppi_fd;
...@@ -208,6 +207,43 @@ static int vlclua_net_recv( lua_State *L ) ...@@ -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 ) static int vlclua_net_select( lua_State *L )
{ {
int i_ret; int i_ret;
...@@ -423,6 +459,7 @@ static const luaL_Reg vlclua_net_reg[] = { ...@@ -423,6 +459,7 @@ static const luaL_Reg vlclua_net_reg[] = {
{ "close", vlclua_net_close }, { "close", vlclua_net_close },
{ "send", vlclua_net_send }, { "send", vlclua_net_send },
{ "recv", vlclua_net_recv }, { "recv", vlclua_net_recv },
{ "poll", vlclua_net_poll },
{ "select", vlclua_net_select }, { "select", vlclua_net_select },
{ "fd_set_new", vlclua_fd_set_new }, { "fd_set_new", vlclua_fd_set_new },
{ "read", vlclua_fd_read }, { "read", vlclua_fd_read },
...@@ -436,5 +473,15 @@ void luaopen_net( lua_State *L ) ...@@ -436,5 +473,15 @@ void luaopen_net( lua_State *L )
{ {
lua_newtable( L ); lua_newtable( L );
luaL_register( L, NULL, vlclua_net_reg ); 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" ); lua_setfield( L, -2, "net" );
} }
...@@ -126,9 +126,12 @@ end ...@@ -126,9 +126,12 @@ end
net.close( fd ): Close file descriptor. net.close( fd ): Close file descriptor.
net.send( fd, string, [length] ): Send data on fd. net.send( fd, string, [length] ): Send data on fd.
net.recv( fd, [max length] ): Receive data from 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 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 descriptors. Returns number of fds to handle. See "man select".
slept. See "man select".
net.fd_set_new(): Create a new fd_set. net.fd_set_new(): Create a new fd_set.
local fds = vlc.net.fd_set_new() local fds = vlc.net.fd_set_new()
fds:clr( fd ) -- remove fd from set fds:clr( fd ) -- remove fd from set
......
...@@ -72,10 +72,6 @@ function host() ...@@ -72,10 +72,6 @@ function host()
local listeners = {} local listeners = {}
local status_callbacks = {} local status_callbacks = {}
-- private data
local fds_read = vlc.net.fd_set_new()
local fds_write = vlc.net.fd_set_new()
-- private methods -- private methods
local function fd_client( client ) local function fd_client( client )
if client.status == status.read then if client.status == status.read then
...@@ -177,18 +173,6 @@ function host() ...@@ -177,18 +173,6 @@ function host()
client:switch_status(status.password) client:switch_status(status.password)
end 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 -- public methods
local function _listen_tcp( h, host, port ) local function _listen_tcp( h, host, port )
if listeners.tcp and listeners.tcp[host] if listeners.tcp and listeners.tcp[host]
...@@ -238,36 +222,42 @@ function host() ...@@ -238,36 +222,42 @@ function host()
end end
local function _accept_and_select( h, timeout ) local function _accept_and_select( h, timeout )
local nfds = math.max( filter_client( fds_read, status.read, status.password ), local function filter_client( fds, status, event )
filter_client( fds_write, status.write ) ) + 1 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 if listeners.tcp then
for _, listener in pairs(listeners.tcp.list) do for _, listener in pairs(listeners.tcp.list) do
for _, fd in pairs({listener:fds()}) do for _, fd in pairs({listener:fds()}) do
fds_read:set(fd) pollfds[fd] = vlc.net.POLLIN
if fd >= nfds then
nfds = fd + 1
end
end end
end end
end end
local ret = vlc.net.select( nfds, fds_read, fds_write, local ret = vlc.net.poll( pollfds, timeout or -1 )
timeout or -1 )
local wclients = {} local wclients = {}
local rclients = {} local rclients = {}
if ret > 0 then if ret > 0 then
for _, client in pairs(clients) do 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) table.insert(wclients,client)
end end
if fds_read:isset( client:fd() ) then if pollfds[client:fd()] == vlc.net.POLLIN then
table.insert(rclients,client) table.insert(rclients,client)
end end
end end
if listeners.tcp then if listeners.tcp then
for _, listener in pairs(listeners.tcp.list) do for _, listener in pairs(listeners.tcp.list) do
for _, fd in pairs({listener:fds()}) 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) local afd = listener:accept(0)
new_client( h, afd, afd, client_type.net ) new_client( h, afd, afd, client_type.net )
break break
...@@ -276,6 +266,7 @@ function host() ...@@ -276,6 +266,7 @@ function host()
end end
end end
end end
return wclients, rclients return wclients, rclients
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment