From: Adam Thomason Date: Wed, 11 Nov 2009 01:38:26 +0000 (-0800) Subject: Use TCP_CORK/TCP_NOFLUSH socket options where available to coalesce writes for multi... X-Git-Tag: 0.40~102^2 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=ae08249421c63be6a7cd0dfc52ec1caeb5f6de8e;p=m6w6%2Flibmemcached 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. --- 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