Updates to clean server structure.
authorBrian Aker <brian@tangent.org>
Sat, 13 Oct 2007 00:13:33 +0000 (17:13 -0700)
committerBrian Aker <brian@tangent.org>
Sat, 13 Oct 2007 00:13:33 +0000 (17:13 -0700)
Addition for wildcard tests.
Fix for multi, aka three, hosts for key reads.

include/memcached.h
lib/memcached_connect.c
lib/memcached_get.c
lib/memcached_hosts.c
lib/memcached_io.c
lib/memcached_quit.c
lib/memcached_response.c
tests/test.c

index 558fbb09e22273d8764fa8dbeaab63e1722d49c1..6797279b5dbf0e701a6f13375e01fa09aa8abcd3 100644 (file)
@@ -88,6 +88,7 @@ struct memcached_server_st {
   unsigned int port;
   int fd;
   unsigned int stack_responses;
+  unsigned int cursor_active;
 };
 
 struct memcached_stat_st {
index 116423cea9d98ce926f94684fb84e758a24f7aba..57274be2086a17d35192dd98bd68c54716de2507 100644 (file)
@@ -13,6 +13,9 @@ memcached_return memcached_real_connect(memcached_st *ptr, unsigned int server_k
 
   if (ptr->hosts[server_key].fd == -1)
   {
+    /* Old connection junk still is in the structure */
+    assert(ptr->hosts[server_key].stack_responses == 0);
+
     if ((h= gethostbyname(ptr->hosts[server_key].hostname)) == NULL)
     {
       ptr->my_errno= h_errno;
@@ -72,6 +75,7 @@ test_connect:
       }
       ptr->connected++;
     }
+    assert(ptr->hosts[server_key].stack_responses == 0);
   }
 
   return MEMCACHED_SUCCESS;
index 4894b2a05ef32334a9f26029057412ee5ac2dda7..251cd59201c0ac67236cf289b6ee48006185af2f 100644 (file)
@@ -85,14 +85,13 @@ static char *memcached_value_fetch(memcached_st *ptr, char *key, size_t *key_len
 
       /* We add two bytes so that we can walk the \r\n */
       value= (char *)malloc(((*value_length) +2) * sizeof(char));
-      memset(value, 0, ((*value_length) +2) * sizeof(char));
-
       if (!value)
       {
         *value_length= 0;
         *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
         return NULL;
       }
+      memset(value, 0, ((*value_length) +2) * sizeof(char));
 
       value_ptr= value;
       read_length= 0;
@@ -164,6 +163,8 @@ char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
     *error= MEMCACHED_NOTFOUND;
     goto error;
   }
+  else if (*error == MEMCACHED_END)
+    assert(0); /* If this happens we have somehow messed up the fetch */
   else if (*error == MEMCACHED_SUCCESS)
   {
     memcached_return rc;
@@ -259,7 +260,10 @@ memcached_return memcached_mget(memcached_st *ptr,
       }
       memcached_string_free(ptr, string);
       cursor_key_exec[x]= NULL; /* Remove warning */
+      ptr->hosts[x].cursor_active= 1;
     }
+    else
+      ptr->hosts[x].cursor_active= 0;
   }
 
   free(cursor_key_exec);
@@ -277,16 +281,28 @@ char *memcached_fetch(memcached_st *ptr, char *key, size_t *key_length,
 
   while (ptr->cursor_server < ptr->number_of_hosts)
   {
+    if (!ptr->hosts[ptr->cursor_server].cursor_active)
+    {
+      ptr->cursor_server++;
+      continue;
+    }
+
     value_check= memcached_value_fetch(ptr, key, key_length, value_length, flags,
                                        error, 1, ptr->cursor_server);
     
     if (*error == MEMCACHED_NOTFOUND)
       ptr->cursor_server++;
+    else if (*error == MEMCACHED_END && *value_length == 0)
+      return NULL;
+    else if (*error == MEMCACHED_END)
+      assert(0); /* If this happens we have somehow messed up the fetch */
     else if (*error != MEMCACHED_SUCCESS)
       return NULL;
     else
       return value_check;
+
   }
 
+  *value_length= 0;
   return NULL;
 }
