]> code.citadel.org Git - citadel.git/blobdiff - citadel/event_client.c
fix loop / handling error when connecting fails immediately
[citadel.git] / citadel / event_client.c
index a7ea8003d67f0d88e903bb58b190998d1c3e95a0..37a943a45e90cd909b40e5099291c7ac1770a3a2 100644 (file)
@@ -319,8 +319,14 @@ IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
        ev_timer_stop (event_base, &IO->rw_timeout);
        become_session(IO->CitContext);
 
-       close(IO->SendBuf.fd);
-       IO->SendBuf.fd = IO->RecvBuf.fd = 0;
+       if (IO->SendBuf.fd != 0)
+       {
+               ev_io_stop(event_base, &IO->send_event);
+               ev_io_stop(event_base, &IO->recv_event);
+               ev_timer_stop (event_base, &IO->rw_timeout);
+               close(IO->SendBuf.fd);
+               IO->SendBuf.fd = IO->RecvBuf.fd = 0;
+       }
 
        assert(IO->Timeout);
         switch (IO->Timeout(IO))
@@ -331,6 +337,7 @@ IO_Timeout_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
                break;
        }
 }
+
 static void
 IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
 {
@@ -338,11 +345,40 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
 
        ev_timer_stop (event_base, &IO->conn_fail);
 
-       ev_io_stop(loop, &IO->conn_event);
+       if (IO->SendBuf.fd != 0)
+       {
+               ev_io_stop(loop, &IO->conn_event);
+               ev_io_stop(event_base, &IO->send_event);
+               ev_io_stop(event_base, &IO->recv_event);
+               ev_timer_stop (event_base, &IO->rw_timeout);
+               close(IO->SendBuf.fd);
+               IO->SendBuf.fd = IO->RecvBuf.fd = 0;
+       }
+       become_session(IO->CitContext);
+
+       assert(IO->ConnFail);
+        switch (IO->ConnFail(IO))
+       {
+       case eAbort:
+               ShutDownCLient(IO);
+       default:
+               break;
+
+       }
+}
+
+static void
+IO_connfailimmediate_callback(struct ev_loop *loop, ev_idle *watcher, int revents)
+{
+       AsyncIO *IO = watcher->data;
 
-       close(IO->SendBuf.fd);
-       IO->SendBuf.fd = IO->RecvBuf.fd = 0;
+       ev_idle_stop (event_base, &IO->conn_fail_immediate);
 
+       if (IO->SendBuf.fd != 0)
+       {
+               close(IO->SendBuf.fd);
+               IO->SendBuf.fd = IO->RecvBuf.fd = 0;
+       }
        become_session(IO->CitContext);
 
        assert(IO->ConnFail);
@@ -355,6 +391,7 @@ IO_connfail_callback(struct ev_loop *loop, ev_timer *watcher, int revents)
 
        }
 }
+
 static void
 IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents)
 {
@@ -477,11 +514,14 @@ eNextState event_connect_socket(AsyncIO *IO, double conn_timeout, double first_r
                return IO->NextState;
        }
        else {
+               ev_idle_init(&IO->conn_fail_immediate,
+                            IO_connfailimmediate_callback);
+               IO->conn_fail_immediate.data = IO;
+               ev_idle_start(event_base, &IO->conn_fail_immediate);
+               
                CtdlLogPrintf(CTDL_ERR, "connect() failed: %s\n", strerror(errno));
                StrBufPrintf(IO->ErrMsg, "Failed to connect: %s", strerror(errno));
-               assert(IO->ConnFail);
-               IO->ConnFail(IO);
-               return eAbort;
+               return IO->NextState;
        }
        return IO->NextState;
 }