bug fix for recursive decent into quit()
authorBrian Aker <brian@gaz>
Wed, 10 Feb 2010 17:00:45 +0000 (09:00 -0800)
committerBrian Aker <brian@gaz>
Wed, 10 Feb 2010 17:00:45 +0000 (09:00 -0800)
ChangeLog
libmemcached/io.c
libmemcached/quit.c
libmemcached/server.c
libmemcached/server.h

index a3024f1439cac8113c133e3e7dd410dd63549ff4..5012b84c4eeb94790ebbe0075fcf7fe8e52b2aaa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,7 @@
 * Many fixes to memslap.
 * Updates for memcapable.
 * Compile fixes for OpenBSD.
+* Fix for possible recursive decent on IO failure.
 
 0.37 Mon Jan 11 16:29:57 PST 2010
 * Fixed build for libhashkit.
index 6f5f3d2317fac14ae083add81c614d2033feb832..ef46a0d9e460b93f819e8c70d368ce3c2c107b72 100644 (file)
@@ -64,14 +64,14 @@ static memcached_return_t io_wait(memcached_server_instance_st *ptr,
       return MEMCACHED_SUCCESS;
     case 0:
       return MEMCACHED_TIMEOUT;
-#if TARGET_OS_LINUX
+#ifdef TARGET_OS_LINUX
     case ERESTART:
 #endif
     case EINTR:
       continue;
     default:
       ptr->cached_errno= error;
-      memcached_quit_server(ptr, 1);
+      memcached_quit_server(ptr, true);
 
       return MEMCACHED_FAILURE;
     }
@@ -80,7 +80,7 @@ static memcached_return_t io_wait(memcached_server_instance_st *ptr,
   /* Imposssible for anything other then -1 */
   WATCHPOINT_ASSERT(error == -1);
   ptr->cached_errno= error;
-  memcached_quit_server(ptr, 1);
+  memcached_quit_server(ptr, true);
 
   return MEMCACHED_FAILURE;
 }
@@ -260,7 +260,7 @@ memcached_return_t memcached_io_read(memcached_server_instance_st *ptr,
           {
           case EAGAIN:
           case EINTR:
-#if TARGET_OS_LINUX
+#ifdef TARGET_OS_LINUX
           case ERESTART:
 #endif
             if ((rc= io_wait(ptr, MEM_READ)) == MEMCACHED_SUCCESS)
@@ -269,7 +269,7 @@ memcached_return_t memcached_io_read(memcached_server_instance_st *ptr,
 
           default:
             {
-              memcached_quit_server(ptr, 1);
+              memcached_quit_server(ptr, true);
               *nread= -1;
               return rc;
             }
@@ -286,7 +286,7 @@ memcached_return_t memcached_io_read(memcached_server_instance_st *ptr,
             for blocking I/O we do not return 0 and for non-blocking case
             it will return EGAIN if data is not immediatly available.
           */
-          memcached_quit_server(ptr, 1);
+          memcached_quit_server(ptr, true);
           *nread= -1;
           return MEMCACHED_UNKNOWN_READ_FAILURE;
         }
@@ -569,11 +569,11 @@ static ssize_t io_flush(memcached_server_instance_st *ptr,
           if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_TIMEOUT)
             continue;
 
-          memcached_quit_server(ptr, 1);
+          memcached_quit_server(ptr, true);
           return -1;
         }
       default:
-        memcached_quit_server(ptr, 1);
+        memcached_quit_server(ptr, true);
         *error= MEMCACHED_ERRNO;
         return -1;
       }
@@ -582,7 +582,7 @@ static ssize_t io_flush(memcached_server_instance_st *ptr,
     if (ptr->type == MEMCACHED_CONNECTION_UDP &&
         (size_t)sent_length != write_length)
     {
-      memcached_quit_server(ptr, 1);
+      memcached_quit_server(ptr, true);
       return -1;
     }
 
@@ -612,7 +612,7 @@ static ssize_t io_flush(memcached_server_instance_st *ptr,
 */
 void memcached_io_reset(memcached_server_instance_st *ptr)
 {
-  memcached_quit_server(ptr, 1);
+  memcached_quit_server(ptr, true);
 }
 
 /**
index 8b5acf67d1f056727f38328241af7b0c4abac6c4..292bc6e43442f6158287b1e54c7a3a6fa38ae96d 100644 (file)
@@ -13,11 +13,13 @@ void memcached_quit_server(memcached_server_st *ptr, bool io_death)
 {
   if (ptr->fd != -1)
   {
-    if (io_death == false && ptr->type != MEMCACHED_CONNECTION_UDP)
+    if (io_death == false && ptr->type != MEMCACHED_CONNECTION_UDP && ptr->options.is_shutting_down == false)
     {
       memcached_return_t rc;
       char buffer[MEMCACHED_MAX_BUFFER];
 
+      ptr->options.is_shutting_down= true;
+
       if (ptr->root->flags.binary_protocol)
       {
         protocol_binary_request_quit request = {.bytes= {0}};
@@ -59,6 +61,7 @@ void memcached_quit_server(memcached_server_st *ptr, bool io_death)
   ptr->write_buffer_offset= (size_t) ((ptr->type == MEMCACHED_CONNECTION_UDP) ? UDP_DATAGRAM_HEADER_LENGTH : 0);
   ptr->read_buffer_length= 0;
   ptr->read_ptr= ptr->read_buffer;
+  ptr->options.is_shutting_down= false;
   memcached_server_response_reset(ptr);
 
   if (io_death)
@@ -81,7 +84,7 @@ void memcached_quit(memcached_st *ptr)
       memcached_server_instance_st *instance=
         memcached_server_instance_fetch(ptr, x);
 
-      memcached_quit_server(instance, 0);
+      memcached_quit_server(instance, false);
     }
   }
 }
index 6fd685feac76dcece0dce6aaaa498f2fe094ef37..f480750d8679079c5003ce4448c834777da91c6d 100644 (file)
@@ -19,6 +19,7 @@ static inline void _server_init(memcached_server_st *self, const memcached_st *r
                                 uint32_t weight, memcached_connection_t type)
 {
   self->options.sockaddr_inited= false;
+  self->options.is_shutting_down= false;
   self->number_of_hosts= 0;
   self->cursor_active= 0;
   self->port= port;
@@ -100,7 +101,7 @@ memcached_server_st *memcached_server_create_with(const memcached_st *memc, memc
 
 void memcached_server_free(memcached_server_st *self)
 {
-  memcached_quit_server(self, 0);
+  memcached_quit_server(self, false);
 
   if (self->cached_server_error)
     free(self->cached_server_error);
index 109f9d50b42e5e0e774384820b334a605805224e..5174752822c63ee8327eebbb2fbd461c69fd21da 100644 (file)
@@ -18,6 +18,7 @@ struct memcached_server_st {
     bool is_allocated MEMCACHED_BITFIELD;
     bool is_initialized MEMCACHED_BITFIELD;
     bool sockaddr_inited MEMCACHED_BITFIELD;
+    bool is_shutting_down MEMCACHED_BITFIELD;
   } options;
   uint32_t number_of_hosts;
   uint32_t cursor_active;