Merge 0.10->trunk
authorKim Alvefur <zash@zash.se>
Fri, 8 Jul 2016 20:01:10 +0000 (22:01 +0200)
committerKim Alvefur <zash@zash.se>
Fri, 8 Jul 2016 20:01:10 +0000 (22:01 +0200)
1  2 
net/server_select.lua
plugins/mod_admin_telnet.lua

diff --combined net/server_select.lua
index 37d57d29ae4afd5ffeab9960c5686d60f3c1700d,85730e73c4d2d6c216d9ec062ab97926b6cf56a2..f70f81d02335fa06b44b6429fc1c4034e8e01f26
@@@ -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
                        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
                        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( )
                                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( )
                        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
        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,
index 4f11d8eacebb5b08f5bdc547c06ccb94be12e1e0,088e09dd042eaf1c19a4187e5e939fd365799816..dd583663c01746f216fdc551d3b2b3ca38ca8556
@@@ -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);