summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2017-09-28 16:21:21 +0800
committerzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>2017-09-28 16:21:21 +0800
commitcb9dde3280244ec3b449f081639c37dd5a1916ab (patch)
tree76793acec5703b20d5d1201408705ed7cc5039d2
parent474adba9fa7a173d866300b1abd7cddd34cbac40 (diff)
downloadredis-cb9dde3280244ec3b449f081639c37dd5a1916ab.tar.gz
Modules: handle the conflict of registering commands
-rw-r--r--src/module.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/module.c b/src/module.c
index fda68b273..4604c0bef 100644
--- a/src/module.c
+++ b/src/module.c
@@ -615,7 +615,7 @@ int RM_CreateCommand(RedisModuleCtx *ctx, const char *name, RedisModuleCmdFunc c
sds cmdname = sdsnew(name);
/* Check if the command name is busy. */
- if (lookupCommand((char*)name) != NULL) {
+ if (lookupCommand(cmdname) != NULL) {
sdsfree(cmdname);
return REDISMODULE_ERR;
}
@@ -3661,6 +3661,28 @@ void moduleFreeModuleStructure(struct RedisModule *module) {
zfree(module);
}
+void moduleUnregisterCommands(struct RedisModule *module) {
+ /* Unregister all the commands registered by this module. */
+ dictIterator *di = dictGetSafeIterator(server.commands);
+ dictEntry *de;
+ while ((de = dictNext(di)) != NULL) {
+ struct redisCommand *cmd = dictGetVal(de);
+ if (cmd->proc == RedisModuleCommandDispatcher) {
+ RedisModuleCommandProxy *cp =
+ (void*)(unsigned long)cmd->getkeys_proc;
+ sds cmdname = cp->rediscmd->name;
+ if (cp->module == module) {
+ dictDelete(server.commands,cmdname);
+ dictDelete(server.orig_commands,cmdname);
+ sdsfree(cmdname);
+ zfree(cp->rediscmd);
+ zfree(cp);
+ }
+ }
+ }
+ dictReleaseIterator(di);
+}
+
/* Load a module and initialize it. On success C_OK is returned, otherwise
* C_ERR is returned. */
int moduleLoad(const char *path, void **module_argv, int module_argc) {
@@ -3681,7 +3703,10 @@ int moduleLoad(const char *path, void **module_argv, int module_argc) {
return C_ERR;
}
if (onload((void*)&ctx,module_argv,module_argc) == REDISMODULE_ERR) {
- if (ctx.module) moduleFreeModuleStructure(ctx.module);
+ if (ctx.module) {
+ moduleUnregisterCommands(ctx.module);
+ moduleFreeModuleStructure(ctx.module);
+ }
dlclose(handle);
serverLog(LL_WARNING,
"Module %s initialization failed. Module not loaded",path);
@@ -3715,25 +3740,7 @@ int moduleUnload(sds name) {
return REDISMODULE_ERR;
}
- /* Unregister all the commands registered by this module. */
- dictIterator *di = dictGetSafeIterator(server.commands);
- dictEntry *de;
- while ((de = dictNext(di)) != NULL) {
- struct redisCommand *cmd = dictGetVal(de);
- if (cmd->proc == RedisModuleCommandDispatcher) {
- RedisModuleCommandProxy *cp =
- (void*)(unsigned long)cmd->getkeys_proc;
- sds cmdname = cp->rediscmd->name;
- if (cp->module == module) {
- dictDelete(server.commands,cmdname);
- dictDelete(server.orig_commands,cmdname);
- sdsfree(cmdname);
- zfree(cp->rediscmd);
- zfree(cp);
- }
- }
- }
- dictReleaseIterator(di);
+ moduleUnregisterCommands(module);
/* Unregister all the hooks. TODO: Yet no hooks support here. */