index 64892212009361da7d5b47ac37acd8e5acf984fd..0fcf4cdb9e7c7c38048ba470a96e68f249618224 100644 (file)
@@ -1,6 +1,15 @@
 #include <memcached.h>
 #include "common.h"
 
+static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port)
+{
+  host->stack_responses= 0;
+  host->cursor_active= 0;
+  host->hostname= new_hostname;
+  host->port= port;
+  host->fd= -1;
+}
+
 memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
 {
   unsigned int x;
@@ -26,9 +35,11 @@ memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *l
     ptr->hosts[ptr->number_of_hosts].hostname= strdup(list[x].hostname);
     ptr->hosts[ptr->number_of_hosts].port= list[x].port;
     ptr->hosts[ptr->number_of_hosts].fd= list[x].fd;
+    ptr->hosts[ptr->number_of_hosts].stack_responses= list[x].stack_responses;
+    ptr->hosts[ptr->number_of_hosts].cursor_active= list[x].cursor_active;
     ptr->number_of_hosts++;
   }
-  memset(&ptr->hosts[ptr->number_of_hosts], 0, sizeof(memcached_server_st));
+  host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0);
 
   return MEMCACHED_SUCCESS;
 }
@@ -52,7 +63,7 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne
                                                   sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
     if (!new_host_list)
       return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-    memset(&new_host_list[ptr->number_of_hosts], 0, sizeof(memcached_server_st));
+    host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0);
   }
   else
   {
@@ -60,7 +71,8 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne
       (memcached_server_st *)malloc(sizeof(memcached_server_st) * 2);
     if (!new_host_list)
       return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
-    memset(new_host_list, 0, sizeof(memcached_server_st) * 2);
+    host_reset(&new_host_list[0], NULL, 0);
+    host_reset(&new_host_list[1], NULL, 0);
   }
 
   ptr->hosts= new_host_list;
@@ -73,9 +85,7 @@ memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigne
 
   memset(new_hostname, 0, strlen(hostname)+1);
   memcpy(new_hostname, hostname, strlen(hostname));
-  ptr->hosts[ptr->number_of_hosts].hostname= new_hostname;
-  ptr->hosts[ptr->number_of_hosts].port= port;
-  ptr->hosts[ptr->number_of_hosts].fd= -1;
+  host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port);
   ptr->number_of_hosts++;
 
   LIBMEMCACHED_MEMCACHED_SERVER_ADD_END();
@@ -105,7 +115,7 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
     new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
     if (!new_host_list)
       goto error;
-    memset(&new_host_list[count-1], 0, sizeof(memcached_server_st));
+    host_reset(&new_host_list[count-1], NULL, 0);
   }
   else
   {
@@ -113,7 +123,8 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
     new_host_list= (memcached_server_st *)malloc(sizeof(memcached_server_st) * count);
     if (!new_host_list)
       goto error;
-    memset(new_host_list, 0, sizeof(memcached_server_st) * 2);
+    host_reset(&new_host_list[0], NULL, 0);
+    host_reset(&new_host_list[1], NULL, 0);
   }
 
   new_hostname= strdup(hostname);
@@ -121,9 +132,7 @@ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
   if (!new_hostname)
     goto error;
 
-  new_host_list[count-2].hostname= new_hostname;
-  new_host_list[count-2].port= port;
-  new_host_list[count-2].fd= -1;
+  host_reset(&new_host_list[count-2], new_hostname, port);
 
   *error= MEMCACHED_SUCCESS;
   return new_host_list;
