diff options
author | antirez <antirez@gmail.com> | 2015-09-28 18:25:57 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2015-09-30 16:29:41 +0200 |
commit | 1c7d87df0cd64fd786bebd5cb9636912504359d5 (patch) | |
tree | 31bce750170bc1ac32d6b879984396c63b8174bc /src/networking.c | |
parent | d1b6a17d1ed64c919d55a27ea780e973196a5e98 (diff) | |
download | redis-1c7d87df0cd64fd786bebd5cb9636912504359d5.tar.gz |
Avoid installing the client write handler when possible.
Diffstat (limited to 'src/networking.c')
-rw-r--r-- | src/networking.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/networking.c b/src/networking.c index 336561e10..4f6441de0 100644 --- a/src/networking.c +++ b/src/networking.c @@ -166,16 +166,18 @@ int prepareClientToWrite(client *c) { /* Only install the handler if not already installed and, in case of * slaves, if the client can actually receive writes. */ if (c->bufpos == 0 && listLength(c->reply) == 0 && + !(c->flags & CLIENT_PENDING_WRITE) && (c->replstate == REPL_STATE_NONE || (c->replstate == SLAVE_STATE_ONLINE && !c->repl_put_online_on_ack))) { - /* Try to install the write handler. */ - if (aeCreateFileEvent(server.el, c->fd, AE_WRITABLE, - sendReplyToClient, c) == AE_ERR) - { - freeClientAsync(c); - return C_ERR; - } + /* Here instead of installing the write handler, we just flag the + * client and put it into a list of clients that have something + * to write to the socket. This way before re-entering the event + * loop, we can try to directly write to the client sockets avoiding + * a system call. We'll only really install the write handler if + * we'll not be able to write the whole reply at once. */ + c->flags |= CLIENT_PENDING_WRITE; + listAddNodeTail(server.clients_pending_write,c); } /* Authorize the caller to queue in the output buffer of this client. */ @@ -739,6 +741,12 @@ void freeClient(client *c) { listDelNode(server.clients,ln); } + /* Remove from the list of pending writes if needed. */ + if (c->flags & CLIENT_PENDING_WRITE) { + ln = listSearchKey(server.clients_pending_write,c); + listDelNode(server.clients_pending_write,ln); + } + /* When client was just unblocked because of a blocking operation, * remove it from the list of unblocked clients. */ if (c->flags & CLIENT_UNBLOCKED) { |