summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2017-07-11 12:33:00 +0200
committerantirez <antirez@gmail.com>2017-07-14 10:55:17 +0200
commit884ceb692e5f9857de0ff8a763838c46339ad199 (patch)
tree46aa48f4baa23152d0f16ac69d4442395ec4a8ad
parentccbdd762c572c73f39a8246ace489675f8bc0a32 (diff)
downloadredis-884ceb692e5f9857de0ff8a763838c46339ad199.tar.gz
Clients blocked in modules: free argv/argc later.
See issue #3844 for more information.
-rw-r--r--src/module.c5
-rw-r--r--src/networking.c13
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;
}
}