Merge in fix for additional logic for timeouts.
authorBrian Aker <brian@tangent.org>
Tue, 14 Jun 2011 11:41:17 +0000 (04:41 -0700)
committerBrian Aker <brian@tangent.org>
Tue, 14 Jun 2011 11:41:17 +0000 (04:41 -0700)
16 files changed:
libmemcached/connect.cc
libmemcached/delete.cc
libmemcached/do.cc
libmemcached/error.cc
libmemcached/io.cc
libmemcached/memcached.cc
libmemcached/quit.cc
libmemcached/server.cc
libmemcached/server.h
libmemcached/stats.cc
libmemcached/storage.cc
libmemcached/strerror.cc
libtest/server.c
libtest/test.h
tests/mem_functions.cc
tests/parser.cc

index 1d45ded110798b13a4c91be05e9bb974fbc8ab84..707f7344387af9fbe1661387294d1de7c01a6a94 100644 (file)
@@ -74,13 +74,13 @@ static memcached_return_t connect_poll(memcached_server_st *ptr)
         {
           return MEMCACHED_SUCCESS;
         }
-        else
-        {
-          return memcached_set_errno(*ptr, err, MEMCACHED_AT);
-        }
+
+        return memcached_set_errno(*ptr, err, MEMCACHED_AT);
       }
     case 0:
-      return MEMCACHED_TIMEOUT;
+      {
+        return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+      }
 
     default: // A real error occurred and we need to completely bail
       WATCHPOINT_ERRNO(get_socket_errno());
@@ -114,22 +114,19 @@ static memcached_return_t connect_poll(memcached_server_st *ptr)
 
         (void)closesocket(ptr->fd);
         ptr->fd= INVALID_SOCKET;
+        ptr->state= MEMCACHED_SERVER_STATE_NEW;
 
-        return MEMCACHED_ERRNO;
+        return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
       }
     }
   }
 
   // This should only be possible from ERESTART or EINTR;
-  ptr->cached_errno= get_socket_errno();
-
-  return MEMCACHED_ERRNO;
+  return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
 }
 
 static memcached_return_t set_hostinfo(memcached_server_st *server)
 {
-  char str_port[NI_MAXSERV];
-
   assert(! server->address_info); // We cover the case where a programming mistake has been made.
   if (server->address_info)
   {
@@ -138,6 +135,7 @@ static memcached_return_t set_hostinfo(memcached_server_st *server)
     server->address_info_next= NULL;
   }
 
+  char str_port[NI_MAXSERV];
   int length= snprintf(str_port, NI_MAXSERV, "%u", (uint32_t)server->port);
   if (length >= NI_MAXSERV || length < 0)
     return MEMCACHED_FAILURE;
@@ -175,7 +173,7 @@ static memcached_return_t set_hostinfo(memcached_server_st *server)
     return memcached_set_error(*server, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_BADFLAGS)"));
 
   case EAI_MEMORY:
-    return memcached_set_error(*server, MEMCACHED_ERRNO, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_MEMORY)"));
+    return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("getaddrinfo(EAI_MEMORY)"));
 
   default:
     {
@@ -185,17 +183,18 @@ static memcached_return_t set_hostinfo(memcached_server_st *server)
     }
   }
   server->address_info_next= server->address_info;
+  server->state= MEMCACHED_SERVER_STATE_ADDRINFO;
 
   return MEMCACHED_SUCCESS;
 }
 
