MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT added from Marcelo's patch to make sure
author <brian@gir-2.local> <>
Tue, 19 Feb 2008 02:34:34 +0000 (08:04 +0530)
committer <brian@gir-2.local> <>
Tue, 19 Feb 2008 02:34:34 +0000 (08:04 +0530)
that connnect() does not block/loop when using non-block mode.

ChangeLog
docs/memcached_behavior.pod
include/memcached.h
lib/memcached_behavior.c
lib/memcached_connect.c

index 4510c19bd98707e932e44512492974292193a766..0c835b88ac6053ac0e09cb8af664ea2527f7f0ec 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+0.17
+  * MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT added for connect timeout in
+    non-block mode.
+
 0.16
   * Work on the UDP protocol
   * Added get_by_key, set_by_key tests for C++ API
index 50e215f874ca996356f4be4d86bb2ec0a58a9e76..74a3a732396a21fe70c90d05587c74ac5c1ee68d 100755 (executable)
@@ -98,6 +98,11 @@ are valid keys.
 Enabling this will cause hosts that are added to be placed in the host list in 
 sorted order. This will defeat consisten hashing.
 
+=item MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT
+
+In non-blocking mode this changes the value of the timeout during socket
+connection.
+
 =back
 
 =head1 RETURN
index e0f829aa7b526de3140b47107e162f6800d25bab..5458974170e997ffaf1a78899c44de4970baf3f7 100644 (file)
@@ -102,6 +102,7 @@ typedef enum {
   MEMCACHED_BEHAVIOR_USER_DATA,
   MEMCACHED_BEHAVIOR_SORT_HOSTS,
   MEMCACHED_BEHAVIOR_VERIFY_KEY,
+  MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,
 } memcached_behavior;
 
 typedef enum {
@@ -217,6 +218,7 @@ struct memcached_st {
   int send_size;
   int recv_size;
   int32_t poll_timeout;
+  int32_t connect_timeout;
   memcached_result_st result;
   memcached_hash hash;
   memcached_server_distribution distribution;
index 8c02a383d7e6b9abe313983d61f643cfcc3a4425..15ee08c9eaaf5a49749624eb13ab5dbdc467e18d 100644 (file)
@@ -73,6 +73,13 @@ memcached_return memcached_behavior_set(memcached_st *ptr,
       ptr->poll_timeout= timeout;
       break;
     }
+  case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
+    {
+      int32_t timeout= (*((int32_t *)data));
+
+      ptr->connect_timeout= timeout;
+      break;
+    }
   case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
     {
       ptr->send_size= (*((int *)data));
@@ -133,6 +140,10 @@ unsigned long long memcached_behavior_get(memcached_st *ptr,
     {
       return (unsigned long long)ptr->poll_timeout;
     }
+  case MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT:
+    {
+      return (unsigned long long)ptr->connect_timeout;
+    }
   case MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE:
     {
       int sock_size;
index b4642c7630fb542ece0935e0f9312ebf31b7ab60..50c6fa62acacd3e40823909343586735cce5d093 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 */