diff options
author | antirez <antirez@gmail.com> | 2017-07-11 12:33:00 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2017-07-14 10:55:17 +0200 |
commit | 884ceb692e5f9857de0ff8a763838c46339ad199 (patch) | |
tree | 46aa48f4baa23152d0f16ac69d4442395ec4a8ad | |
parent | ccbdd762c572c73f39a8246ace489675f8bc0a32 (diff) | |
download | redis-884ceb692e5f9857de0ff8a763838c46339ad199.tar.gz |
Clients blocked in modules: free argv/argc later.
See issue #3844 for more information.
-rw-r--r-- | src/module.c | 5 | ||||
-rw-r--r-- | src/networking.c | 13 |
2 files changed, 15 insertions, 3 deletions
diff --git a/src/module.c b/src/module.c index 3def48207..e0906e255 100644 --- a/src/module.c +++ b/src/module.c @@ -3304,6 +3304,11 @@ void moduleBlockedClientPipeReadable(aeEventLoop *el, int fd, void *privdata, in void unblockClientFromModule(client *c) { RedisModuleBlockedClient *bc = c->bpop.module_blocked_handle; bc->client = NULL; + /* Reset the client for a new query since, for blocking commands implemented + * into modules, we do not it immediately after the command returns (and + * the client blocks) in order to be still able to access the argument + * vector from callbacks. */ + resetClient(c); } /* Block a client in the context of a blocking command, returning an handle diff --git a/src/networking.c b/src/networking.c index 98e779642..aeaeca967 100644 --- a/src/networking.c +++ b/src/networking.c @@ -1332,10 +1332,17 @@ void processInputBuffer(client *c) { /* Update the applied replication offset of our master. */ c->reploff = c->read_reploff - sdslen(c->querybuf); } - resetClient(c); + + /* Don't reset the client structure for clients blocked in a + * module blocking command, so that the reply callback will + * still be able to access the client argv and argc field. + * The client will be reset in unblockClientFromModule(). */ + if (!(c->flags & CLIENT_BLOCKED) || c->btype != BLOCKED_MODULE) + resetClient(c); } - /* freeMemoryIfNeeded may flush slave output buffers. This may result - * into a slave, that may be the active client, to be freed. */ + /* freeMemoryIfNeeded may flush slave output buffers. This may + * result into a slave, that may be the active client, to be + * freed. */ if (server.current_client == NULL) break; } } |