*****************************************************************************/
static int vlclua_net_listen_close( lua_State * );
static int vlclua_net_accept( lua_State * );
+static int vlclua_net_fds( lua_State * );
static const luaL_Reg vlclua_net_listen_reg[] = {
{ "accept", vlclua_net_accept },
+ { "fds", vlclua_net_fds },
{ NULL, NULL }
};
return 0;
}
+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;
+
+ int i_count = 0;
+ while( pi_fd[i_count] != -1 )
+ lua_pushinteger( L, pi_fd[i_count++] );
+
+ return i_count;
+}
+
static int vlclua_net_accept( lua_State *L )
{
vlc_object_t *p_this = vlclua_get_this( L );
if( i_nfds > FD_SETSIZE )
i_nfds = FD_SETSIZE;
#endif
- timeout.tv_sec = (int)f_timeout;
- timeout.tv_usec = (int)(1e6*(f_timeout-(double)((int)f_timeout)));
- i_ret = select( i_nfds, fds_read, fds_write, 0, &timeout );
+ if( f_timeout >= 0. )
+ {
+ timeout.tv_sec = (int)f_timeout;
+ timeout.tv_usec = (int)(1e6*(f_timeout-(double)((int)f_timeout)));
+ }
+ i_ret = select( i_nfds, fds_read, fds_write, 0, f_timeout >= 0. ? &timeout : NULL );
lua_pushinteger( L, i_ret );
- lua_pushinteger( L, (double)timeout.tv_sec+((double)timeout.tv_usec)/1e-6 );
- return 2;
+ return 1;
}
/*****************************************************************************
fields "protocol", "username", "password", "host", "port", path" and
"option".
net.listen_tcp( host, port ): Listen to TCP connections. This returns an
- object with an accept method. This method takes an optional timeout
- argument (in milliseconds). For example:
+ object with an accept and an fds method. The accept takes an optional timeout
+ argument (in milliseconds). The fds method returns a list of fds you can call
+ select on before using the accept method. For example:
local l = vlc.net.listen_tcp( "localhost", 1234 )
while true do
local fd = l:accept( 500 )
-- The main loop
while not vlc.misc.should_die() do
- -- accept new connections
- h:accept()
-
- -- select active clients
- local write, read = h:select( 0.1 ) -- 0.1 is a timeout in seconds
+ -- accept new connections and select active clients
+ local write, read = h:accept_and_select()
-- handle clients in write mode
for _, client in pairs(write) do
local fds_write = vlc.net.fd_set_new()
-- private methods
- local function client_accept( clients, listen )
+ --[[local function client_accept( clients, listen )
local wait
if #clients == 0 then
wait = -1
wait = 0
end
return listen:accept( wait )
- end
+ end]]
local function fd_client( client )
if client.status == status.read then
end
end
- local function _accept( h )
+ 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
- local wait
- if #clients == 0 and not listeners.stdio and #listeners.tcp.list == 1 then
- wait = -1 -- blocking
- else
- wait = 0
- end
for _, listener in pairs(listeners.tcp.list) do
- local fd = listener:accept( wait )
- new_client( h, fd, fd, client_type.net )
+ for _, fd in pairs({listener:fds()}) do
+ fds_read:set(fd)
+ if fd >= nfds then
+ nfds = fd + 1
+ end
+ end
end
end
- end
- local function _select( h, timeout )
- local nfds = math.max( filter_client( fds_read, status.read, status.password ),
- filter_client( fds_write, status.write ) ) + 1
local ret = vlc.net.select( nfds, fds_read, fds_write,
- timeout or 0.5 )
+ timeout or -1 )
local wclients = {}
local rclients = {}
if ret > 0 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
+ local afd = listener:accept(0)
+ new_client( h, afd, afd, client_type.net )
+ break
+ end
+ end
+ end
+ end
end
return wclients, rclients
end
listen = _listen,
listen_tcp = _listen_tcp,
listen_stdio = _listen_stdio,
- accept = _accept,
- select = _select,
+ accept_and_select = _accept_and_select,
broadcast = _broadcast,
}
--[[ The main loop ]]
while not vlc.misc.should_die() do
- h:accept()
- local write, read = h:select(0.1)
+ local write, read = h:accept_and_select()
for _, client in pairs(write) do
local len = client:send()
--[[ The main loop ]]
while not vlc.misc.should_die() do
- h:accept()
- local w, r = h:select( 0.1 )
+ local w, r = h:accept_and_select()
-- Handle writes
for _, client in pairs(w) do