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;
|
||||
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:
|
||||
*completed = 1;
|
||||
return REDIS_OK;
|
||||
case EALREADY:
|
||||
case EINPROGRESS:
|
||||
case EWOULDBLOCK:
|
||||
*completed = 0;
|
||||
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
|
||||
* EINPROGRESS for POSIX connect(), so we do that translation to keep POSIX
|
||||
* logic consistent. */
|
||||
if (errno == EWOULDBLOCK) {
|
||||
* logic consistent.
|
||||
* 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;
|
||||
}
|
||||
else if (err == EIO) {
|
||||
errno = EALREADY;
|
||||
}
|
||||
|
||||
return ret != SOCKET_ERROR ? ret : -1;
|
||||
}
|
||||
@ -205,6 +212,14 @@ int win32_getsockopt(SOCKET sockfd, int level, int optname, void *optval, sockle
|
||||
} else {
|
||||
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);
|
||||
return ret != SOCKET_ERROR ? ret : -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user