@@ -612,6 +612,19 @@ int moduleDelKeyIfEmpty(RedisModuleKey *key) {
612612 }
613613}
614614
615+ /* This function is used to set the thread local variables (serverTL) for
616+ * arbitrary module threads. All incoming module threads share the same set of
617+ * thread local variables (modulethreadvar).
618+ *
619+ * This is needed as some KeyDB functions use thread local variables to do things,
620+ * and we don't want to share the thread local variables of existing server threads */
621+ void moduleSetThreadVariablesIfNeeded (void ) {
622+ if (serverTL == nullptr ) {
623+ serverTL = &g_pserver->modulethreadvar ;
624+ g_fModuleThread = true ;
625+ }
626+ }
627+
615628/* --------------------------------------------------------------------------
616629 * Service API exported to modules
617630 *
@@ -2265,6 +2278,7 @@ int RM_GetContextFlags(RedisModuleCtx *ctx) {
22652278 * periodically in timer callbacks or other periodic callbacks.
22662279 */
22672280int RM_AvoidReplicaTraffic () {
2281+ moduleSetThreadVariablesIfNeeded ();
22682282 return checkClientPauseTimeoutAndReturnIfPaused ();
22692283}
22702284
@@ -2341,8 +2355,11 @@ void *RM_OpenKey(RedisModuleCtx *ctx, robj *keyname, int mode) {
23412355/* Destroy a RedisModuleKey struct (freeing is the responsibility of the caller). */
23422356static void moduleCloseKey (RedisModuleKey *key) {
23432357 int signal = SHOULD_SIGNAL_MODIFIED_KEYS (key->ctx );
2358+ moduleAcquireGIL (false );
23442359 if ((key->mode & REDISMODULE_WRITE) && signal)
23452360 signalModifiedKey (key->ctx ->client ,key->db ,key->key );
2361+ /* TODO: if (key->iter) RM_KeyIteratorStop(kp); */
2362+ moduleReleaseGIL (false );
23462363 if (key->iter ) zfree (key->iter );
23472364 RM_ZsetRangeStop (key);
23482365 if (key && key->value && key->value ->type == OBJ_STREAM &&
@@ -5595,10 +5612,7 @@ int moduleClientIsBlockedOnKeys(client *c) {
55955612 * RedisModule_BlockClientOnKeys() is accessible from the timeout
55965613 * callback via RM_GetBlockedClientPrivateData). */
55975614int RM_UnblockClient (RedisModuleBlockedClient *bc, void *privdata) {
5598- if (serverTL == nullptr ) {
5599- serverTL = &g_pserver->modulethreadvar ;
5600- g_fModuleThread = true ;
5601- }
5615+ moduleSetThreadVariablesIfNeeded ();
56025616 if (bc->blocked_on_keys ) {
56035617 /* In theory the user should always pass the timeout handler as an
56045618 * argument, but better to be safe than sorry. */
@@ -5898,10 +5912,7 @@ void RM_FreeThreadSafeContext(RedisModuleCtx *ctx) {
58985912 * a blocked client connected to the thread safe context. */
58995913void RM_ThreadSafeContextLock (RedisModuleCtx *ctx) {
59005914 UNUSED (ctx);
5901- if (serverTL == nullptr ) {
5902- serverTL = &g_pserver->modulethreadvar ;
5903- g_fModuleThread = true ;
5904- }
5915+ moduleSetThreadVariablesIfNeeded ();
59055916 moduleAcquireGIL (FALSE /* fServerThread*/ , true /* fExclusive*/ );
59065917}
59075918
0 commit comments