@@ -4895,14 +4895,17 @@ void RM_FreeThreadSafeContext(RedisModuleCtx *ctx) {
4895
4895
zfree (ctx);
4896
4896
}
4897
4897
4898
+ static bool g_fModuleThread = false ;
4898
4899
/* Acquire the server lock before executing a thread safe API call.
4899
4900
* This is not needed for `RedisModule_Reply*` calls when there is
4900
4901
* a blocked client connected to the thread safe context. */
4901
4902
void RM_ThreadSafeContextLock (RedisModuleCtx *ctx) {
4902
4903
UNUSED (ctx);
4903
- moduleAcquireGIL (FALSE /* fServerThread*/ );
4904
- if (serverTL == nullptr )
4904
+ if (serverTL == nullptr ) {
4905
4905
serverTL = &g_pserver->rgthreadvar [IDX_EVENT_LOOP_MAIN]; // arbitrary module threads get the main thread context
4906
+ g_fModuleThread = true ;
4907
+ }
4908
+ moduleAcquireGIL (FALSE /* fServerThread*/ );
4906
4909
}
4907
4910
4908
4911
/* Release the server lock after a thread safe API call was executed. */
@@ -4911,10 +4914,20 @@ void RM_ThreadSafeContextUnlock(RedisModuleCtx *ctx) {
4911
4914
moduleReleaseGIL (FALSE /* fServerThread*/ );
4912
4915
}
4913
4916
4917
+ // A module may be triggered synchronously in a non-module context. In this scenario we don't lock again
4918
+ // as the server thread acquisition is sufficient. If we did try to lock we would deadlock
4919
+ static bool FModuleCallBackLock (bool fServerThread )
4920
+ {
4921
+ return !fServerThread && aeThreadOwnsLock () && !g_fModuleThread && s_cAcquisitionsServer > 0 ;
4922
+ }
4914
4923
void moduleAcquireGIL (int fServerThread ) {
4915
4924
std::unique_lock<std::mutex> lock (s_mutex);
4916
4925
int *pcheck = fServerThread ? &s_cAcquisitionsModule : &s_cAcquisitionsServer;
4917
4926
4927
+ if (FModuleCallBackLock (fServerThread )) {
4928
+ return ;
4929
+ }
4930
+
4918
4931
while (*pcheck > 0 )
4919
4932
s_cv.wait (lock);
4920
4933
@@ -4932,6 +4945,10 @@ void moduleAcquireGIL(int fServerThread) {
4932
4945
void moduleReleaseGIL (int fServerThread ) {
4933
4946
std::unique_lock<std::mutex> lock (s_mutex);
4934
4947
4948
+ if (FModuleCallBackLock (fServerThread )) {
4949
+ return ;
4950
+ }
4951
+
4935
4952
if (fServerThread )
4936
4953
{
4937
4954
--s_cAcquisitionsServer;
0 commit comments