Remove cork from being optional, just use it as we need it.
authorBrian Aker <brian@tangent.org>
Mon, 28 Mar 2011 04:23:13 +0000 (21:23 -0700)
committerBrian Aker <brian@tangent.org>
Mon, 28 Mar 2011 04:23:13 +0000 (21:23 -0700)
configure.ac
libmemcached/behavior.c
libmemcached/common.h
libmemcached/io.c
libmemcached/io.h
libmemcached/memcached.c
libmemcached/memcached.h
m4/socket_send_flags.m4

index 9349b1f4756ad22974c6e36660975a1fea840024..b4581e9f7d15dd767d8b6003a38f65c48a862eee 100644 (file)
@@ -91,6 +91,10 @@ AH_BOTTOM([
 #define MSG_DONTWAIT 0
 #endif
 
+#ifndef HAVE_MSG_MORE
+#define MSG_MORE 0
+#endif
+
 #endif
 ])
 
index 48c6487f5f42f5da079dc55143f99d0582e7f36a..2e2b99e4c151ae945f0bb4ace3e7cc486149285c 100644 (file)
@@ -169,55 +169,12 @@ memcached_return_t memcached_behavior_set(memcached_st *ptr,
       break;
   case MEMCACHED_BEHAVIOR_CORK:
       {
-        memcached_server_write_instance_st instance;
-        bool action= set_flag(data);
-
-        if (action == false)
-        {
-          ptr->flags.cork= set_flag(false);
-          return MEMCACHED_SUCCESS;
-        }
-
-        instance= memcached_server_instance_fetch(ptr, 0);
-        if (! instance)
-          return MEMCACHED_NO_SERVERS;
-
-
-        /* We just try the first host, and if it is down we return zero */
-        memcached_return_t rc;
-        rc= memcached_connect(instance);
-        if (rc != MEMCACHED_SUCCESS)
-        {
-          return rc;
-        }
-
-        /* Now we test! */
-        memcached_ternary_t enabled;
-        enabled= test_cork(instance, true);
-
-        switch (enabled)
-        {
-        case MEM_FALSE:
-          return memcached_last_error_errno(ptr) ? MEMCACHED_ERRNO : MEMCACHED_FAILURE ;
-        case MEM_TRUE:
-          {
-            enabled= test_cork(instance, false);
-
-            if (enabled == false) // Possible bug in OS?
-            {
-              memcached_quit_server(instance, false); // We should reset everything on this error.
-              return MEMCACHED_ERRNO;  // Errno will be true because we will have already set it.
-            }
-            ptr->flags.cork= true;
-            ptr->flags.tcp_nodelay= true;
-            memcached_quit(ptr); // We go on and reset the connections.
-          }
-          break;
-        case MEM_NOT:
-        default:
-          return memcached_set_error_string(ptr, MEMCACHED_NOT_SUPPORTED, 
-                                            memcached_string_with_size("MEMCACHED_BEHAVIOR_CORK is not supported on this platform."));
-        }
+#ifdef HAVE_MSG_MORE
+      break;
+#else
+      return memcached_set_error_string(ptr, MEMCACHED_NOT_SUPPORTED, 
+                                        memcached_string_with_size("MEMCACHED_BEHAVIOR_CORK is not supported on this platform."));
+#endif
       }
       break;
   case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE:
@@ -377,7 +334,11 @@ uint64_t memcached_behavior_get(memcached_st *ptr,
   case MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ:
     return ptr->flags.randomize_replica_read;
   case MEMCACHED_BEHAVIOR_CORK:
-    return ptr->flags.cork;
+#ifdef HAVE_MSG_MORE
+    return true;
+#else
+    return false;
+#endif
   case MEMCACHED_BEHAVIOR_TCP_KEEPALIVE:
     return ptr->flags.tcp_keepalive;
   case MEMCACHED_BEHAVIOR_LOAD_FROM_FILE:
index 1a813a02443315036767e9c6343c3d3a904de34d..e350149bded5249b572de9638649532f5447d1bb 100644 (file)
@@ -1,11 +1,38 @@
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  LibMemcached
  *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker
+ *  All rights reserved.
  *
- * Summary:
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
@@ -80,14 +107,6 @@ struct memcached_continuum_item_st
   uint32_t value;
 };
 
-/* Yum, Fortran.... can you make the reference? */
-typedef enum {
-  MEM_NOT= -1,
-  MEM_FALSE= false,
-  MEM_TRUE= true
-} memcached_ternary_t;
-
-
 #if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
 
 #define likely(x)       if((x))
@@ -157,44 +176,6 @@ static inline memcached_return_t memcached_validate_key_length(size_t key_length
   return MEMCACHED_SUCCESS;
 }
 
-#ifdef TCP_CORK
-  #define CORK TCP_CORK
-#elif defined TCP_NOPUSH
-  #define CORK TCP_NOPUSH
-#endif
-
-/*
-  test_cork() tries to enable TCP_CORK. IF TCP_CORK is not an option
-  on the system it returns false but sets errno to 0. Otherwise on
-  failure errno is set.
-*/
-static inline memcached_ternary_t test_cork(memcached_server_st *ptr, int enable)
-{
-#ifdef CORK
-  if (ptr->type != MEMCACHED_CONNECTION_TCP)
-    return MEM_FALSE;
-
-  int err= setsockopt(ptr->fd, IPPROTO_TCP, CORK,
-                      &enable, (socklen_t)sizeof(int));
-  if (! err)
-  {
-    return MEM_TRUE;
-  }
-
-  perror(strerror(errno));
-  ptr->cached_errno= errno;
-
-  return MEM_FALSE;
-#else
-  (void)ptr;
-  (void)enable;
-
-  ptr->cached_errno= 0;
-
-  return MEM_NOT;
-#endif
-}
-
 static inline void libmemcached_free(const memcached_st *ptr, void *mem)
 {
   ptr->allocators.free(ptr, mem, ptr->allocators.context);
index 5a9a7320f4d691ec2b5bc7a7004a824e1f98d6f5..5acbbd521ce6cd9f2c488d5e016cf4df50f1e23c 100644 (file)
@@ -1,16 +1,43 @@
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  LibMemcached
  *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker
+ *  All rights reserved.
  *
- * Summary: Server IO, Not public!
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
 
-#include "common.h"
+#include "libmemcached/common.h"
 
 typedef enum {
   MEM_READ,
@@ -18,6 +45,7 @@ typedef enum {
 } memc_read_or_write;
 
 static ssize_t io_flush(memcached_server_write_instance_st ptr,
+                        const bool with_flush,
                         memcached_return_t *error);
 static void increment_udp_message_id(memcached_server_write_instance_st ptr);
 
@@ -199,40 +227,6 @@ static bool process_input_buffer(memcached_server_write_instance_st ptr)
   return false;
 }
 
-static inline void memcached_io_cork_push(memcached_server_st *ptr)
-{
-  (void)ptr;
-#ifdef CORK
-  if (ptr->root->flags.cork == false || ptr->state.is_corked)
-    return;
-
-  int enable= 1;
-  int err= setsockopt(ptr->fd, IPPROTO_TCP, CORK,
-                      &enable, (socklen_t)sizeof(int));
-  if (! err)
-    ptr->state.is_corked= true;
-
-  WATCHPOINT_ASSERT(ptr->state.is_corked == true);
-#endif
-}
-
-static inline void memcached_io_cork_pop(memcached_server_st *ptr)
-{
-  (void)ptr;
-#ifdef CORK
-  if (ptr->root->flags.cork == false || ptr->state.is_corked == false)
-    return;
-
-  int enable= 0;
-  int err= setsockopt(ptr->fd, IPPROTO_TCP, CORK,
-                      &enable, (socklen_t)sizeof(int));
-  if (! err)
-    ptr->state.is_corked= false;
-
-  WATCHPOINT_ASSERT(ptr->state.is_corked == false);
-#endif
-}
-
 #if 0 // Dead code, this should be removed.
 void memcached_io_preread(memcached_st *ptr)
 {
@@ -368,12 +362,6 @@ static ssize_t _io_write(memcached_server_write_instance_st ptr,
   original_length= length;
   buffer_ptr= buffer;
 
-  /* more writable data is coming if a flush isn't required, so delay send */
-  if (! with_flush)
-  {
-    memcached_io_cork_push(ptr);
-  }
-
   while (length)
   {
     char *write_ptr;
@@ -409,7 +397,7 @@ static ssize_t _io_write(memcached_server_write_instance_st ptr,
       ssize_t sent_length;
 
       WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
-      sent_length= io_flush(ptr, &rc);
+      sent_length= io_flush(ptr, with_flush, &rc);
       if (sent_length == -1)
       {
         return -1;
@@ -427,12 +415,10 @@ static ssize_t _io_write(memcached_server_write_instance_st ptr,
   {
     memcached_return_t rc;
     WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
-    if (io_flush(ptr, &rc) == -1)
+    if (io_flush(ptr, with_flush, &rc) == -1)
     {
       return -1;
     }
-
-    memcached_io_cork_pop(ptr);
   }
 
   return (ssize_t) original_length;
@@ -566,6 +552,7 @@ memcached_server_write_instance_st memcached_io_get_readable_server(memcached_st
 }
 
 static ssize_t io_flush(memcached_server_write_instance_st ptr,
+                        const bool with_flush,
                         memcached_return_t *error)
 {
   /*
@@ -618,8 +605,16 @@ static ssize_t io_flush(memcached_server_write_instance_st ptr,
     if (ptr->type == MEMCACHED_CONNECTION_UDP)
       increment_udp_message_id(ptr);
 
-    WATCHPOINT_ASSERT(ptr->fd != -1);
-    sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT);
+    WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET);
+    if (with_flush)
+    {
+      sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT);
+    }
+    else
+    {
+      sent_length= send(ptr->fd, local_write_ptr, write_length, MSG_NOSIGNAL|MSG_DONTWAIT|MSG_MORE);
+    }
+
     if (sent_length == SOCKET_ERROR)
     {
       ptr->cached_errno= get_socket_errno();
index b4f7806f1d40a02040088fcbaca0781142bb9177..85d56b16d70539e93fede37a7cabcc230488566a 100644 (file)
@@ -1,11 +1,38 @@
-/* LibMemcached
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  LibMemcached
  *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker
+ *  All rights reserved.
  *
- * Summary: Server IO, Not public!
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
 
index 8cacdc47a3062f39cbffc5a12dace320b79fe154..396f34e6e8643379bab268f038ca7e3cd5ce8c7c 100644 (file)
@@ -21,7 +21,6 @@ static const memcached_st global_copy= {
     .auto_eject_hosts= false,
     .binary_protocol= false,
     .buffer_requests= false,
-    .cork= false,
     .hash_with_prefix_key= false,
     .ketama_weighted= false,
     .no_block= false,
index b2cb0bfd3c2ac49ae41912da309662a1a2682e02..35805bdc568642b31f8ff0598e6d1267e07b118f 100644 (file)
@@ -71,7 +71,6 @@ struct memcached_st {
     bool auto_eject_hosts:1;
     bool binary_protocol:1;
     bool buffer_requests:1;
-    bool cork:1;
     bool hash_with_prefix_key:1;
     bool ketama_weighted:1;
     bool no_block:1; // Don't block
index 8251980dad93c5642daba58701ff2cd46c6b0346..290bc4a2b97311280da54f83fb054a772a602b58 100644 (file)
@@ -38,10 +38,27 @@ int flags= MSG_DONTWAIT;
    AC_LANG_POP
   ])
 
+  AC_CACHE_CHECK([for MSG_MORE], [ac_cv_msg_more], [
+    AC_LANG_PUSH([C])
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -I${srcdir}"
+    AC_TRY_LINK([
+#include <sys/socket.h>
+                   ], [
+int flags= MSG_MORE;
+                   ],
+                   [ ac_cv_msg_more=yes ],
+                   [ ac_cv_msg_more=no ])
+   CFLAGS="$save_CFLAGS"
+   AC_LANG_POP
+  ])
+
   AS_IF([test "x$ac_cv_msg_nosignal" = "xyes"],[
         AC_DEFINE(HAVE_MSG_NOSIGNAL, 1, [Define to 1 if you have a MSG_NOSIGNAL])])
   AS_IF([test "x$ac_cv_msg_dontwait" = "xyes"],[
         AC_DEFINE(HAVE_MSG_DONTWAIT, 1, [Define to 1 if you have a MSG_DONTWAIT])])
+  AS_IF([test "x$ac_cv_msg_more" = "xyes"],[
+        AC_DEFINE(HAVE_MSG_MORE, 1, [Define to 1 if you have a HAVE_MSG_MORE])])
 ])
 
 dnl ---------------------------------------------------------------------------