@@ -365,11 +365,7 @@ typedef struct RedisModuleCommandFilter {
365365static list *moduleCommandFilters;
366366
367367/* Module GIL Variables */
368- static int s_cAcquisitionsServer = 0 ;
369- static int s_cAcquisitionsModule = 0 ;
370- static std::mutex s_mutex;
371- static std::condition_variable s_cv;
372- static std::recursive_mutex s_mutexModule;
368+ static readWriteLock s_moduleGIL;
373369thread_local bool g_fModuleThread = false ;
374370
375371typedef void (*RedisModuleForkDoneHandler) (int exitcode, int bysignal, void *user_data);
@@ -5969,95 +5965,58 @@ void RM_ThreadSafeContextUnlock(RedisModuleCtx *ctx) {
59695965// as the server thread acquisition is sufficient. If we did try to lock we would deadlock
59705966static bool FModuleCallBackLock (bool fServerThread )
59715967{
5972- return !fServerThread && aeThreadOwnsLock () && !g_fModuleThread && s_cAcquisitionsServer > 0 ;
5968+ return !fServerThread && aeThreadOwnsLock () && !g_fModuleThread && s_moduleGIL. hasReader () ;
59735969}
59745970void moduleAcquireGIL (int fServerThread , int fExclusive ) {
5975- std::unique_lock<std::mutex> lock (s_mutex);
5976- int *pcheck = fServerThread ? &s_cAcquisitionsModule : &s_cAcquisitionsServer;
5977-
59785971 if (FModuleCallBackLock (fServerThread )) {
59795972 return ;
59805973 }
59815974
5982- while (*pcheck > 0 )
5983- s_cv.wait (lock);
5984-
59855975 if (fServerThread )
59865976 {
5987- ++s_cAcquisitionsServer ;
5977+ s_moduleGIL. acquireRead () ;
59885978 }
59895979 else
59905980 {
5991- // only try to acquire the mutexModule in exclusive mode
5992- if (fExclusive ){
5993- // It is possible that another module thread holds the GIL (and s_mutexModule as a result).
5994- // When said thread goes to release the GIL, it will wait for s_mutex, which this thread owns.
5995- // This thread is however waiting for the GIL (and s_mutexModule) that the other thread owns.
5996- // As a result, a deadlock has occured.
5997- // We release the lock on s_mutex and wait until we are able to safely acquire the GIL
5998- // in order to prevent this deadlock from occuring.
5999- while (!s_mutexModule.try_lock ())
6000- s_cv.wait (lock);
6001- }
6002- ++s_cAcquisitionsModule;
6003- fModuleGILWlocked ++;
5981+ s_moduleGIL.acquireWrite (fExclusive );
60045982 }
60055983}
60065984
60075985int moduleTryAcquireGIL (bool fServerThread , int fExclusive ) {
6008- std::unique_lock<std::mutex> lock (s_mutex, std::defer_lock);
6009- if (!lock.try_lock ())
6010- return 1 ;
6011- int *pcheck = fServerThread ? &s_cAcquisitionsModule : &s_cAcquisitionsServer;
6012-
60135986 if (FModuleCallBackLock (fServerThread )) {
60145987 return 0 ;
60155988 }
60165989
6017- if (*pcheck > 0 )
6018- return 1 ;
6019-
60205990 if (fServerThread )
60215991 {
6022- ++s_cAcquisitionsServer;
5992+ if (!s_moduleGIL.tryAcquireRead ())
5993+ return 1 ;
60235994 }
60245995 else
60255996 {
6026- // only try to acquire the mutexModule in exclusive mode
6027- if (fExclusive ){
6028- if (!s_mutexModule.try_lock ())
6029- return 1 ;
6030- }
6031- ++s_cAcquisitionsModule;
6032- fModuleGILWlocked ++;
5997+ if (!s_moduleGIL.tryAcquireWrite (fExclusive ))
5998+ return 1 ;
60335999 }
60346000 return 0 ;
60356001}
60366002
60376003void moduleReleaseGIL (int fServerThread , int fExclusive ) {
6038- std::unique_lock<std::mutex> lock (s_mutex);
6039-
60406004 if (FModuleCallBackLock (fServerThread )) {
60416005 return ;
60426006 }
6043-
6007+
60446008 if (fServerThread )
60456009 {
6046- --s_cAcquisitionsServer ;
6010+ s_moduleGIL. releaseRead () ;
60476011 }
60486012 else
60496013 {
6050- // only try to release the mutexModule in exclusive mode
6051- if (fExclusive )
6052- s_mutexModule.unlock ();
6053- --s_cAcquisitionsModule;
6054- fModuleGILWlocked --;
6014+ s_moduleGIL.releaseWrite (fExclusive );
60556015 }
6056- s_cv.notify_all ();
60576016}
60586017
60596018int moduleGILAcquiredByModule (void ) {
6060- return fModuleGILWlocked > 0 ;
6019+ return s_moduleGIL. hasWriter () ;
60616020}
60626021
60636022
0 commit comments