From: Kim Alvefur Date: Fri, 8 Jul 2016 20:01:10 +0000 (+0200) Subject: Merge 0.10->trunk X-Git-Url: https://git.enpas.org/?a=commitdiff_plain;h=5f7b93067521c3dea61262bf8fcfc704f5e19a3f;hp=-c;p=prosody.git Merge 0.10->trunk --- 5f7b93067521c3dea61262bf8fcfc704f5e19a3f diff --combined net/server_select.lua index 37d57d29,85730e73..f70f81d0 --- a/net/server_select.lua +++ b/net/server_select.lua @@@ -31,6 -31,7 +31,6 @@@ local tostring = use "tostring --// lua libs //-- -local os = use "os" local table = use "table" local string = use "string" local coroutine = use "coroutine" @@@ -40,7 -41,6 +40,7 @@@ local math_min = math.min local math_huge = math.huge local table_concat = table.concat +local table_insert = table.insert local string_sub = string.sub local coroutine_wrap = coroutine.wrap local coroutine_yield = coroutine.yield @@@ -56,6 -56,7 +56,6 @@@ local getaddrinfo = luasocket.dns.getad local ssl_wrap = ( has_luasec and luasec.wrap ) local socket_bind = luasocket.bind -local socket_sleep = luasocket.sleep local socket_select = luasocket.select --// functions //-- @@@ -100,6 -101,7 +100,6 @@@ local _sendtraffi local _readtraffic local _selecttimeout -local _sleeptime local _tcpbacklog local _accepretry @@@ -113,6 -115,8 +113,6 @@@ local _checkinterva local _sendtimeout local _readtimeout -local _timer - local _maxselectlen local _maxfd @@@ -138,6 -142,7 +138,6 @@@ _sendtraffic = 0 -- some stat _readtraffic = 0 _selecttimeout = 1 -- timeout of socket.select -_sleeptime = 0 -- time to wait at the end of every loop _tcpbacklog = 128 -- some kind of hint to the OS _accepretry = 10 -- seconds to wait until the next attempt of a full server to accept @@@ -297,6 -302,7 +297,6 @@@ wrapconnection = function( server, list local bufferqueuelen = 0 -- end of buffer array local toclose - local fatalerror local needtls local bufferlen = 0 @@@ -511,6 -517,7 +511,6 @@@ return dispatch( handler, buffer, err ) else -- connections was closed or fatal error out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) ) - fatalerror = true _ = handler and handler:force_close( err ) return false end @@@ -550,6 -557,7 +550,6 @@@ return true else -- connection was closed during sending or fatal error out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) ) - fatalerror = true _ = handler and handler:force_close( err ) return false end @@@ -798,6 -806,7 +798,6 @@@ en getsettings = function( ) return { select_timeout = _selecttimeout; - select_sleep_time = _sleeptime; tcp_backlog = _tcpbacklog; max_send_buffer_size = _maxsendlen; max_receive_buffer_size = _maxreadlen; @@@ -816,6 -825,7 +816,6 @@@ changesettings = function( new return nil, "invalid settings table" end _selecttimeout = tonumber( new.select_timeout ) or _selecttimeout - _sleeptime = tonumber( new.select_sleep_time ) or _sleeptime _maxsendlen = tonumber( new.max_send_buffer_size ) or _maxsendlen _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval @@@ -838,49 -848,6 +838,49 @@@ addtimer = function( listener return true end +local add_task do + local data = {}; + local new_data = {}; + + function add_task(delay, callback) + local current_time = luasocket_gettime(); + delay = delay + current_time; + if delay >= current_time then + table_insert(new_data, {delay, callback}); + else + local r = callback(current_time); + if r and type(r) == "number" then + return add_task(r, callback); + end + end + end + + addtimer(function(current_time) + if #new_data > 0 then + for _, d in pairs(new_data) do + table_insert(data, d); + end + new_data = {}; + end + + local next_time = math_huge; + for i, d in pairs(data) do + local t, callback = d[1], d[2]; + if t <= current_time then + data[i] = nil; + local r = callback(current_time); + if type(r) == "number" then + add_task(r, callback); + next_time = math_min(next_time, r); + end + else + next_time = math_min(next_time, t - current_time); + end + end + return next_time; + end); +end + stats = function( ) return _readtraffic, _sendtraffic, _readlistlen, _sendlistlen, _timerlistlen end @@@ -894,17 -861,10 +894,17 @@@ en loop = function(once) -- this is the main loop of the program if quitting then return "quitting"; end if once then quitting = "once"; end - local next_timer_time = math_huge; + _currenttime = luasocket_gettime( ) repeat + -- Fire timers + local next_timer_time = math_huge; + for i = 1, _timerlistlen do + local t = _timerlist[ i ]( _currenttime ) -- fire timers + if t then next_timer_time = math_min(next_timer_time, t); end + end + local read, write, err = socket_select( _readlist, _sendlist, math_min(_selecttimeout, next_timer_time) ) - for i, socket in ipairs( write ) do -- send data waiting in writequeues + for _, socket in ipairs( write ) do -- send data waiting in writequeues local handler = _socketlist[ socket ] if handler then handler.sendbuffer( ) @@@ -913,7 -873,7 +913,7 @@@ out_put "server.lua: found no handler and closed socket (writelist)" -- this should not happen end end - for i, socket in ipairs( read ) do -- receive data + for _, socket in ipairs( read ) do -- receive data local handler = _socketlist[ socket ] if handler then handler.readbuffer( ) @@@ -950,12 -910,27 +950,12 @@@ end end - -- Fire timers - if _currenttime - _timer >= math_min(next_timer_time, 1) then - next_timer_time = math_huge; - for i = 1, _timerlistlen do - local t = _timerlist[ i ]( _currenttime ) -- fire timers - if t then next_timer_time = math_min(next_timer_time, t); end - end - _timer = _currenttime - else - next_timer_time = next_timer_time - (_currenttime - _timer); - end - for server, paused_time in pairs( _fullservers ) do if _currenttime - paused_time > _accepretry then _fullservers[ server ] = nil; server.resume(); end end - - -- wait some time (0 by default) - socket_sleep( _sleeptime ) until quitting; if once and quitting == "once" then quitting = nil; return; end closeall(); @@@ -1002,14 -977,16 +1002,14 @@@ local addclient = function( address, po elseif sslctx and not has_luasec then err = "luasec not found" end - if not typ then + if getaddrinfo and not typ then local addrinfo, err = getaddrinfo(address) if not addrinfo then return nil, err end if addrinfo[1] and addrinfo[1].family == "inet6" then typ = "tcp6" - else - typ = "tcp" end end - local create = luasocket[typ] + local create = luasocket[typ or "tcp"] if type( create ) ~= "function" then err = "invalid socket type" end @@@ -1025,19 -1002,22 +1025,19 @@@ end client:settimeout( 0 ) local ok, err = client:connect( address, port ) - if ok or err == "timeout" then + if ok or err == "timeout" or err == "Operation already in progress" then return wrapclient( client, address, port, listeners, pattern, sslctx ) else return nil, err end end ---// EXPERIMENTAL //-- - ----------------------------------// BEGIN //-- use "setmetatable" ( _socketlist, { __mode = "k" } ) use "setmetatable" ( _readtimes, { __mode = "k" } ) use "setmetatable" ( _writetimes, { __mode = "k" } ) -_timer = luasocket_gettime( ) _starttime = luasocket_gettime( ) local function setlogger(new_logger) @@@ -1052,7 -1032,6 +1052,7 @@@ en return { _addtimer = addtimer, + add_task = add_task; addclient = addclient, wrapclient = wrapclient, diff --combined plugins/mod_admin_telnet.lua index 4f11d8ea,088e09dd..dd583663 --- a/plugins/mod_admin_telnet.lua +++ b/plugins/mod_admin_telnet.lua @@@ -336,43 -336,6 +336,43 @@@ function def_env.server:memory( return true, "OK"; end +def_env.timer = {}; + +function def_env.timer:info() + local socket = require "socket"; + local print = self.session.print; + local add_task = require"util.timer".add_task; + local h, params = add_task.h, add_task.params; + if h then + print("-- util.timer"); + for i, id in ipairs(h.ids) do + if not params[id] then + print(os.date("%F %T", h.priorities[i]), h.items[id]); + elseif not params[id].callback then + print(os.date("%F %T", h.priorities[i]), h.items[id], unpack(params[id])); + else + print(os.date("%F %T", h.priorities[i]), params[id].callback, unpack(params[id])); + end + end + end + if server.event_base then + local count = 0; + for k, v in pairs(debug.getregistry()) do + if type(v) == "function" and v.callback and v.callback == add_task._on_timer then + count = count + 1; + end + end + print(count .. " libevent callbacks"); + end + if h then + local next_time = h:peek(); + if next_time then + return true, os.date("Next event at %F %T (in %%.6fs)", next_time):format(next_time - socket.gettime()); + end + end + return true; +end + def_env.module = {}; local function get_hosts_set(hosts, module) @@@ -769,7 -732,6 +769,6 @@@ local function print_errors(print, erro end function def_env.s2s:showcert(domain) - local ser = require "util.serialization".serialize; local print = self.session.print; local s2s_sessions = module:shared"/*/s2s/sessions"; local domain_sessions = set.new(array.collect(values(s2s_sessions))) @@@ -994,11 -956,11 +993,11 @@@ local function check_muc(jid end function def_env.muc:create(room_jid) - local room, host = check_muc(room_jid); + local room_name, host = check_muc(room_jid); if not room_name then return room_name, host; end - if not room then return nil, host end + if not room_name then return nil, host end if hosts[host].modules.muc.rooms[room_jid] then return nil, "Room exists already" end return hosts[host].modules.muc.create_room(room_jid); end @@@ -1008,7 -970,7 +1007,7 @@@ function def_env.muc:room(room_jid if not room_name then return room_name, host; end - local room_obj = hosts[host].modules.muc.rooms[room_jid]; + local room_obj = hosts[host].modules.muc.get_room_from_jid(room_jid); if not room_obj then return nil, "No such room: "..room_jid; end @@@ -1022,8 -984,8 +1021,8 @@@ function def_env.muc:list(host end local print = self.session.print; local c = 0; - for name in keys(host_session.modules.muc.rooms) do - print(name); + for room in host_session.modules.muc.each_room() do + print(room.jid); c = c + 1; end return true, c.." rooms"; @@@ -1188,7 -1150,7 +1187,7 @@@ function printbanner(session if option == "short" or option == "full" then session.print("Welcome to the Prosody administration console. For a list of commands, type: help"); session.print("You may find more help on using this console in our online documentation at "); - session.print("http://prosody.im/doc/console\n"); + session.print("https://prosody.im/doc/console\n"); end if option ~= "short" and option ~= "full" and option ~= "graphic" then session.print(option);