mirror of
https://code.videolan.org/videolan/vlc
synced 2024-08-31 06:46:39 +02:00
Add vlc.net.poll() and use in modules/host.lua.
This commit is contained in:
parent
92432bcb27
commit
8bbd4a3154
@ -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" );
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
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
|
||||
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 ret = vlc.net.select( nfds, fds_read, fds_write,
|
||||
timeout or -1 )
|
||||
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
|
||||
pollfds[fd] = vlc.net.POLLIN
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user