From 481efe3c437e1d87e0fabb987982cc1df2b2c35d Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Sun, 27 Mar 2011 21:23:13 -0700 Subject: [PATCH] Remove cork from being optional, just use it as we need it. --- configure.ac | 4 ++ libmemcached/behavior.c | 61 +++++------------------ libmemcached/common.h | 85 +++++++++++++------------------- libmemcached/io.c | 101 +++++++++++++++++++-------------------- libmemcached/io.h | 39 ++++++++++++--- libmemcached/memcached.c | 1 - libmemcached/memcached.h | 1 - m4/socket_send_flags.m4 | 17 +++++++ 8 files changed, 146 insertions(+), 163 deletions(-) diff --git a/configure.ac b/configure.ac index 9349b1f4..b4581e9f 100644 --- a/configure.ac +++ b/configure.ac @@ -91,6 +91,10 @@ AH_BOTTOM([ #define MSG_DONTWAIT 0 #endif +#ifndef HAVE_MSG_MORE +#define MSG_MORE 0 +#endif + #endif ]) diff --git a/libmemcached/behavior.c b/libmemcached/behavior.c index 48c6487f..2e2b99e4 100644 --- a/libmemcached/behavior.c +++ b/libmemcached/behavior.c @@ -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: diff --git a/libmemcached/common.h b/libmemcached/common.h index 1a813a02..e350149b 100644 --- a/libmemcached/common.h +++ b/libmemcached/common.h @@ -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); diff --git a/libmemcached/io.c b/libmemcached/io.c index 5a9a7320..5acbbd52 100644 --- a/libmemcached/io.c +++ b/libmemcached/io.c @@ -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(); diff --git a/libmemcached/io.h b/libmemcached/io.h index b4f7806f..85d56b16 100644 --- a/libmemcached/io.h +++ b/libmemcached/io.h @@ -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. * */ diff --git a/libmemcached/memcached.c b/libmemcached/memcached.c index 8cacdc47..396f34e6 100644 --- a/libmemcached/memcached.c +++ b/libmemcached/memcached.c @@ -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, diff --git a/libmemcached/memcached.h b/libmemcached/memcached.h index b2cb0bfd..35805bdc 100644 --- a/libmemcached/memcached.h +++ b/libmemcached/memcached.h @@ -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 diff --git a/m4/socket_send_flags.m4 b/m4/socket_send_flags.m4 index 8251980d..290bc4a2 100644 --- a/m4/socket_send_flags.m4 +++ b/m4/socket_send_flags.m4 @@ -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 + ], [ +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 --------------------------------------------------------------------------- -- 2.30.2