Merge pull request #1073 from michael-grunder/kristjanvalur-pr1
Fix async connect on Windows
This commit is contained in:
commit
a890d9ce20
20
net.c
20
net.c
@ -277,12 +277,28 @@ int redisCheckConnectDone(redisContext *c, int *completed) {
|
|||||||
*completed = 1;
|
*completed = 1;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
switch (errno) {
|
int error = errno;
|
||||||
|
if (error == EINPROGRESS) {
|
||||||
|
/* must check error to see if connect failed. Get the socket error */
|
||||||
|
int fail, so_error;
|
||||||
|
socklen_t optlen = sizeof(so_error);
|
||||||
|
fail = getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &so_error, &optlen);
|
||||||
|
if (fail == 0) {
|
||||||
|
if (so_error == 0) {
|
||||||
|
/* Socket is connected! */
|
||||||
|
*completed = 1;
|
||||||
|
return REDIS_OK;
|
||||||
|
}
|
||||||
|
/* connection error; */
|
||||||
|
errno = so_error;
|
||||||
|
error = so_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (error) {
|
||||||
case EISCONN:
|
case EISCONN:
|
||||||
*completed = 1;
|
*completed = 1;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
case EALREADY:
|
case EALREADY:
|
||||||
case EINPROGRESS:
|
|
||||||
case EWOULDBLOCK:
|
case EWOULDBLOCK:
|
||||||
*completed = 0;
|
*completed = 0;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
|
19
sockcompat.c
19
sockcompat.c
@ -180,10 +180,17 @@ int win32_connect(SOCKET sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
|||||||
|
|
||||||
/* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as
|
/* For Winsock connect(), the WSAEWOULDBLOCK error means the same thing as
|
||||||
* EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX
|
* EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX
|
||||||
* logic consistent. */
|
* logic consistent.
|
||||||
if (errno == EWOULDBLOCK) {
|
* Additionally, WSAALREADY is can be reported as WSAEINVAL to and this is
|
||||||
|
* translated to EIO. Convert appropriately
|
||||||
|
*/
|
||||||
|
int err = errno;
|
||||||
|
if (err == EWOULDBLOCK) {
|
||||||
errno = EINPROGRESS;
|
errno = EINPROGRESS;
|
||||||
}
|
}
|
||||||
|
else if (err == EIO) {
|
||||||
|
errno = EALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
return ret != SOCKET_ERROR ? ret : -1;
|
return ret != SOCKET_ERROR ? ret : -1;
|
||||||
}
|
}
|
||||||
@ -205,6 +212,14 @@ int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, sockle
|
|||||||
} else {
|
} else {
|
||||||
ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);
|
ret = getsockopt(sockfd, level, optname, (char*)optval, optlen);
|
||||||
}
|
}
|
||||||
|
if (ret != SOCKET_ERROR && level == SOL_SOCKET && optname == SO_ERROR) {
|
||||||
|
/* translate SO_ERROR codes, if non-zero */
|
||||||
|
int err = *(int*)optval;
|
||||||
|
if (err != 0) {
|
||||||
|
err = _wsaErrorToErrno(err);
|
||||||
|
*(int*)optval = err;
|
||||||
|
}
|
||||||
|
}
|
||||||
_updateErrno(ret != SOCKET_ERROR);
|
_updateErrno(ret != SOCKET_ERROR);
|
||||||
return ret != SOCKET_ERROR ? ret : -1;
|
return ret != SOCKET_ERROR ? ret : -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user