index 2f86930e3690f482c34a2fd7c523ba4d2c316677..5e05d2c5ac8a84206541754533f1ed325d4a3d3f 100644 (file)
@@ -9,53 +9,44 @@
 ssize_t memcached_io_read(memcached_st *ptr, unsigned  int server_key,
                           char *buffer, size_t length)
 {
-  size_t x;
   char *buffer_ptr;
 
   buffer_ptr= buffer;
 
-  for (x= 0, buffer_ptr= buffer; 
-       x < length; x++)
+  while (length)
   {
     if (!ptr->read_buffer_length)
     {
-      if (length > 1)
-      {
+      size_t data_read;
 
-        size_t data_read;
-        data_read= recv(ptr->hosts[server_key].fd, 
-                        buffer_ptr, 
-                        length - x, 0);
-        if (data_read == -1)
-        {
-          return -1;
-        }
-        if (data_read == 0)
-          return x;
-
-        data_read+= x;
-
-        return data_read;
-      }
-      else
+      while (1)
       {
-        size_t data_read;
-try_again:
-
         if (ptr->flags & MEM_NO_BLOCK)
         {
-          struct timeval local_tv;
-          fd_set set;
-
-          memset(&local_tv, 0, sizeof(struct timeval));
-
-          local_tv.tv_sec= 0;
-          local_tv.tv_usec= 300;
-
-          FD_ZERO(&set);
-          FD_SET(ptr->hosts[server_key].fd, &set);
-
-          select(1, &set, NULL, NULL, &local_tv);
+          while (1)
+          {
+            int select_return;
+            struct timeval local_tv;
+            fd_set set;
+
+            memset(&local_tv, 0, sizeof(struct timeval));
+
+            local_tv.tv_sec= 0;
+            local_tv.tv_usec= 300;
+
+            FD_ZERO(&set);
+            FD_SET(ptr->hosts[server_key].fd, &set);
+
+            select_return= select(1, &set, NULL, NULL, &local_tv);
+
+            if (select_return == -1)
+            {
+              ptr->my_errno= errno;
+              return -1;
+            }
+            else if (!select_return)
+              break;
+          }
         }
 
         data_read= recv(ptr->hosts[server_key].fd, 
@@ -63,26 +54,34 @@ try_again:
                         MEMCACHED_MAX_BUFFER, 0);
         if (data_read == -1)
         {
-          if (errno == EAGAIN)
-            goto try_again;
-          return -1;
+          switch (errno)
+          {
+          case EAGAIN:
+            break;
+          default:
+            {
+              ptr->my_errno= errno;
+              return -1;
+            }
+          }
         }
-        ptr->read_buffer_length= data_read;
-        ptr->read_ptr= ptr->read_buffer;
+        else if (data_read)
+          break;
+        /* If zero, just keep looping */
       }
 
-      if (ptr->read_buffer_length == -1)
-        return -1;
-      if (ptr->read_buffer_length == 0)
-        return x;
+      ptr->read_buffer_length= data_read;
+      ptr->read_ptr= ptr->read_buffer;
     }
+
     *buffer_ptr= *ptr->read_ptr;
-    buffer_ptr++;
+    length--;
     ptr->read_ptr++;
     ptr->read_buffer_length--;
+    buffer_ptr++;
   }
 
-  return length;
+  return (size_t)(buffer_ptr - buffer);
 }
 
 ssize_t memcached_io_write(memcached_st *ptr, unsigned int server_key,
index d7a42315cc39ae6fe6365925814400f18eae7d0b..2ceaa679650b4761c69cff1e7754cda72959642e 100644 (file)
@@ -18,6 +18,7 @@ void memcached_quit_server(memcached_st *ptr, unsigned int server_key)
     close(ptr->hosts[server_key].fd);
     ptr->hosts[server_key].fd= -1;
     ptr->hosts[server_key].stack_responses= 0;
+    ptr->hosts[server_key].cursor_active= 0;
   }
 
   ptr->connected--;
