MEMCACHED_BEHAVIOR_RETRY_TIMEOUT added for timeout
[m6w6/libmemcached] / lib / memcached_connect.c
index b4642c7630fb542ece0935e0f9312ebf31b7ab60..4bfc710fa23e9c1543de27c46da52bbfa37d6116 100644 (file)
@@ -135,9 +135,49 @@ test_connect:
                 sizeof(servAddr)) < 0)
     {
       switch (errno) {
+      case EINPROGRESS:
+        {
+        struct timeval tm = { ptr->root->connect_timeout, 0 };
+        socklen_t len= sizeof(int);
+        fd_set wset;
+        int error=0, value;
+
+        FD_ZERO(&wset);
+        FD_SET(ptr->fd, &wset);
+
+        select(ptr->fd+1, NULL, &wset, NULL, &tm);
+        if (FD_ISSET(ptr->fd, &wset) != 0)
+        {
+          if (getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &value, &len) == 0)
+          {
+            if (value)
+            {
+              error= 1;
+            }
+          }
+          else
+          {
+            error= 1;
+          }
+        }
+        else
+        {
+          error= 1;
+        }
+
+        if (error)
+        {
+          ptr->cached_errno= errno;
+          WATCHPOINT_ERRNO(ptr->cached_errno);
+          close(ptr->fd);
+          ptr->fd= -1;
+          return MEMCACHED_ERRNO;
+        }
+
+        break;
+        }
         /* We are spinning waiting on connect */
       case EALREADY:
-      case EINPROGRESS:
       case EINTR:
         goto test_connect;
       case EISCONN: /* We were spinning waiting on connect */
@@ -206,6 +246,13 @@ test_connect:
           WATCHPOINT_ERRNO(ptr->cached_errno);
           close(ptr->fd);
           ptr->fd= -1;
+          if (ptr->root->retry_timeout)
+          {
+            struct timeval next_time;
+
+            gettimeofday(&next_time, NULL);
+            ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
+          }
         }
       }
       else
@@ -229,6 +276,14 @@ memcached_return memcached_connect(memcached_server_st *ptr)
   memcached_return rc= MEMCACHED_NO_SERVERS;
   LIBMEMCACHED_MEMCACHED_CONNECT_START();
 
+  if (ptr->root->retry_timeout)
+  {
+    struct timeval next_time;
+
+    gettimeofday(&next_time, NULL);
+    if (next_time.tv_sec < ptr->next_retry)
+      return MEMCACHED_TIMEOUT;
+  }
   /* We need to clean up the multi startup piece */
   switch (ptr->type)
   {