Merge 0.10->trunk
[prosody.git] / net / server_select.lua
index d84040018418a62cb29c30c4cf73a9b193ad8d8f..4df6e12d750ce2ce15ef6a719e4308792a5ac2f8 100644 (file)
@@ -31,14 +31,12 @@ local tostring = use "tostring"
 
 --// lua libs //--
 
-local os = use "os"
 local table = use "table"
 local string = use "string"
 local coroutine = use "coroutine"
 
 --// lua lib methods //--
 
-local os_difftime = os.difftime
 local math_min = math.min
 local math_huge = math.huge
 local table_concat = table.concat
@@ -58,7 +56,6 @@ local getaddrinfo = luasocket.dns.getaddrinfo
 
 local ssl_wrap = ( has_luasec and luasec.wrap )
 local socket_bind = luasocket.bind
-local socket_sleep = luasocket.sleep
 local socket_select = luasocket.select
 
 --// functions //--
@@ -102,7 +99,6 @@ local _sendtraffic
 local _readtraffic
 
 local _selecttimeout
-local _sleeptime
 local _tcpbacklog
 
 local _starttime
@@ -115,8 +111,6 @@ local _checkinterval
 local _sendtimeout
 local _readtimeout
 
-local _timer
-
 local _maxselectlen
 local _maxfd
 
@@ -141,7 +135,6 @@ _sendtraffic = 0 -- some stats
 _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
 
 _maxsendlen = 51000 * 1024 -- max len of send buffer
@@ -293,7 +286,6 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
        local bufferqueuelen = 0        -- end of buffer array
 
        local toclose
-       local fatalerror
        local needtls
 
        local bufferlen = 0
@@ -505,7 +497,6 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                        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
@@ -545,7 +536,6 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                        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
@@ -590,8 +580,9 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                                                coroutine_yield( ) -- handshake not finished
                                        end
                                end
-                               out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
-                               _ = handler and handler:force_close("ssl handshake failed")
+                               err = "ssl handshake error: " .. ( err or "handshake too long" );
+                               out_put( "server.lua: ", err );
+                               _ = handler and handler:force_close(err)
                                return false, err -- handshake failed
                        end
                )
@@ -793,7 +784,6 @@ end
 getsettings = function( )
        return {
                select_timeout = _selecttimeout;
-               select_sleep_time = _sleeptime;
                tcp_backlog = _tcpbacklog;
                max_send_buffer_size = _maxsendlen;
                max_receive_buffer_size = _maxreadlen;
@@ -811,7 +801,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
@@ -850,8 +839,7 @@ local add_task do
                end
        end
 
-       addtimer(function()
-               local current_time = luasocket_gettime();
+       addtimer(function(current_time)
                if #new_data > 0 then
                        for _, d in pairs(new_data) do
                                table_insert(data, d);
@@ -890,8 +878,15 @@ end
 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
                        local handler = _socketlist[ socket ]
@@ -919,17 +914,16 @@ loop = function(once) -- this is the main loop of the program
                _currenttime = luasocket_gettime( )
 
                -- Check for socket timeouts
-               local difftime = os_difftime( _currenttime - _starttime )
-               if difftime > _checkinterval then
+               if _currenttime - _starttime > _checkinterval then
                        _starttime = _currenttime
                        for handler, timestamp in pairs( _writetimes ) do
-                               if os_difftime( _currenttime - timestamp ) > _sendtimeout then
+                               if _currenttime - timestamp > _sendtimeout then
                                        handler.disconnect( )( handler, "send timeout" )
                                        handler:force_close()    -- forced disconnect
                                end
                        end
                        for handler, timestamp in pairs( _readtimes ) do
-                               if os_difftime( _currenttime - timestamp ) > _readtimeout then
+                               if _currenttime - timestamp > _readtimeout then
                                        if not(handler.onreadtimeout) or handler:onreadtimeout() ~= true then
                                                handler.disconnect( )( handler, "read timeout" )
                                                handler:close( )        -- forced disconnect?
@@ -939,23 +933,9 @@ loop = function(once) -- this is the main loop of the program
                                end
                        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
-
-               -- wait some time (0 by default)
-               socket_sleep( _sleeptime )
        until quitting;
        if once and quitting == "once" then quitting = nil; return; end
+       closeall();
        return "quitting"
 end
 
@@ -1029,15 +1009,12 @@ local addclient = function( address, port, listeners, pattern, sslctx, typ )
        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)