-static inline memcached_return_t set_socket_nonblocking(memcached_server_st *ptr)
+static inline void set_socket_nonblocking(memcached_server_st *ptr)
 {
 #ifdef WIN32
   u_long arg = 1;
   if (ioctlsocket(ptr->fd, FIONBIO, &arg) == SOCKET_ERROR)
   {
-    return memcached_set_errno(*ptr, get_socket_errno(), NULL);
+    memcached_set_errno(*ptr, get_socket_errno(), NULL);
   }
 #else
   int flags;
@@ -203,12 +202,11 @@ static inline memcached_return_t set_socket_nonblocking(memcached_server_st *ptr
   do
   {
     flags= fcntl(ptr->fd, F_GETFL, 0);
-  }
-  while (flags == -1 && (errno == EINTR || errno == EAGAIN));
+  } while (flags == -1 && (errno == EINTR || errno == EAGAIN));
 
-  unlikely (flags == -1)
+  if (flags == -1)
   {
-    return memcached_set_errno(*ptr, errno, NULL);
+    memcached_set_errno(*ptr, errno, NULL);
   }
   else if ((flags & O_NONBLOCK) == 0)
   {
@@ -217,24 +215,22 @@ static inline memcached_return_t set_socket_nonblocking(memcached_server_st *ptr
     do
     {
       rval= fcntl(ptr->fd, F_SETFL, flags | O_NONBLOCK);
-    }
-    while (rval == -1 && (errno == EINTR || errno == EAGAIN));
+    } while (rval == -1 && (errno == EINTR || errno == EAGAIN));
 
     unlikely (rval == -1)
     {
-      return memcached_set_errno(*ptr, errno, NULL);
+      memcached_set_errno(*ptr, errno, NULL);
     }
   }
 #endif
-  return MEMCACHED_SUCCESS;
 }
 
-static memcached_return_t set_socket_options(memcached_server_st *ptr)
+static void set_socket_options(memcached_server_st *ptr)
 {
   WATCHPOINT_ASSERT(ptr->fd != -1);
 
   if (ptr->type == MEMCACHED_CONNECTION_UDP)
-    return MEMCACHED_SUCCESS;
+    return;
 
 #ifdef HAVE_SNDTIMEO
   if (ptr->root->snd_timeout)
@@ -248,8 +244,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDTIMEO,
                       &waittime, (socklen_t)sizeof(struct timeval));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 #endif
 
@@ -265,15 +259,13 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVTIMEO,
                       &waittime, (socklen_t)sizeof(struct timeval));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 #endif
 
 
 #if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
   {
-    int set = 1;
+    int set= 1;
     int error= setsockopt(ptr->fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
 
     // This is not considered a fatal error
@@ -295,8 +287,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, SOL_SOCKET, SO_LINGER,
                       &linger, (socklen_t)sizeof(struct linger));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 
   if (ptr->root->flags.tcp_nodelay)
@@ -307,8 +297,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_NODELAY,
                       &flag, (socklen_t)sizeof(int));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 
   if (ptr->root->flags.tcp_keepalive)
@@ -319,8 +307,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, SOL_SOCKET, SO_KEEPALIVE,
                       &flag, (socklen_t)sizeof(int));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 
 #ifdef TCP_KEEPIDLE
@@ -331,8 +317,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, IPPROTO_TCP, TCP_KEEPIDLE,
                       &ptr->root->tcp_keepidle, (socklen_t)sizeof(int));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 #endif
 
@@ -343,8 +327,6 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, SOL_SOCKET, SO_SNDBUF,
                       &ptr->root->send_size, (socklen_t)sizeof(int));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 
   if (ptr->root->recv_size > 0)
@@ -354,13 +336,11 @@ static memcached_return_t set_socket_options(memcached_server_st *ptr)
     error= setsockopt(ptr->fd, SOL_SOCKET, SO_RCVBUF,
                       &ptr->root->recv_size, (socklen_t)sizeof(int));
     WATCHPOINT_ASSERT(error == 0);
-    if (error)
-      return MEMCACHED_FAILURE;
   }
 
 
   /* libmemcached will always use nonblocking IO to avoid write deadlocks */
-  return set_socket_nonblocking(ptr);
+  set_socket_nonblocking(ptr);
 }
 
 static memcached_return_t unix_socket_connect(memcached_server_st *ptr)
@@ -379,25 +359,29 @@ static memcached_return_t unix_socket_connect(memcached_server_st *ptr)
   servAddr.sun_family= AF_UNIX;
   strncpy(servAddr.sun_path, ptr->hostname, sizeof(servAddr.sun_path)); /* Copy filename */
 
