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
 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.
 
 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
 =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_USER_DATA,
   MEMCACHED_BEHAVIOR_SORT_HOSTS,
   MEMCACHED_BEHAVIOR_VERIFY_KEY,
+  MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT,
 } memcached_behavior;
 
 typedef enum {
 } memcached_behavior;
 
 typedef enum {
@@ -217,6 +218,7 @@ struct memcached_st {
   int send_size;
   int recv_size;
   int32_t poll_timeout;
   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;
   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;
     }
       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));
   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;
     }
     {
       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;
   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) {
                 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:
         /* We are spinning waiting on connect */
       case EALREADY:
-      case EINPROGRESS:
       case EINTR:
         goto test_connect;
       case EISCONN: /* We were spinning waiting on connect */
       case EINTR:
         goto test_connect;
       case EISCONN: /* We were spinning waiting on connect */