index 10547504743c476956ade3a7a5ebfe664f44aa4c..d0962a2d759e27b27839181d14251f81f02a89e8 100644 (file)
@@ -24,6 +24,7 @@ memcached_return memcached_response(memcached_st *ptr,
   max_messages= memcached_server_response_count(ptr, server_key);
   for (x= 0; x <=  max_messages; x++)
   {
+    size_t total_length= 0;
     buffer_ptr= buffer;
 
     while (1)
@@ -40,6 +41,9 @@ memcached_return memcached_response(memcached_st *ptr,
         break;
       else
         buffer_ptr++;
+
+      total_length++;
+      assert(total_length < buffer_length);
     }
 
     if (memcached_server_response_count(ptr, server_key))
index 714cd89120223fe01883746486f1f7ab51361263..047ed29a95d31d7528dc88a77c54835ca1adee02 100644 (file)
@@ -208,6 +208,8 @@ void get_test3(memcached_st *memc)
   string= memcached_get(memc, key, strlen(key),
                         &string_length, &flags, &rc);
 
+  WATCHPOINT_ERRNO(memc->my_errno);
+  WATCHPOINT_ERROR(rc);
   assert(rc == MEMCACHED_SUCCESS);
   assert(string);
   assert(string_length == value_length);
@@ -570,8 +572,12 @@ int main(int argc, char *argv[])
 {
   unsigned int x;
   char *server_list;
+  char *wildcard= NULL;
   memcached_server_st *servers;
 
+  if (argc == 2)
+    wildcard= argv[1];
+
   if (!(server_list= getenv("MEMCACHED_SERVERS")))
     server_list= "localhost";
 
@@ -581,6 +587,16 @@ int main(int argc, char *argv[])
   servers= memcached_servers_parse(server_list);
   assert(servers);
 
+  for (x= 0; x < memcached_server_list_count(servers); x++)
+  {
+    printf("\t%s : %u\n", servers[x].hostname, servers[x].port);
+    assert(servers[x].stack_responses == 0);
+    assert(servers[x].fd == -1);
+    assert(servers[x].cursor_active == 0);
+  }
+
+  printf("\n");
+
   /* Clean the server before beginning testing */
   test_st tests[] ={
     {"flush", 0, flush_test },
@@ -617,6 +633,10 @@ int main(int argc, char *argv[])
   fprintf(stderr, "\nBlock tests\n\n");
   for (x= 0; tests[x].function_name; x++)
   {
+    if (wildcard)
+      if (strcmp(wildcard, tests[x].function_name))
+        continue;
+
     memcached_st *memc;
     memcached_return rc;
     memc= memcached_create(NULL);
@@ -625,6 +645,14 @@ int main(int argc, char *argv[])
     rc= memcached_server_push(memc, servers);
     assert(rc == MEMCACHED_SUCCESS);
 
+    unsigned int loop;
+    for (loop= 0; loop < memcached_server_list_count(servers); loop++)
+    {
+      assert(memc->hosts[loop].stack_responses == 0);
+      assert(memc->hosts[loop].fd == -1);
+      assert(memc->hosts[loop].cursor_active == 0);
+    }
+
     fprintf(stderr, "Testing %s", tests[x].function_name);
     tests[x].function(memc);
     fprintf(stderr, "\t\t\t\t\t[ ok ]\n");
@@ -635,6 +663,10 @@ int main(int argc, char *argv[])
   fprintf(stderr, "\nNonblock tests\n\n");
   for (x= 0; tests[x].function_name; x++)
   {
+    if (wildcard)
+      if (strcmp(wildcard, tests[x].function_name))
+        continue;
+
     memcached_st *memc;
     memcached_return rc;
     memc= memcached_create(NULL);
@@ -654,6 +686,10 @@ int main(int argc, char *argv[])
   fprintf(stderr, "\nTCP Nodelay tests\n\n");
   for (x= 0; tests[x].function_name; x++)
   {
+    if (wildcard)
+      if (strcmp(wildcard, tests[x].function_name))
+        continue;
+
     memcached_st *memc;
     memcached_return rc;
     memc= memcached_create(NULL);
@@ -674,6 +710,10 @@ int main(int argc, char *argv[])
   fprintf(stderr, "\nMD5 Hashing\n\n");
   for (x= 0; tests[x].function_name; x++)
   {
+    if (wildcard)
+      if (strcmp(wildcard, tests[x].function_name))
+        continue;
+
     memcached_st *memc;
     memcached_return rc;
     memc= memcached_create(NULL);
@@ -693,6 +733,10 @@ int main(int argc, char *argv[])
   fprintf(stderr, "\nUser Supplied tests\n\n");
   for (x= 0; user_tests[x].function_name; x++)
   {
+    if (wildcard)
+      if (strcmp(wildcard, tests[x].function_name))
+        continue;
+
     memcached_st *memc;
     memcached_return rc;
     memc= memcached_create(NULL);