diff options
author | Oran Agra <oran@redislabs.com> | 2019-08-19 12:18:25 +0300 |
---|---|---|
committer | Yossi Gottlieb <yossigo@gmail.com> | 2019-10-07 21:06:30 +0300 |
commit | 6b6294807c0bca50041da117c1abb35f5114e972 (patch) | |
tree | e13c13d22cab5b36d1ad70c73d4398d30dd6eb15 /src/connection.c | |
parent | 5a477946065bcf05b335ededd6b794e82882ab73 (diff) | |
download | redis-6b6294807c0bca50041da117c1abb35f5114e972.tar.gz |
TLS: Implement support for write barrier.
Diffstat (limited to 'src/connection.c')
-rw-r--r-- | src/connection.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/src/connection.c b/src/connection.c index 601f175bc..85bf572ad 100644 --- a/src/connection.c +++ b/src/connection.c @@ -194,10 +194,14 @@ static int connSocketAccept(connection *conn, ConnectionCallbackFunc accept_hand /* Register a write handler, to be called when the connection is writable. * If NULL, the existing handler is removed. */ -static int connSocketSetWriteHandler(connection *conn, ConnectionCallbackFunc func) { +static int connSocketSetWriteHandler(connection *conn, ConnectionCallbackFunc func, int barrier) { if (func == conn->write_handler) return C_OK; conn->write_handler = func; + if (barrier) + conn->flags |= CONN_FLAG_WRITE_BARRIER; + else + conn->flags &= ~CONN_FLAG_WRITE_BARRIER; if (!conn->write_handler) aeDeleteFileEvent(server.el,conn->fd,AE_WRITABLE); else @@ -247,13 +251,35 @@ static void connSocketEventHandler(struct aeEventLoop *el, int fd, void *clientD conn->conn_handler = NULL; } + /* Normally we execute the readable event first, and the writable + * event laster. This is useful as sometimes we may be able + * to serve the reply of a query immediately after processing the + * query. + * + * However if WRITE_BARRIER is set in the mask, our application is + * asking us to do the reverse: never fire the writable event + * after the readable. In such a case, we invert the calls. + * This is useful when, for instance, we want to do things + * in the beforeSleep() hook, like fsynching a file to disk, + * before replying to a client. */ + int invert = conn->flags & CONN_FLAG_WRITE_BARRIER; + + int call_write = (mask & AE_WRITABLE) && conn->write_handler; + int call_read = (mask & AE_READABLE) && conn->read_handler; + /* Handle normal I/O flows */ - if ((mask & AE_READABLE) && conn->read_handler) { + if (!invert && call_read) { if (!callHandler(conn, conn->read_handler)) return; } - if ((mask & AE_WRITABLE) && conn->write_handler) { + /* Fire the writable event. */ + if (call_write) { if (!callHandler(conn, conn->write_handler)) return; } + /* If we have to invert the call, fire the readable event now + * after the writable one. */ + if (invert && call_read) { + if (!callHandler(conn, conn->read_handler)) return; + } } static int connSocketBlockingConnect(connection *conn, const char *addr, int port, long long timeout) { |