diff options
author | OmriSteiner <51128928+OmriSteiner@users.noreply.github.com> | 2020-06-22 23:20:30 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-22 13:20:30 -0700 |
commit | 392de5d7f97353485df1237872cb682842e8d83f (patch) | |
tree | a45994c209909167bdb09e54cba8c733abb95930 | |
parent | a28de70a0196275317642eb60f8387a2ee950330 (diff) |
fix #785: defer TCP_NODELAY in async tcp connections (#836)
Co-authored-by: Omri Steiner <omri@insoundz.com>
-rw-r--r-- | async.c | 15 | ||||
-rw-r--r-- | net.c | 6 | ||||
-rw-r--r-- | net.h | 2 |
3 files changed, 18 insertions, 5 deletions
@@ -539,20 +539,31 @@ void redisProcessCallbacks(redisAsyncContext *ac) { __redisAsyncDisconnect(ac); } +static void __redisAsyncHandleConnectFailure(redisAsyncContext *ac) { + if (ac->onConnect) ac->onConnect(ac, REDIS_ERR); + __redisAsyncDisconnect(ac); +} + /* Internal helper function to detect socket status the first time a read or * write event fires. When connecting was not successful, the connect callback * is called with a REDIS_ERR status and the context is free'd. */ static int __redisAsyncHandleConnect(redisAsyncContext *ac) { int completed = 0; redisContext *c = &(ac->c); + if (redisCheckConnectDone(c, &completed) == REDIS_ERR) { /* Error! */ redisCheckSocketError(c); - if (ac->onConnect) ac->onConnect(ac, REDIS_ERR); - __redisAsyncDisconnect(ac); + __redisAsyncHandleConnectFailure(ac); return REDIS_ERR; } else if (completed == 1) { /* connected! */ + if (c->connection_type == REDIS_CONN_TCP && + redisSetTcpNoDelay(c) == REDIS_ERR) { + __redisAsyncHandleConnectFailure(ac); + return REDIS_ERR; + } + if (ac->onConnect) ac->onConnect(ac, REDIS_OK); c->flags |= REDIS_CONNECTED; return REDIS_OK; @@ -203,7 +203,7 @@ int redisKeepAlive(redisContext *c, int interval) { return REDIS_OK; } -static int redisSetTcpNoDelay(redisContext *c) { +int redisSetTcpNoDelay(redisContext *c) { int yes = 1; if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) { __redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)"); @@ -487,12 +487,12 @@ addrretry: wait_for_ready: if (redisContextWaitReady(c,timeout_msec) != REDIS_OK) goto error; + if (redisSetTcpNoDelay(c) != REDIS_OK) + goto error; } } if (blocking && redisSetBlocking(c,1) != REDIS_OK) goto error; - if (redisSetTcpNoDelay(c) != REDIS_OK) - goto error; c->flags |= REDIS_CONNECTED; rv = REDIS_OK; @@ -51,4 +51,6 @@ int redisContextConnectUnix(redisContext *c, const char *path, const struct time int redisKeepAlive(redisContext *c, int interval); int redisCheckConnectDone(redisContext *c, int *completed); +int redisSetTcpNoDelay(redisContext *c); + #endif |