Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
c549513a
Commit
c549513a
authored
Oct 02, 2019
by
antirez
Browse files
Modules: handle propagation when ctx is freed. Flag modules commands ctx.
parent
758b39be
Changes
1
Show whitespace changes
Inline
Side-by-side
src/module.c
View file @
c549513a
...
@@ -158,6 +158,7 @@ typedef struct RedisModuleCtx RedisModuleCtx;
...
@@ -158,6 +158,7 @@ typedef struct RedisModuleCtx RedisModuleCtx;
#define REDISMODULE_CTX_BLOCKED_TIMEOUT (1<<4)
#define REDISMODULE_CTX_BLOCKED_TIMEOUT (1<<4)
#define REDISMODULE_CTX_THREAD_SAFE (1<<5)
#define REDISMODULE_CTX_THREAD_SAFE (1<<5)
#define REDISMODULE_CTX_BLOCKED_DISCONNECTED (1<<6)
#define REDISMODULE_CTX_BLOCKED_DISCONNECTED (1<<6)
#define REDISMODULE_CTX_MODULE_COMMAND_CALL (1<<7)
/* This represents a Redis key opened with RM_OpenKey(). */
/* This represents a Redis key opened with RM_OpenKey(). */
struct RedisModuleKey {
struct RedisModuleKey {
...
@@ -519,39 +520,42 @@ int RM_GetApi(const char *funcname, void **targetPtrPtr) {
...
@@ -519,39 +520,42 @@ int RM_GetApi(const char *funcname, void **targetPtrPtr) {
return REDISMODULE_OK;
return REDISMODULE_OK;
}
}
/* Free the context after the user function was called. */
void
moduleFreeContext
(
RedisModuleCtx
*
ctx
)
{
autoMemoryCollect
(
ctx
);
poolAllocRelease
(
ctx
);
if
(
ctx
->
postponed_arrays
)
{
zfree
(
ctx
->
postponed_arrays
);
ctx
->
postponed_arrays_count
=
0
;
serverLog
(
LL_WARNING
,
"API misuse detected in module %s: "
"RedisModule_ReplyWithArray(REDISMODULE_POSTPONED_ARRAY_LEN) "
"not matched by the same number of RedisModule_SetReplyArrayLen() "
"calls."
,
ctx
->
module
->
name
);
}
if
(
ctx
->
flags
&
REDISMODULE_CTX_THREAD_SAFE
)
freeClient
(
ctx
->
client
);
}
/* Helper function for when a command callback is called, in order to handle
/* Helper function for when a command callback is called, in order to handle
* details needed to correctly replicate commands. */
* details needed to correctly replicate commands. */
void moduleHandlePropagationAfterCommandCallback(RedisModuleCtx *ctx) {
void moduleHandlePropagationAfterCommandCallback(RedisModuleCtx *ctx) {
client *c = ctx->client;
client *c = ctx->client;
/* We don't need to do anything here if the context was never used
* in order to propagate commands. */
if (!(ctx->flags & REDISMODULE_CTX_MULTI_EMITTED)) return;
if (c->flags & CLIENT_LUA) return;
if (c->flags & CLIENT_LUA) return;
/* Handle the replication of the final EXEC, since whatever a command
/* Handle the replication of the final EXEC, since whatever a command
* emits is always wrapped around MULTI/EXEC. */
* emits is always wrapped around MULTI/EXEC. */
if
(
ctx
->
flags
&
REDISMODULE_CTX_MULTI_EMITTED
)
{
robj *propargv[1];
robj *propargv[1];
propargv[0] = createStringObject("EXEC",4);
propargv[0] = createStringObject("EXEC",4);
alsoPropagate(server.execCommand,c->db->id,propargv,1,
alsoPropagate(server.execCommand,c->db->id,propargv,1,
PROPAGATE_AOF|PROPAGATE_REPL);
PROPAGATE_AOF|PROPAGATE_REPL);
decrRefCount(propargv[0]);
decrRefCount(propargv[0]);
}
/* Free the context after the user function was called. */
void moduleFreeContext(RedisModuleCtx *ctx) {
moduleHandlePropagationAfterCommandCallback(ctx);
autoMemoryCollect(ctx);
poolAllocRelease(ctx);
if (ctx->postponed_arrays) {
zfree(ctx->postponed_arrays);
ctx->postponed_arrays_count = 0;
serverLog(LL_WARNING,
"API misuse detected in module %s: "
"RedisModule_ReplyWithArray(REDISMODULE_POSTPONED_ARRAY_LEN) "
"not matched by the same number of RedisModule_SetReplyArrayLen() "
"calls.",
ctx->module->name);
}
}
if (ctx->flags & REDISMODULE_CTX_THREAD_SAFE) freeClient(ctx->client);
}
}
/* This Redis command binds the normal Redis command invocation with commands
/* This Redis command binds the normal Redis command invocation with commands
...
@@ -560,10 +564,10 @@ void RedisModuleCommandDispatcher(client *c) {
...
@@ -560,10 +564,10 @@ void RedisModuleCommandDispatcher(client *c) {
RedisModuleCommandProxy *cp = (void*)(unsigned long)c->cmd->getkeys_proc;
RedisModuleCommandProxy *cp = (void*)(unsigned long)c->cmd->getkeys_proc;
RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
RedisModuleCtx ctx = REDISMODULE_CTX_INIT;
ctx.flags |= REDISMODULE_CTX_MODULE_COMMAND_CALL;
ctx.module = cp->module;
ctx.module = cp->module;
ctx.client = c;
ctx.client = c;
cp->func(&ctx,(void**)c->argv,c->argc);
cp->func(&ctx,(void**)c->argv,c->argc);
moduleHandlePropagationAfterCommandCallback
(
&
ctx
);
moduleFreeContext(&ctx);
moduleFreeContext(&ctx);
/* In some cases processMultibulkBuffer uses sdsMakeRoomFor to
/* In some cases processMultibulkBuffer uses sdsMakeRoomFor to
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment