diff options
author | antirez <antirez@gmail.com> | 2017-05-03 11:26:21 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2017-05-03 11:26:21 +0200 |
commit | 3fcf959e609e850a114d4016843e4c991066ebac (patch) | |
tree | 6ec7dc7bd6ecb0d8b36b247018ab999c5a75290e /src/modules/helloblock.c | |
parent | ba4a5a3255d9a28c6aa9ead36f640705704249a7 (diff) | |
download | redis-3fcf959e609e850a114d4016843e4c991066ebac.tar.gz |
Modules TSC: Release the GIL for all the time we are blocked.
Instead of giving the module background operations just a small time to
run in the beforeSleep() function, we can have the lock released for all
the time we are blocked in the multiplexing syscall.
Diffstat (limited to 'src/modules/helloblock.c')
-rw-r--r-- | src/modules/helloblock.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/modules/helloblock.c b/src/modules/helloblock.c index 71ec9b121..e760e33fb 100644 --- a/src/modules/helloblock.c +++ b/src/modules/helloblock.c @@ -105,6 +105,45 @@ int HelloBlock_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int a return REDISMODULE_OK; } +/* The thread entry point that actually executes the blocking part + * of the command HELLO.KEYS. */ +void *HelloKeys_ThreadMain(void *arg) { + RedisModuleBlockedClient *bc = arg; + RedisModuleCtx *ctx = RedisModule_GetThreadSafeContext(bc); + + RedisModule_ThreadSafeContextLock(ctx); + RedisModule_ReplyWithLongLong(ctx,1234); + RedisModule_ThreadSafeContextUnlock(ctx); + + RedisModule_UnblockClient(bc,NULL); + return NULL; +} + +/* HELLO.KEYS -- Return all the keys in the current database without blocking + * the server. The keys do not represent a point-in-time state so only the keys + * that were in the database from the start to the end are guaranteed to be + * there. */ +int HelloKeys_RedisCommand(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + REDISMODULE_NOT_USED(argv); + if (argc != 1) return RedisModule_WrongArity(ctx); + + pthread_t tid; + + /* Note that when blocking the client we do not set any callback: no + * timeout is possible since we passed '0', nor we need a reply callback + * because we'll use the thread safe context to accumulate a reply. */ + RedisModuleBlockedClient *bc = RedisModule_BlockClient(ctx,NULL,NULL,NULL,0); + + /* Now that we setup a blocking client, we need to pass the control + * to the thread. However we need to pass arguments to the thread: + * the reference to the blocked client handle. */ + if (pthread_create(&tid,NULL,HelloKeys_ThreadMain,bc) != 0) { + RedisModule_AbortBlock(bc); + return RedisModule_ReplyWithError(ctx,"-ERR Can't start thread"); + } + return REDISMODULE_OK; +} + /* This function must be present on each Redis module. It is used in order to * register the commands into the Redis server. */ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { @@ -117,6 +156,9 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) if (RedisModule_CreateCommand(ctx,"hello.block", HelloBlock_RedisCommand,"",0,0,0) == REDISMODULE_ERR) return REDISMODULE_ERR; + if (RedisModule_CreateCommand(ctx,"hello.keys", + HelloKeys_RedisCommand,"",0,0,0) == REDISMODULE_ERR) + return REDISMODULE_ERR; return REDISMODULE_OK; } |