net.server_select, net.server_event: Change semantics of conn:close() - always call...
authorMatthew Wild <mwild1@gmail.com>
Sun, 22 Jul 2012 15:54:33 +0000 (16:54 +0100)
committerMatthew Wild <mwild1@gmail.com>
Sun, 22 Jul 2012 15:54:33 +0000 (16:54 +0100)
net/server_event.lua
net/server_select.lua

index 03a7708c24841d576d8f75111682f2e6657d3af8..3c4185af96b07e2a7ecbd26bba16a988787ece16 100644 (file)
@@ -249,7 +249,7 @@ do
                        return true
        end
        function interface_mt:_destroy()  -- close this interface + events and call last listener
-                       debug( "closing client with id:", self.id )
+                       debug( "closing client with id:", self.id, self.fatalerror )
                        self:_lock( true, true, true )  -- first of all, lock the interface to avoid further actions
                        local _
                        _ = self.eventread and self.eventread:close( )  -- close events; this must be called outside of the event callbacks!
@@ -328,22 +328,22 @@ do
                end
                return true
        end
-       function interface_mt:close(now)
+       function interface_mt:close()
                if self.nointerface then return nil, "locked"; end
                debug( "try to close client connection with id:", self.id )
                if self.type == "client" then
                        self.fatalerror = "client to close"
-                       if ( not self.eventwrite ) or now then  -- try to close immediately
-                               self:_lock( true, true, true )
-                               self:_close()
-                               return true
-                       else  -- wait for incomplete write request
+                       if self.eventwrite then -- wait for incomplete write request
                                self:_lock( true, true, false )
                                debug "closing delayed until writebuffer is empty"
                                return nil, "writebuffer not empty, waiting"
+                       else -- close now
+                               self:_lock( true, true, true )
+                               self:_close()
+                               return true
                        end
                else
-                       debug( "try to close server with id:", tostring(self.id), "args:", tostring(now) )
+                       debug( "try to close server with id:", tostring(self.id))
                        self.fatalerror = "server to close"
                        self:_lock( true )
                        self:_close( 0 )  -- add new event to remove the server interface
index de637f705ca155315c6fa2e19791692741121ab6..c0f8742e1adf2eb425f15bd7ab4dc35107b27fcf 100644 (file)
@@ -314,22 +314,28 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                end
                return false, "setoption not implemented";
        end
-       handler.close = function( self, forced )
+       handler.force_close = function ( self )
+               if bufferqueuelen ~= 0 then
+                       out_put("discarding unwritten data for ", tostring(ip), ":", tostring(clientport))
+                       for i = bufferqueuelen, 1, -1 do
+                               bufferqueue[i] = nil;
+                       end
+                       bufferqueuelen = 0;
+               end
+               return self:close();
+       end
+       handler.close = function( self )
                if not handler then return true; end
                _readlistlen = removesocket( _readlist, socket, _readlistlen )
                _readtimes[ handler ] = nil
                if bufferqueuelen ~= 0 then
-                       if not ( forced or fatalerror ) then
-                               handler.sendbuffer( )
-                               if bufferqueuelen ~= 0 then -- try again...
-                                       if handler then
-                                               handler.write = nil -- ... but no further writing allowed
-                                       end
-                                       toclose = true
-                                       return false
+                       handler.sendbuffer() -- Try now to send any outstanding data
+                       if bufferqueuelen ~= 0 then -- Still not empty, so we'll try again later
+                               if handler then
+                                       handler.write = nil -- ... but no further writing allowed
                                end
-                       else
-                               send( socket, table_concat( bufferqueue, "", 1, bufferqueuelen ), 1, bufferlen )        -- forced send
+                               toclose = true
+                               return false
                        end
                end
                if socket then
@@ -347,7 +353,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                        local _handler = handler;
                        handler = nil
                        if disconnect then
-                               disconnect(_handler, "closed");
+                               disconnect(_handler, false);
                        end
                end
                if server then
@@ -480,7 +486,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                        _ = _cleanqueue and clean( bufferqueue )
                        --out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
                else
-                       succ, err, count = false, "closed", 0;
+                       succ, err, count = false, "unexpected close", 0;
                end
                if succ then    -- sending succesful
                        bufferqueuelen = 0
@@ -491,7 +497,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                                drain(handler)
                        end
                        _ = needtls and handler:starttls(nil)
-                       _ = toclose and handler:close( )
+                       _ = toclose and handler:force_close( )
                        return true
                elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
                        buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
@@ -504,7 +510,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                        out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
                        fatalerror = true
                        disconnect( handler, err )
-                       _ = handler and handler:close( )
+                       _ = handler and handler:force_close( )
                        return false
                end
        end
@@ -547,7 +553,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
                                end
                                out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
                                disconnect( handler, "ssl handshake failed" )
-                               _ = handler and handler:close( true )    -- forced disconnect
+                               _ = handler and handler:force_close()
                                return false, err -- handshake failed
                        end
                )
@@ -810,7 +816,7 @@ loop = function(once) -- this is the main loop of the program
                end
                for handler, err in pairs( _closelist ) do
                        handler.disconnect( )( handler, err )
-                       handler:close( true )    -- forced disconnect
+                       handler:force_close()    -- forced disconnect
                end
                clean( _closelist )
                _currenttime = luasocket_gettime( )
@@ -896,7 +902,7 @@ addtimer( function( )
                                if os_difftime( _currenttime - timestamp ) > _sendtimeout then
                                        --_writetimes[ handler ] = nil
                                        handler.disconnect( )( handler, "send timeout" )
-                                       handler:close( true )    -- forced disconnect
+                                       handler:force_close()    -- forced disconnect
                                end
                        end
                        for handler, timestamp in pairs( _readtimes ) do