unix: handle EINPROGRESS for unix sockets

Before this commit, it was assumed that connect() on UNIX sockets never
returns EINPROGRESS. It turned out to be a bad assumption: Dave Pacheco
reports sporadic hangups on SmartOS because of that.

It's not clear to me _why_ the Illumos kernel returns that error but
that's inconsequential: whatever the cause, libuv needs to handle it
and now it does.

Fixes joyent/node#4785.
This commit is contained in:
Ben Noordhuis 2013-02-21 23:11:40 +01:00
parent 1d64c8284d
commit 3348cd7407

View File

@ -183,9 +183,6 @@ void uv_pipe_connect(uv_connect_t* req,
uv_strlcpy(saddr.sun_path, name, sizeof(saddr.sun_path)); uv_strlcpy(saddr.sun_path, name, sizeof(saddr.sun_path));
saddr.sun_family = AF_UNIX; saddr.sun_family = AF_UNIX;
/* We don't check for EINPROGRESS. Think about it: the socket
* is either there or not.
*/
do { do {
r = connect(uv__stream_fd(handle), r = connect(uv__stream_fd(handle),
(struct sockaddr*)&saddr, sizeof saddr); (struct sockaddr*)&saddr, sizeof saddr);
@ -193,6 +190,7 @@ void uv_pipe_connect(uv_connect_t* req,
while (r == -1 && errno == EINTR); while (r == -1 && errno == EINTR);
if (r == -1) if (r == -1)
if (errno != EINPROGRESS)
goto out; goto out;
if (new_sock) if (new_sock)
@ -213,7 +211,8 @@ out:
req->cb = cb; req->cb = cb;
ngx_queue_init(&req->queue); ngx_queue_init(&req->queue);
/* Run callback on next tick. */ /* Force callback to run on next tick in case of error. */
if (err != 0)
uv__io_feed(handle->loop, &handle->io_watcher); uv__io_feed(handle->loop, &handle->io_watcher);
/* Mimic the Windows pipe implementation, always /* Mimic the Windows pipe implementation, always