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))
break;
}
}
+
static void
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);
}
}
+
static void
IO_connestd_callback(struct ev_loop *loop, ev_io *watcher, int revents)
{
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;
}