Merge 0.10->trunk
[prosody.git] / net / server_event.lua
index a3087847ee094e32931e8dde7e9cc0c8976531c3..fa6dda19fe552f5807a6caa7464fb90d57040bc2 100644 (file)
@@ -439,9 +439,11 @@ do
        end
 
        function interface_mt:setlistener(listener)
-               self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onreadtimeout, self.onstatus
-                       = listener.onconnect, listener.ondisconnect, listener.onincoming,
-                         listener.ontimeout, listener.onreadtimeout, listener.onstatus;
+               self:ondetach(); -- Notify listener that it is no longer responsible for this connection
+               self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout,
+               self.onreadtimeout, self.onstatus, self.ondetach
+                       = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout,
+                         listener.onreadtimeout, listener.onstatus, listener.ondetach;
        end
 
        -- Stub handlers
@@ -461,6 +463,8 @@ do
        end
        function interface_mt:ondrain()
        end
+       function interface_mt:ondetach()
+       end
        function interface_mt:onstatus()
        end
 end
@@ -488,6 +492,7 @@ do
                        ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs
                        onreadtimeout = listener.onreadtimeout; -- called when socket inactivity timeout occurs
                        ondrain = listener.ondrain; -- called when writebuffer is empty
+                       ondetach = listener.ondetach; -- called when disassociating this listener from this connection
                        onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS)
                        eventread = false, eventwrite = false, eventclose = false,
                        eventhandshake = false, eventstarthandshake = false;  -- event handler
@@ -761,7 +766,7 @@ do
                end
                client:settimeout( 0 )  -- set nonblocking
                local res, err = client:connect( addr, serverport )  -- connect
-               if res or ( err == "timeout" ) then
+               if res or ( err == "timeout" or err == "Operation already in progress" ) then
                        if client.getsockname then
                                addr = client:getsockname( )
                        end
@@ -840,6 +845,24 @@ local function link(sender, receiver, buffersize)
                        sender:pause();
                end
        end
+       sender:set_mode("*a");
+end
+
+local add_task do
+       local EVENT_LEAVE = (event.core and event.core.LEAVE) or -1;
+       local socket_gettime = socket.gettime
+       function add_task(delay, callback)
+               local event_handle;
+               event_handle = base:addevent(nil, 0, function ()
+                       local ret = callback(socket_gettime());
+                       if ret then
+                               return 0, ret;
+                       elseif event_handle then
+                               return EVENT_LEAVE;
+                       end
+               end
+               , delay);
+       end
 end
 
 return {
@@ -858,6 +881,7 @@ return {
        closeall = closeallservers,
        get_backend = get_backend,
        hook_signal = hook_signal,
+       add_task = add_task,
 
        __NAME = SCRIPT_NAME,
        __DATE = LAST_MODIFIED,