aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2012-07-22 16:54:33 +0100
committerMatthew Wild <mwild1@gmail.com>2012-07-22 16:54:33 +0100
commit73c5470e83551c632206d765ac3094f9598d664b (patch)
tree10a190660d93f7b88592dc0e62a9c815706e8b09
parent5e7ab4f153891bb8d220c9d12ce639ad6e31db0a (diff)
downloadprosody-73c5470e83551c632206d765ac3094f9598d664b.tar.gz
prosody-73c5470e83551c632206d765ac3094f9598d664b.zip
net.server_select, net.server_event: Change semantics of conn:close() - always call ondisconnect (with err == nil), and never close with data in send buffer (i.e. 'now' parameter removed)
-rw-r--r--net/server_event.lua16
-rw-r--r--net/server_select.lua42
2 files changed, 32 insertions, 26 deletions
diff --git a/net/server_event.lua b/net/server_event.lua
index 03a7708c..3c4185af 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -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
diff --git a/net/server_select.lua b/net/server_select.lua
index de637f70..c0f8742e 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -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