Browse files

Reconnect on EINVAL for windows

Sometimes on WinXP second call of WSAConnect function returns
WSAEINVAL. To avoid it we make reconnect

Change-Id: I11eb12c99f9043def017527b4af1d745c34c7962
Reviewed-on: http://review.couchbase.org/25155
Tested-by: Sergey Avseyev <sergey.avseyev@gmail.com>
Reviewed-by: Trond Norbye <trond.norbye@gmail.com>
  • Loading branch information...
1 parent 1097eca commit af8bd6b2ebb10e17b630adbf39fafe5f354a931a Yury Alioshinov committed with trondn Mar 14, 2013
Showing with 32 additions and 4 deletions.
  1. +9 −1 src/http.c
  2. +10 −1 src/instance.c
  3. +1 −0 src/internal.h
  4. +9 −1 src/server.c
  5. +3 −1 src/utilities.c
View
10 src/http.c
@@ -455,6 +455,7 @@ static void request_connected(lcb_http_request_t req)
static lcb_error_t request_connect(lcb_http_request_t req)
{
int retry;
+ int retry_once = 0;
int save_errno;
do {
@@ -495,7 +496,14 @@ static lcb_error_t request_connect(lcb_http_request_t req)
return LCB_SUCCESS;
case LCB_CONNECT_EALREADY: /* Subsequent calls to connect */
return LCB_SUCCESS;
-
+ case LCB_CONNECT_EINVAL:
+ if (!retry_once) { /* First time get WSAEINVAL error - do retry */
+ retry = 1;
+ retry_once = 1;
+ break;
+ } else { /* Second time get WSAEINVAL error - it is permanent error */
+ retry_once = 0; /* go to LCB_CONNECT_EFAIL brench (no break or return) */
+ }
case LCB_CONNECT_EFAIL:
if (req->curr_ai->ai_next) {
retry = 1;
View
11 src/instance.c
@@ -1119,6 +1119,7 @@ static void lcb_instance_connect_handler(lcb_socket_t sock,
{
lcb_t instance = arg;
int retry;
+ int retry_once = 0;
lcb_connect_status_t connstatus = LCB_CONNECT_OK;
int save_errno;
do {
@@ -1174,7 +1175,15 @@ static void lcb_instance_connect_handler(lcb_socket_t sock,
return ;
case LCB_CONNECT_EALREADY: /* Subsequent calls to connect */
return ;
-
+ case LCB_CONNECT_EINVAL:
+ if (!retry_once) { /* First time get WSAEINVAL error - do retry */
+ retry = 1;
+ retry_once = 1;
+ break;
+ } else { /* Second time get WSAEINVAL error - it is permanent error */
+ retry_once = 0; /* go to default brench (no break or return) */
+ connstatus = LCB_CONNECT_EFAIL;
+ }
default: {
release_socket(instance);
if (connstatus == LCB_CONNECT_EFAIL &&
View
1 src/internal.h
@@ -78,6 +78,7 @@ extern "C" {
LCB_CONNECT_EISCONN,
LCB_CONNECT_EINTR,
LCB_CONNECT_EFAIL,
+ LCB_CONNECT_EINVAL,
LCB_CONNECT_EUNHANDLED
} lcb_connect_status_t;
View
10 src/server.c
@@ -657,6 +657,7 @@ static void server_connect_handler(lcb_socket_t sock, short which, void *arg)
static void server_connect(lcb_server_t *server)
{
int retry;
+ int retry_once = 0;
int save_errno;
do {
@@ -703,7 +704,14 @@ static void server_connect(lcb_server_t *server)
return ;
case LCB_CONNECT_EALREADY: /* Subsequent calls to connect */
return ;
-
+ case LCB_CONNECT_EINVAL:
+ if (!retry_once) { /* First time get WSAEINVAL error - do retry */
+ retry = 1;
+ retry_once = 1;
+ break;
+ } else { /* Second time get WSAEINVAL error - it is permanent error */
+ retry_once = 0; /* go to LCB_CONNECT_EFAIL brench (no break or return) */
+ }
case LCB_CONNECT_EFAIL:
if (server->curr_ai->ai_next) {
retry = 1;
View
4 src/utilities.c
@@ -75,7 +75,9 @@ lcb_connect_status_t lcb_connect_status(int err)
/* Possible to get these from a bad dns lookup */
case EAFNOSUPPORT:
case EINVAL:
-
+#ifdef _WIN32
+ return LCB_CONNECT_EINVAL;
+#endif
case ECONNREFUSED:
case ENETUNREACH:

0 comments on commit af8bd6b

Please sign in to comment.