When returning CLIENT_ERROR do not close the socket connection (i.e. it should not...
authorBrian Aker <brian@tangent.org>
Mon, 12 Nov 2012 06:36:53 +0000 (01:36 -0500)
committerBrian Aker <brian@tangent.org>
Mon, 12 Nov 2012 06:36:53 +0000 (01:36 -0500)
libmemcached-1.0/return.h
libmemcached/error.cc
libmemcached/response.cc
tests/libmemcached-1.0/all_tests.h
tests/libmemcached-1.0/mem_functions.cc
tests/libmemcached-1.0/mem_functions.h

index 65dc63af5eb02cb7783200287f9cb5316dc06a86..781603b86e84ec8c8ac97983bba1d7e1e14ba762 100644 (file)
@@ -63,6 +63,7 @@ static inline bool memcached_fatal(memcached_return_t rc)
 {
   return (
           rc != MEMCACHED_BUFFERED &&
+          rc != MEMCACHED_CLIENT_ERROR &&
           rc != MEMCACHED_DATA_EXISTS &&
           rc != MEMCACHED_DELETED &&
           rc != MEMCACHED_E2BIG && 
index f963e12446d42e2570733eea36aaae4187f1adbb..67edcce82aaab93f33b52aab15077386a8ee7c14 100644 (file)
@@ -276,7 +276,7 @@ memcached_return_t memcached_set_error(org::libmemcached::Instance& self, memcac
 {
   assert_msg(rc != MEMCACHED_ERRNO, "Programmer error, MEMCACHED_ERRNO was set to be returned to client");
   assert_msg(rc != MEMCACHED_SOME_ERRORS, "Programmer error, MEMCACHED_SOME_ERRORS was about to be set on a org::libmemcached::Instance");
-  if (memcached_fatal(rc) == false)
+  if (memcached_fatal(rc) == false and rc != MEMCACHED_CLIENT_ERROR)
   {
     return rc;
   }
@@ -295,7 +295,7 @@ memcached_return_t memcached_set_error(org::libmemcached::Instance& self, memcac
 
   memcached_string_t error_host= { hostname_port_message, size_t(size) };
 
-  assert(self.root);
+  assert_msg(self.root, "Programmer error, root was not set on instance");
   if (self.root == NULL)
   {
     return rc;
@@ -305,6 +305,7 @@ memcached_return_t memcached_set_error(org::libmemcached::Instance& self, memcac
   _set(self, (*self.root));
   assert(self.root->error_messages);
   assert(self.error_messages);
+  assert(self.error_messages->rc == self.root->error_messages->rc);
 
   return rc;
 }
@@ -411,6 +412,15 @@ memcached_return_t memcached_set_errno(org::libmemcached::Instance& self, int lo
   _set(*self.root, &error_host, rc, at, local_errno);
   _set(self, (*self.root));
 
+#if 0
+  if (self.root->error_messages->rc != self.error_messages->rc)
+  {
+    fprintf(stderr, "%s:%d %s != %s\n", __FILE__, __LINE__,
+            memcached_strerror(NULL, self.root->error_messages->rc),
+            memcached_strerror(NULL, self.error_messages->rc));
+  }
+#endif
+
   return rc;
 }
 
index 67b0999f7f2afff67e462ec9c2c5a4894577aea8..cb0e682bd163eaebe51a95e31062b60e720bde04 100644 (file)
@@ -416,7 +416,17 @@ static memcached_return_t textual_read_one_response(org::libmemcached::Instance*
           and buffer[6] == '_'
           and buffer[7] == 'E' and buffer[8] == 'R' and buffer[9] == 'R' and buffer[10] == 'O' and buffer[11] == 'R')
       {
-        return MEMCACHED_CLIENT_ERROR;
+        // Move past the basic error message and whitespace
+        char *startptr= buffer + memcached_literal_param_size("CLIENT_ERROR");
+        if (startptr[0] == ' ')
+        {
+          startptr++;
+        }
+
+        char *endptr= startptr;
+        while (*endptr != '\r' && *endptr != '\n') endptr++;
+
+        return memcached_set_error(*instance, MEMCACHED_CLIENT_ERROR, MEMCACHED_AT, startptr, size_t(endptr - startptr));
       }
     }
     break;
index 7bdfe39438d451f7a590e086dfbda128fe89fc12..74e619d234bfc45c3df2321c0c727e5bf6d4895e 100644 (file)
@@ -279,6 +279,7 @@ test_st regression_tests[]= {
   {"lp:1009493", true, (test_callback_fn*)regression_1009493_TEST },
   {"lp:1021819", true, (test_callback_fn*)regression_1021819_TEST },
   {"lp:1048945", true, (test_callback_fn*)regression_1048945_TEST },
+  {"lp:1067242", true, (test_callback_fn*)regression_1067242_TEST },
   {0, false, (test_callback_fn*)0}
 };
 
index 38c0db77e88a90e967128531b273ec0387f3b646..a0570884a7c8a690133bcaf16a06b979c1e5bf26 100644 (file)
@@ -823,6 +823,34 @@ test_return_t memcached_add_SUCCESS_TEST(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
+test_return_t regression_1067242_TEST(memcached_st *memc)
+{
+  test_compare(MEMCACHED_SUCCESS, memcached_set(memc,
+                                                test_literal_param(__func__), 
+                                                test_literal_param("-2"),
+                                                0, 0));
+
+  memcached_return_t rc;
+  char* value;
+  test_true((value= memcached_get(memc, test_literal_param(__func__), NULL, NULL, &rc)));
+  test_compare(MEMCACHED_SUCCESS, rc);
+  free(value);
+
+  for (size_t x= 0; x < 10; x++)
+  {
+    uint64_t new_number;
+    test_compare(MEMCACHED_CLIENT_ERROR,
+                 memcached_increment(memc, 
+                                     test_literal_param(__func__), 1, &new_number));
+    test_compare(MEMCACHED_CLIENT_ERROR, memcached_last_error(memc));
+    test_true((value= memcached_get(memc, test_literal_param(__func__), NULL, NULL, &rc)));
+    test_compare(MEMCACHED_SUCCESS, rc);
+    free(value);
+  }
+
+  return TEST_SUCCESS;
+}
+
 /*
   Set the value, then quit to make sure it is flushed.
   Come back in and test that add fails.
index eb9afa29c2ae8ed8710a8636be2ca4d6a9af8062..104d44eefbd5cdd4282b2edadca6f15f21723848 100644 (file)
@@ -180,3 +180,4 @@ test_return_t regression_996813_TEST(memcached_st*);
 test_return_t regression_994772_TEST(memcached_st*);
 test_return_t regression_1009493_TEST(memcached_st*);
 test_return_t regression_1048945_TEST(memcached_st*);
+test_return_t regression_1067242_TEST(memcached_st*);