Updating the get function in the C++ interface.
[awesomized/libmemcached] / libmemcached / memcached_connect.c
index 8e0e4208e864f11556ed8aaa9927aa8b15400c11..0d61f847bab0996e2de08a41ba333b47851b720c 100644 (file)
@@ -121,7 +121,7 @@ static memcached_return set_socket_options(memcached_server_st *ptr)
   }
 
   /* For the moment, not getting a nonblocking mode will not be fatal */
-  if (ptr->root->flags & MEM_NO_BLOCK)
+  if ((ptr->root->flags & MEM_NO_BLOCK) || ptr->root->connect_timeout)
   {
     int flags;
 
@@ -185,15 +185,6 @@ static memcached_return network_connect(memcached_server_st *ptr)
   {
     struct addrinfo *use;
 
-    if (ptr->root->server_failure_limit != 0) 
-    {
-      if (ptr->server_failure_counter >= ptr->root->server_failure_limit) 
-      {
-          memcached_server_remove(ptr);
-          return MEMCACHED_FAILURE;
-      }
-    }
-
     if (!ptr->sockaddr_inited ||
         (!(ptr->root->flags & MEM_USE_CACHE_LOOKUPS)))
     {
@@ -227,7 +218,7 @@ static memcached_return network_connect(memcached_server_st *ptr)
 
       (void)set_socket_options(ptr);
 
-      int flags;
+      int flags= 0;
       if (ptr->root->connect_timeout)
       {
         flags= fcntl(ptr->fd, F_GETFL, 0);
@@ -243,7 +234,9 @@ static memcached_return network_connect(memcached_server_st *ptr)
         if (errno == EINPROGRESS || /* nonblocking mode - first return, */
             errno == EALREADY) /* nonblocking mode - subsequent returns */
         {
-          struct pollfd fds[1] = { [0].fd = ptr->fd, [0].events = POLLOUT };
+          struct pollfd fds[1];
+          fds[0].fd = ptr->fd;
+          fds[0].events = POLLOUT;
           int error= poll(fds, 1, ptr->root->connect_timeout);
 
           if (error != 1 || fds[0].revents & POLLERR)
@@ -251,9 +244,9 @@ static memcached_return network_connect(memcached_server_st *ptr)
             if (fds[0].revents & POLLERR)
             {
               int err;
-              int len = sizeof (err);
+              socklen_t len = sizeof (err);
               (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
-              ptr->cached_errno= errno;
+              ptr->cached_errno= (err == 0) ? errno : err;
             }
 
             (void)close(ptr->fd);
@@ -275,7 +268,7 @@ static memcached_return network_connect(memcached_server_st *ptr)
       if (ptr->fd != -1)
       {
         /* restore flags */ 
-        if (ptr->root->connect_timeout && (flags & O_NONBLOCK) == 0) 
+        if (ptr->root->connect_timeout && (ptr->root->flags & MEM_NO_BLOCK) == 0) 
           (void)fcntl(ptr->fd, F_SETFL, flags & ~O_NONBLOCK);
 
         WATCHPOINT_ASSERT(ptr->cursor_active == 0);
@@ -297,6 +290,8 @@ static memcached_return network_connect(memcached_server_st *ptr)
         ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
     }
     ptr->server_failure_counter+= 1;
+    if (ptr->cached_errno == 0)
+      return MEMCACHED_TIMEOUT;
     return MEMCACHED_ERRNO; /* The last error should be from connect() */
   }
 
@@ -310,14 +305,30 @@ memcached_return memcached_connect(memcached_server_st *ptr)
   memcached_return rc= MEMCACHED_NO_SERVERS;
   LIBMEMCACHED_MEMCACHED_CONNECT_START();
 
-  if (ptr->root->retry_timeout)
+  /* both retry_timeout and server_failure_limit must be set in order to delay retrying a server on error. */
+  WATCHPOINT_ASSERT(ptr->root);
+  if (ptr->root->retry_timeout && ptr->root->server_failure_limit)
   {
     struct timeval next_time;
 
     gettimeofday(&next_time, NULL);
+
+    /* if we've had too many consecutive errors on this server, mark it dead. */
+    if (ptr->server_failure_counter > ptr->root->server_failure_limit)
+    {
+      ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
+      ptr->server_failure_counter= 0;
+    }
+
     if (next_time.tv_sec < ptr->next_retry)
-      return MEMCACHED_TIMEOUT;
+    {
+      if (memcached_behavior_get(ptr->root, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS))
+        run_distribution(ptr->root);
+
+      return MEMCACHED_SERVER_MARKED_DEAD;
+    }
   }
+
   /* We need to clean up the multi startup piece */
   switch (ptr->type)
   {