summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2019-10-23 10:47:39 +0200
committerantirez <antirez@gmail.com>2019-10-23 10:47:43 +0200
commit3773f22bac712aaaf7e8691e5676dea495162d31 (patch)
tree2a6ebdd30ccafd824b4842d4c522b6792aa0278c
parent3499e88de6ab1b95c4d3fbf1a3cbed288ad54711 (diff)
downloadredis-3773f22bac712aaaf7e8691e5676dea495162d31.tar.gz
Modules hooks: do not re-enter in hooks.
Calling a module hook callback may result in callback operations in turn triggering other events the module is subscribed too. We don't want to trigger those, it's unsafe and quite confusing, and to do it correcly we would need to maintain an event list: quite a more complex implementation.
-rw-r--r--src/module.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/src/module.c b/src/module.c
index 0f57c9b14..9c51f70a8 100644
--- a/src/module.c
+++ b/src/module.c
@@ -61,6 +61,7 @@ struct RedisModule {
list *using; /* List of modules we use some APIs of. */
list *filters; /* List of filters the module has registered. */
int in_call; /* RM_Call() nesting level */
+ int in_hook; /* Non zero if an hook callback is active. */
int options; /* Module options and capabilities. */
RedisModuleInfoFunc info_cb; /* Callback for module to add INFO fields. */
};
@@ -817,6 +818,7 @@ void RM_SetModuleAttribs(RedisModuleCtx *ctx, const char *name, int ver, int api
module->using = listCreate();
module->filters = listCreate();
module->in_call = 0;
+ module->in_hook = 0;
ctx->module = module;
}
@@ -5859,7 +5861,7 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
listRewind(RedisModule_EventListeners,&li);
while((ln = listNext(&li))) {
RedisModuleEventListener *el = ln->value;
- if (el->event.id == eid) {
+ if (el->event.id == eid && !el->module->in_hook) {
RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
ctx.module = el->module;
ctx.client = moduleFreeContextReusedClient;
@@ -5876,7 +5878,9 @@ void moduleFireServerEvent(uint64_t eid, int subid, void *data) {
if (fi->dbnum != -1)
selectDb(ctx.client, fi->dbnum);
}
+ el->module->in_hook = 1;
el->callback(&ctx,el->event,subid,moduledata);
+ el->module->in_hook = 0;
moduleFreeContext(&ctx);
}
}