summaryrefslogtreecommitdiff
path: root/src/modules/helloblock.c
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2017-05-03 11:26:21 +0200
committerantirez <antirez@gmail.com>2017-05-03 11:26:21 +0200
commit3fcf959e609e850a114d4016843e4c991066ebac (patch)
tree6ec7dc7bd6ecb0d8b36b247018ab999c5a75290e /src/modules/helloblock.c
parentba4a5a3255d9a28c6aa9ead36f640705704249a7 (diff)
downloadredis-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.c42
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;
}