diff --git a/src/unix/internal.h b/src/unix/internal.h index dd46c95e..382c2722 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -93,7 +93,8 @@ enum { UV_STREAM_WRITABLE = 0x40, /* The stream is writable */ UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */ UV_TCP_NODELAY = 0x100, /* Disable Nagle. */ - UV_TCP_KEEPALIVE = 0x200 /* Turn on keep-alive. */ + UV_TCP_KEEPALIVE = 0x200, /* Turn on keep-alive. */ + UV_TCP_CONNECTING = 0x400 /* Not alway set. See uv_connect() in tcp.c */ }; inline static void uv__req_init(uv_loop_t* loop, diff --git a/src/unix/stream.c b/src/unix/stream.c index e26b8723..0dbf1d78 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -790,6 +790,12 @@ static void uv__stream_connect(uv_stream_t* stream) { stream->connect_req = NULL; uv__req_unregister(stream->loop, req); + /* Hack. See uv__connect() in tcp.c */ + if (stream->flags & UV_TCP_CONNECTING) { + assert(stream->type == UV_TCP); + uv__handle_stop(stream); + } + if (req->cb) { uv__set_sys_error(stream->loop, error); req->cb(req, error ? -1 : 0); diff --git a/src/unix/tcp.c b/src/unix/tcp.c index 233be825..1aeba0ef 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c @@ -109,8 +109,17 @@ static int uv__connect(uv_connect_t* req, while (r == -1 && errno == EINTR); if (r == -1) { - if (errno == EINPROGRESS) - ; /* not an error */ + if (errno == EINPROGRESS) { + /* Not an error. However, we need to keep the event loop from spinning + * while the connection is in progress. Artificially start the handle + * and stop it again in uv__stream_connect() in stream.c. Yes, it's a + * hack but there's no good alternative, the v0.8 ABI is frozen. + */ + if (!uv__is_active(handle)) { + handle->flags |= UV_TCP_CONNECTING; + uv__handle_start(handle); + } + } else if (errno == ECONNREFUSED) /* If we get a ECONNREFUSED wait until the next tick to report the * error. Solaris wants to report immediately--other unixes want to