-test_connect:
-  if (connect(ptr->fd,
-              (struct sockaddr *)&servAddr,
-              sizeof(servAddr)) < 0)
-  {
-    switch (errno)
+  do {
+    if (connect(ptr->fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
     {
-    case EINPROGRESS:
-    case EALREADY:
-    case EINTR:
-      goto test_connect;
-    case EISCONN: /* We were spinning waiting on connect */
-      break;
-    default:
-      WATCHPOINT_ERRNO(errno);
-      ptr->cached_errno= errno;
-      return MEMCACHED_ERRNO;
+      switch (errno)
+      {
+      case EINPROGRESS:
+      case EALREADY:
+      case EINTR:
+        continue;
+
+      case EISCONN: /* We were spinning waiting on connect */
+        {
+          WATCHPOINT_ASSERT(0); // Programmer error
+          break;
+        }
+
+      default:
+        WATCHPOINT_ERRNO(errno);
+        return memcached_set_errno(*ptr, errno, MEMCACHED_AT);
+      }
     }
-  }
+  } while (0);
+  ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
 
   WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
 
@@ -417,6 +401,7 @@ static memcached_return_t network_connect(memcached_server_st *ptr)
 
   if (not ptr->address_info)
   {
+    WATCHPOINT_ASSERT(ptr->state == MEMCACHED_SERVER_STATE_NEW);
     memcached_return_t rc;
     uint32_t counter= 5;
     while (--counter)
@@ -455,67 +440,87 @@ static memcached_return_t network_connect(memcached_server_st *ptr)
       return memcached_set_errno(*ptr, get_socket_errno(), NULL);
     }
 
-    (void)set_socket_options(ptr);
+    set_socket_options(ptr);
 
     /* connect to server */
     if ((connect(ptr->fd, ptr->address_info_next->ai_addr, ptr->address_info_next->ai_addrlen) != SOCKET_ERROR))
     {
+      ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
       break; // Success
     }
 
     /* An error occurred */
-    ptr->cached_errno= get_socket_errno();
-    switch (ptr->cached_errno) 
+    switch (get_socket_errno())
     {
+    case ETIMEDOUT:
+      timeout_error_occured= true;
+      break;
+
     case EWOULDBLOCK:
     case EINPROGRESS: // nonblocking mode - first return
     case EALREADY: // nonblocking mode - subsequent returns
       {
+        ptr->state= MEMCACHED_SERVER_STATE_IN_PROGRESS;
         memcached_return_t rc= connect_poll(ptr);
 
+        if (memcached_success(rc))
+        {
+          ptr->state= MEMCACHED_SERVER_STATE_CONNECTED;
+          return MEMCACHED_SUCCESS;
+        }
+
+        // A timeout here is treated as an error, we will not retry
         if (rc == MEMCACHED_TIMEOUT)
+        {
           timeout_error_occured= true;
-
-        if (rc == MEMCACHED_SUCCESS)
-          break;
+        }
       }
+      break;
 
     case EISCONN: // we are connected :-)
+      WATCHPOINT_ASSERT(0); // This is a programmer's error
       break;
 
     case EINTR: // Special case, we retry ai_addr
       (void)closesocket(ptr->fd);
       ptr->fd= INVALID_SOCKET;
+      ptr->state= MEMCACHED_SERVER_STATE_NEW;
       continue;
 
     default:
-      (void)closesocket(ptr->fd);
-      ptr->fd= INVALID_SOCKET;
-      ptr->address_info_next= ptr->address_info_next->ai_next;
       break;
     }
+
+    (void)closesocket(ptr->fd);
+    ptr->fd= INVALID_SOCKET;
+    ptr->address_info_next= ptr->address_info_next->ai_next;
   }
 
-  if (ptr->fd == INVALID_SOCKET)
-  {
-    WATCHPOINT_STRING("Never got a good file descriptor");
+  WATCHPOINT_ASSERT(ptr->fd == INVALID_SOCKET);
 
-    /* Failed to connect. schedule next retry */
-    if (ptr->root->retry_timeout)
+  if (timeout_error_occured)
+  {
+    if (ptr->fd != INVALID_SOCKET)
     {
-      struct timeval next_time;
-
-      if (gettimeofday(&next_time, NULL) == 0)
-        ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
+      (void)closesocket(ptr->fd);
+      ptr->fd= INVALID_SOCKET;
     }
+  }
 
-    if (timeout_error_occured)
-      return MEMCACHED_TIMEOUT;
+  WATCHPOINT_STRING("Never got a good file descriptor");
+  /* Failed to connect. schedule next retry */
+  if (ptr->root->retry_timeout)
+  {
+    struct timeval next_time;
 
-    return MEMCACHED_ERRNO; /* The last error should be from connect() */
+    if (gettimeofday(&next_time, NULL) == 0)
+      ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
   }
 
-  return MEMCACHED_SUCCESS; /* The last error should be from connect() */
+  if (timeout_error_occured)
+    return memcached_set_error(*ptr, MEMCACHED_TIMEOUT, MEMCACHED_AT);
+
+  return memcached_set_error(*ptr, MEMCACHED_CONNECTION_FAILURE, MEMCACHED_AT); /* The last error should be from connect() */
 }
 
 void set_last_disconnected_host(memcached_server_write_instance_st self)
index 1005cb90987d46ab442cf3438e56c8c5b59df7ab..1ae891a7bea073a4b1dda5763de5b6126faf6011 100644 (file)
@@ -158,6 +158,7 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
     {
       if (send_length > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
         return MEMCACHED_WRITE_FAILURE;
+
       if (send_length + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
         memcached_io_write(instance, NULL, 0, true);
     }
@@ -216,6 +217,7 @@ static inline memcached_return_t binary_delete(memcached_st *ptr,
     size_t cmd_size= sizeof(request.bytes) + key_length;
     if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
       return MEMCACHED_WRITE_FAILURE;
+
     if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
       memcached_io_write(instance, NULL, 0, true);
   }
index 14824a641aec79c659c8fbdc8f94ae912894f176..854c611497c36b60a2286450cbb2b05f75861a54 100644 (file)
@@ -9,7 +9,7 @@
  *
  */
 
-#include "common.h"
+#include <libmemcached/common.h>
 
 memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const void *command,
                                 size_t command_length, bool with_flush)
@@ -20,8 +20,9 @@ memcached_return_t memcached_do(memcached_server_write_instance_st ptr, const vo
   WATCHPOINT_ASSERT(command_length);
   WATCHPOINT_ASSERT(command);
 
-  if ((rc= memcached_connect(ptr)) != MEMCACHED_SUCCESS)
+  if (memcached_failed(rc= memcached_connect(ptr)))
   {
+    WATCHPOINT_ASSERT(rc == memcached_last_error(ptr->root));
     WATCHPOINT_ERROR(rc);
     return rc;
   }
index b5e947a43ae91705f5cb12aeb0a440f6c4b2d29c..16608ff9eeb8b473cc9581e539c9fc553c6bae24 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include <libmemcached/common.h>
+#include <cassert>
 
 #define MAX_ERROR_LENGTH 2048
 struct memcached_error_t
@@ -120,18 +121,21 @@ static void _set(memcached_st& memc, memcached_string_t *str, memcached_return_t
 
 memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc, const char *at, const char *str, size_t length)
 {
+  assert(rc != MEMCACHED_ERRNO);
   memcached_string_t tmp= { str, length };
   return memcached_set_error(memc, rc, at, tmp);
 }
 
 memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at, const char *str, size_t length)
 {
+  assert(rc != MEMCACHED_ERRNO);
   memcached_string_t tmp= { str, length };
   return memcached_set_error(self, rc, at, tmp);
 }
 
 memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc, const char *at, memcached_string_t& str)
 {
+  assert(rc != MEMCACHED_ERRNO);
   if (memcached_success(rc))
     return MEMCACHED_SUCCESS;
 
@@ -142,6 +146,7 @@ memcached_return_t memcached_set_error(memcached_st& memc, memcached_return_t rc
 
 memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at, memcached_string_t& str)
 {
+  assert(rc != MEMCACHED_ERRNO);
   if (memcached_success(rc))
     return MEMCACHED_SUCCESS;
 
@@ -171,6 +176,7 @@ memcached_return_t memcached_set_error(memcached_server_st& self, memcached_retu
 
 memcached_return_t memcached_set_error(memcached_server_st& self, memcached_return_t rc, const char *at)
 {
+  assert(rc != MEMCACHED_ERRNO);
   if (memcached_success(rc))
     return MEMCACHED_SUCCESS;
 
@@ -189,6 +195,7 @@ memcached_return_t memcached_set_error(memcached_server_st& self, memcached_retu
 
 memcached_return_t memcached_set_error(memcached_st& self, memcached_return_t rc, const char *at)
 {
+  assert(rc != MEMCACHED_ERRNO);
   if (memcached_success(rc))
     return MEMCACHED_SUCCESS;
 
index fb4b00226d7c1b40fdf3fa789920c245e7ce4214..40aaec2044b277a6bf40275021ead86e74be94d9 100644 (file)
@@ -295,8 +295,6 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr,
         }
         else if (data_read == SOCKET_ERROR)
         {
-          ptr->cached_errno= get_socket_errno();
-          memcached_return_t rc= MEMCACHED_ERRNO;
           switch (get_socket_errno())
           {
           case EWOULDBLOCK:
@@ -307,8 +305,10 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr,
 #ifdef TARGET_OS_LINUX
           case ERESTART:
 #endif
-            if ((rc= io_wait(ptr, MEM_READ)) == MEMCACHED_SUCCESS)
+            if (memcached_success(io_wait(ptr, MEM_READ)))
+            {
               continue;
+            }
 
             /* fall through */
 
@@ -316,7 +316,7 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr,
             {
               memcached_quit_server(ptr, true);
               *nread= -1;
-              return memcached_set_error(*ptr, rc, MEMCACHED_AT);
+              return memcached_set_errno(*ptr, get_socket_errno(), MEMCACHED_AT);
             }
           }
         }
@@ -497,6 +497,8 @@ memcached_return_t memcached_io_close(memcached_server_write_instance_st ptr)
   {
     WATCHPOINT_ERRNO(get_socket_errno());
   }
+  ptr->state= MEMCACHED_SERVER_STATE_NEW;
+  ptr->fd= INVALID_SOCKET;
 
   return MEMCACHED_SUCCESS;
 }
index f2e8993b5f57200b25372a416890eb34af35fd4b..ee95eaa165c2305ee0d1a31bca48f5bbcdaf53e2 100644 (file)
@@ -311,9 +311,8 @@ void memcached_free(memcached_st *ptr)
 memcached_st *memcached_clone(memcached_st *clone, const memcached_st *source)
 {
   memcached_return_t rc= MEMCACHED_SUCCESS;
-  memcached_st *new_clone;
 
-  if (source == NULL)
+  if (not source)
     return memcached_create(clone);
 
   if (clone && memcached_is_allocated(clone))
@@ -321,9 +320,9 @@ memcached_st *memcached_clone(memcached_st *clone, const memcached_st *source)
     return NULL;
   }
 
-  new_clone= memcached_create(clone);
+  memcached_st *new_clone= memcached_create(clone);
 
-  if (new_clone == NULL)
+  if (not new_clone)
     return NULL;
 
   new_clone->flags= source->flags;
index fb045ce1d9a05545e95d8a75dd0b961386e62a7d..b44b508e27ea00eacd3e6738d417a9a319902208 100644 (file)
@@ -101,7 +101,6 @@ void memcached_quit_server(memcached_server_st *ptr, bool io_death)
     memcached_io_close(ptr);
   }
 
-  ptr->fd= INVALID_SOCKET;
   ptr->io_bytes_sent= 0;
   ptr->write_buffer_offset= (size_t) ((ptr->type == MEMCACHED_CONNECTION_UDP) ? UDP_DATAGRAM_HEADER_LENGTH : 0);
   ptr->read_buffer_length= 0;
index 57540ccff06d150f9db5c1ed5e997ffe086a7783..ea88967d444716d4599e8194f832d12b2436a0c2 100644 (file)
@@ -69,6 +69,8 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root,
   self->address_info= NULL;
   self->address_info_next= NULL;
 
+  self->state= MEMCACHED_SERVER_STATE_NEW;
+
   if (root)
   {
     self->next_retry= root->retry_timeout;
@@ -80,13 +82,13 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root,
 
   self->root= root;
   self->limit_maxbytes= 0;
-  if (hostname == NULL)
+  if (hostname)
   {
-    self->hostname[0]= 0;
+    strncpy(self->hostname, hostname, NI_MAXHOST - 1);
   }
   else
   {
-    strncpy(self->hostname, hostname, NI_MAXHOST - 1);
+    self->hostname[0]= 0;
   }
 }
 
@@ -294,8 +296,7 @@ void memcached_server_list_free(memcached_server_list_st self)
     }
   }
 
-  memcached_st *root= self->root;
-  libmemcached_free(root, self);
+  libmemcached_free(self->root, self);
 }
 
 uint32_t memcached_servers_set_count(memcached_server_st *servers, uint32_t count)
index d4005f89c222cfb456916a2fdacc50e8e887aeae..aeb493fe9cdf0edf6461acc6f1c98f5e8642806c 100644 (file)
 
 #pragma once
 
+enum memcached_server_state_t {
+  MEMCACHED_SERVER_STATE_NEW,
+  MEMCACHED_SERVER_STATE_ADDRINFO,
+  MEMCACHED_SERVER_STATE_IN_PROGRESS,
+  MEMCACHED_SERVER_STATE_CONNECTED
+};
+
 struct memcached_server_st {
   struct {
     bool is_allocated:1;
@@ -53,6 +60,7 @@ struct memcached_server_st {
   uint32_t io_bytes_sent; /* # bytes sent since last read */
   uint32_t server_failure_counter;
   uint32_t weight;
+  enum memcached_server_state_t state;
   struct {
     uint32_t read;
     uint32_t write;
index d5d34a84285562b9510dc174e38f9a122c01a309..5a2013e815b9d44a5da236dc0250170ee456527e 100644 (file)
@@ -577,14 +577,11 @@ char ** memcached_stat_get_keys(memcached_st *ptr,
   return list;
 }
 
-void memcached_stat_free(const memcached_st *ptr, memcached_stat_st *memc_stat)
+void memcached_stat_free(const memcached_st *, memcached_stat_st *memc_stat)
 {
-  if (not ptr)
-    return;
-
+  WATCHPOINT_ASSERT(memc_stat); // Be polite, but when debugging catch this as an error
   if (not memc_stat)
   {
-    WATCHPOINT_ASSERT(0); /* Be polite, but when debugging catch this as an error */
     return;
   }
 
@@ -594,7 +591,7 @@ void memcached_stat_free(const memcached_st *ptr, memcached_stat_st *memc_stat)
     return;
   }
 
-  libmemcached_free(ptr, memc_stat);
+  libmemcached_free(NULL, memc_stat);
 }
 
 static memcached_return_t call_stat_fn(memcached_st *ptr,
index 006393c484df526b1c864d2dbb83597152ac7591..c6d653c14717608535ab4c984a81cc393257a250 100644 (file)
@@ -68,7 +68,6 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
   bool to_write;
   size_t write_length;
   char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-  uint32_t server_key;
   memcached_server_write_instance_st instance;
 
   WATCHPOINT_ASSERT(!(value == NULL && value_length > 0));
@@ -85,7 +84,7 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
   if (ptr->flags.verify_key && (memcached_key_test((const char **)&key, &key_length, 1) == MEMCACHED_BAD_KEY_PROVIDED))
     return MEMCACHED_BAD_KEY_PROVIDED;
 
-  server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
+  uint32_t server_key= memcached_generate_hash_with_redistribution(ptr, group_key, group_key_length);
   instance= memcached_server_instance_fetch(ptr, server_key);
 
   WATCHPOINT_SET(instance->io_wait_count.read= 0);
@@ -142,13 +141,12 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
       buffer_ptr++;
 
       write_length= (size_t)(buffer_ptr - buffer);
-      int check_length;
-      check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer),
-                                    "%u %llu %lu%s\r\n",
-                                    flags,
-                                    (unsigned long long)expiration, (unsigned long)value_length,
-                                    ptr->flags.no_reply ? " noreply" : "");
-      if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer) || check_length < 0)
+      int check_length= snprintf(buffer_ptr, MEMCACHED_DEFAULT_COMMAND_SIZE -(size_t)(buffer_ptr - buffer),
+                                 "%u %llu %lu%s\r\n",
+                                 flags,
+                                 (unsigned long long)expiration, (unsigned long)value_length,
+                                 ptr->flags.no_reply ? " noreply" : "");
+      if ((size_t)check_length >= MEMCACHED_DEFAULT_COMMAND_SIZE -size_t(buffer_ptr - buffer) || check_length < 0)
       {
         rc= MEMCACHED_WRITE_FAILURE;
         memcached_io_reset(instance);
@@ -162,16 +160,17 @@ static inline memcached_return_t memcached_send(memcached_st *ptr,
 
     if (ptr->flags.use_udp && ptr->flags.buffer_requests)
     {
-      size_t cmd_size= write_length + value_length + 2;
+      size_t cmd_size= write_length + value_length +2;
       if (cmd_size > MAX_UDP_DATAGRAM_LENGTH - UDP_DATAGRAM_HEADER_LENGTH)
-        return MEMCACHED_WRITE_FAILURE;
+        return memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
+
       if (cmd_size + instance->write_buffer_offset > MAX_UDP_DATAGRAM_LENGTH)
         memcached_io_write(instance, NULL, 0, true);
     }
 
     if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
     {
-      rc= MEMCACHED_WRITE_FAILURE;
+      rc= memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT);
     }
     else
     {
index 48a970aa238b87d8e0b8420214ec16e8f90c22c4..d378182427e60154a022d1d5e26692163e772c14 100644 (file)
@@ -47,9 +47,9 @@ const char *memcached_strerror(memcached_st *, memcached_return_t rc)
     return "FAILURE";
   case MEMCACHED_HOST_LOOKUP_FAILURE: // getaddrinfo only
     return "getaddrinfo() HOSTNAME LOOKUP FAILURE";
-  case MEMCACHED_CONNECTION_FAILURE: // DEPRECATED
+  case MEMCACHED_CONNECTION_FAILURE:
     return "CONNECTION FAILURE";
-  case MEMCACHED_CONNECTION_BIND_FAILURE:
+  case MEMCACHED_CONNECTION_BIND_FAILURE: // DEPRECATED, see MEMCACHED_HOST_LOOKUP_FAILURE
     return "CONNECTION BIND FAILURE";
   case MEMCACHED_READ_FAILURE:
     return "READ FAILURE";
index 8c6d296cf412f6e677a41da8fa393fdfb3c52631..1c3ea100f263e1670a989b8107dbd72be26d4a2b 100644 (file)
@@ -258,12 +258,15 @@ void server_startup(server_startup_st *construct)
           switch (errno)
           {
           default:
-            fprintf(stderr, "%s -> fopen(%s)\n", construct->pid_file[x], strerror(errno));
+            fprintf(stderr, "Could not open pid file %s -> fopen(%s) -> %s:%d\n", construct->pid_file[x], strerror(errno),
+                    __FILE__, __LINE__);
             abort();
           case ENOENT:
           case EINTR:
           case EACCES:
+          case EINPROGRESS:
             break;
+
           case ENOTCONN:
             continue;
           }
index 0493f3106b1b4b657aefb312d6195fb49a141af5..29959283ca1078b629689e6326427e50e5c6c117 100644 (file)
@@ -228,6 +228,15 @@ do \
   } \
 } while (0)
 
+#define test_skip(A,B) \
+do \
+{ \
+  if ((A) != (B)) \
+  { \
+    return TEST_SKIPPED; \
+  } \
+} while (0)
+
 #define test_compare_got(A,B,C) \
 do \
 { \
index 093721b5cd29e52c64409b075b167cfeab4eaf7e..c74b6b1ed78d46291122b1bff54ccde4e673ca5a 100644 (file)
@@ -1809,10 +1809,7 @@ static test_return_t mget_execute(memcached_st *memc)
 
 static test_return_t key_setup(memcached_st *memc)
 {
-  (void)memc;
-
-  if (pre_binary(memc) != TEST_SUCCESS)
-    return TEST_SKIPPED;
+  test_skip(TEST_SUCCESS, pre_binary(memc));
 
   global_pairs= pairs_generate(REGRESSION_BINARY_VS_BLOCK_COUNT, 0);
 
@@ -1881,22 +1878,17 @@ static test_return_t version_string_test(memcached_st *memc)
 
 static test_return_t get_stats(memcached_st *memc)
 {
- char **stat_list;
- char **ptr;
  memcached_return_t rc;
- memcached_stat_st *memc_stat;
-
- memc_stat= memcached_stat(memc, NULL, &rc);
- test_true(rc == MEMCACHED_SUCCESS);
 
- test_true(rc == MEMCACHED_SUCCESS);
+ memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc);
+ test_compare(MEMCACHED_SUCCESS, rc);
  test_true(memc_stat);
 
  for (uint32_t x= 0; x < memcached_server_count(memc); x++)
  {
-   stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
-   test_true(rc == MEMCACHED_SUCCESS);
-   for (ptr= stat_list; *ptr; ptr++);
+   char **stat_list= memcached_stat_get_keys(memc, memc_stat+x, &rc);
+   test_compare(MEMCACHED_SUCCESS, rc);
+   for (char **ptr= stat_list; *ptr; ptr++);
 
    free(stat_list);
  }
@@ -3411,8 +3403,7 @@ static test_return_t get_read(memcached_st *memc)
 static test_return_t mget_read(memcached_st *memc)
 {
 
-  if (not libmemcached_util_version_check(memc, 1, 4, 4))
-    return TEST_SKIPPED;
+  test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
 
   memcached_return_t rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
 
@@ -3434,8 +3425,7 @@ static test_return_t mget_read(memcached_st *memc)
 static test_return_t mget_read_result(memcached_st *memc)
 {
 
-  if (not libmemcached_util_version_check(memc, 1, 4, 4))
-    return TEST_SKIPPED;
+  test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
 
   memcached_return_t rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
 
@@ -3460,9 +3450,7 @@ static test_return_t mget_read_result(memcached_st *memc)
 
 static test_return_t mget_read_function(memcached_st *memc)
 {
-
-  if (not libmemcached_util_version_check(memc, 1, 4, 4))
-    return TEST_SKIPPED;
+  test_skip(true, bool(libmemcached_util_version_check(memc, 1, 4, 4)));
 
   memcached_return_t rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
 
@@ -3730,7 +3718,7 @@ static test_return_t pre_sasl(memcached_st *memc)
 
 static test_return_t pre_replication(memcached_st *memc)
 {
-  test_true(TEST_SUCCESS == pre_binary(memc));
+  test_skip(TEST_SUCCESS, pre_binary(memc));
 
   /*
    * Make sure that we store the item on all servers
@@ -3747,7 +3735,7 @@ static test_return_t pre_replication(memcached_st *memc)
 
 static test_return_t pre_replication_noblock(memcached_st *memc)
 {
-  test_compare(TEST_SUCCESS, pre_replication(memc));
+  test_skip(TEST_SUCCESS, pre_replication(memc));
 
   return pre_nonblock(memc);
 }
@@ -4768,7 +4756,6 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
 {
   (void)memc;
   memcached_st *tl_memc_h;
-  memcached_server_st *servers;
 
   const char *key= "MemcachedLives";
   size_t len;
@@ -4778,7 +4765,8 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
 
   // Create a handle.
   tl_memc_h= memcached_create(NULL);
-  servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
+  memcached_server_st *servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
+  test_true(servers);
   memcached_server_push(tl_memc_h, servers);
   memcached_server_list_free(servers);
 
@@ -4786,7 +4774,7 @@ static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
   value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc);
 
   test_false(value);
-  test_true(len == 0);
+  test_compare(0, len);
   test_false(rc == MEMCACHED_SUCCESS);
 
   memcached_free(tl_memc_h);
@@ -5437,7 +5425,7 @@ static test_return_t test_multiple_get_last_disconnect(memcached_st *)
     {
       const char *msg=  memcached_strerror(memc, memcached_return_t(x));
       memcached_return_t ret= memcached_set(memc, msg, strlen(msg), NULL, 0, (time_t)0, (uint32_t)0);
-      test_compare_got(MEMCACHED_WRITE_FAILURE, ret, memcached_strerror(NULL, ret));
+      test_compare_got(MEMCACHED_CONNECTION_FAILURE, ret, memcached_last_error_message(memc));
 
       memcached_server_instance_st disconnected_server= memcached_server_get_last_disconnect(memc);
       test_true(disconnected_server);
index 13561bcc29b03e19719e8ed417f26ac2902a0e74..bb2de83f3ba3be786184a1e8df7c34ca74dbe405 100644 (file)
@@ -566,7 +566,7 @@ test_return_t regression_bug_71231153_connect(memcached_st *)
     char *value= memcached_get(memc, memcached_literal_param("test"), &value_len, NULL, &rc);
     test_false(value);
     test_compare(0, value_len);
-    test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_strerror(NULL, rc));
+    test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_strerror(NULL, rc));
 
     memcached_free(memc);
   }