From ae08249421c63be6a7cd0dfc52ec1caeb5f6de8e Mon Sep 17 00:00:00 2001 From: Adam Thomason Date: Tue, 10 Nov 2009 17:38:26 -0800 Subject: [PATCH] Use TCP_CORK/TCP_NOFLUSH socket options where available to coalesce writes for multi-command operations. When used with MEMCACHED_BEHAVIOR_TCP_NODELAY this eliminates the Nagle delay after sending requests. --- libmemcached/memcached_io.c | 27 +++++++++++++++++++++++++++ libmemcached/memcached_server.c | 1 + libmemcached/memcached_server.h | 1 + 3 files changed, 29 insertions(+) diff --git a/libmemcached/memcached_io.c b/libmemcached/memcached_io.c index 693ce95c..fdcdfdd6 100644 --- a/libmemcached/memcached_io.c +++ b/libmemcached/memcached_io.c @@ -142,6 +142,28 @@ static bool process_input_buffer(memcached_server_st *ptr) return false; } +#ifdef TCP_CORK + #define CORK TCP_CORK +#elif defined TCP_NOPUSH + #define CORK TCP_NOPUSH +#endif + +static void memcached_io_cork(memcached_server_st *ptr, int enable) +{ + #ifdef CORK + if (ptr->type != MEMCACHED_CONNECTION_TCP) + return; + + if ((enable && ptr->is_corked) || (!enable && !ptr->is_corked)) + return; + + int err= setsockopt(ptr->fd, IPPROTO_TCP, CORK, + &enable, (socklen_t)sizeof(int)); + if (!err) + ptr->is_corked= enable; + #endif +} + #ifdef UNUSED void memcached_io_preread(memcached_st *ptr) { @@ -268,6 +290,10 @@ ssize_t memcached_io_write(memcached_server_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(ptr, 1); + while (length) { char *write_ptr; @@ -319,6 +345,7 @@ ssize_t memcached_io_write(memcached_server_st *ptr, WATCHPOINT_ASSERT(ptr->fd != -1); if (io_flush(ptr, &rc) == -1) return -1; + memcached_io_cork(ptr, 0); } return (ssize_t) original_length; diff --git a/libmemcached/memcached_server.c b/libmemcached/memcached_server.c index 2ecbe214..e45d1c95 100644 --- a/libmemcached/memcached_server.c +++ b/libmemcached/memcached_server.c @@ -38,6 +38,7 @@ memcached_server_st *memcached_server_create_with(memcached_st *memc, memcached_ host->fd= -1; host->type= type; host->read_ptr= host->read_buffer; + host->is_corked= 0; if (memc) host->next_retry= memc->retry_timeout; if (type == MEMCACHED_CONNECTION_UDP) diff --git a/libmemcached/memcached_server.h b/libmemcached/memcached_server.h index de57eaec..6d1e376e 100644 --- a/libmemcached/memcached_server.h +++ b/libmemcached/memcached_server.h @@ -40,6 +40,7 @@ struct memcached_server_st { char read_buffer[MEMCACHED_MAX_BUFFER]; char write_buffer[MEMCACHED_MAX_BUFFER]; char hostname[MEMCACHED_MAX_HOST_LENGTH]; + bool is_corked; }; #define memcached_server_count(A) (A)->number_of_hosts -- 2.30.2