From a74c1ee1bfdd9cba590cec705b8d67e706e3b567 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 19 Feb 2024 21:40:07 +0100 Subject: [PATCH] CPLCreateOrAcquireMutexEx(): fix TSAN/valgrind --tool=helgrind warning about lock-order inversion (fixes #1108) --- port/cpl_multiproc.cpp | 60 ++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/port/cpl_multiproc.cpp b/port/cpl_multiproc.cpp index 2658ac1aa5de..8e620fbab50c 100644 --- a/port/cpl_multiproc.cpp +++ b/port/cpl_multiproc.cpp @@ -318,14 +318,14 @@ CPLMutex *CPLCreateOrAcquireMasterMutex(double dfWaitInSeconds = 1000.0) #ifdef MUTEX_NONE -int CPLCreateOrAcquireMutexEx(CPLMutex **phMutex, double dfWaitInSeconds, - int nOptions) +bool CPLCreateOrAcquireMutexEx(CPLMutex **phMutex, double dfWaitInSeconds, + int nOptions) { return false; } #else -int CPLCreateOrAcquireMutexEx(CPLMutex **phMutex, double dfWaitInSeconds, - int nOptions) +bool CPLCreateOrAcquireMutexEx(CPLMutex **phMutex, double dfWaitInSeconds, + int nOptions) { bool bSuccess = false; @@ -358,16 +358,16 @@ int CPLCreateOrAcquireMutexEx(CPLMutex **phMutex, double dfWaitInSeconds, /************************************************************************/ #ifdef MUTEX_NONE -static int CPLCreateOrAcquireMutexInternal(CPLLock **phLock, - double dfWaitInSeconds, - CPLLockType eType) +static bool CPLCreateOrAcquireMutexInternal(CPLLock **phLock, + double dfWaitInSeconds, + CPLLockType eType) { return false; } #else -static int CPLCreateOrAcquireMutexInternal(CPLLock **phLock, - double dfWaitInSeconds, - CPLLockType eType) +static bool CPLCreateOrAcquireMutexInternal(CPLLock **phLock, + double dfWaitInSeconds, + CPLLockType eType) { bool bSuccess = false; @@ -1462,35 +1462,31 @@ int CPLCreateOrAcquireMutexEx(CPLMutex **phMutex, double dfWaitInSeconds, int nOptions) { - bool bSuccess = false; - pthread_mutex_lock(&global_mutex); if (*phMutex == nullptr) { *phMutex = CPLCreateMutexInternal(true, nOptions); - bSuccess = *phMutex != nullptr; + const bool bSuccess = *phMutex != nullptr; pthread_mutex_unlock(&global_mutex); + if (!bSuccess) + return false; } else { pthread_mutex_unlock(&global_mutex); - - bSuccess = CPL_TO_BOOL(CPLAcquireMutex(*phMutex, dfWaitInSeconds)); } - return bSuccess; + return CPL_TO_BOOL(CPLAcquireMutex(*phMutex, dfWaitInSeconds)); } /************************************************************************/ /* CPLCreateOrAcquireMutexInternal() */ /************************************************************************/ -static int CPLCreateOrAcquireMutexInternal(CPLLock **phLock, - double dfWaitInSeconds, - CPLLockType eType) +static bool CPLCreateOrAcquireMutexInternal(CPLLock **phLock, + double dfWaitInSeconds, + CPLLockType eType) { - bool bSuccess = false; - pthread_mutex_lock(&global_mutex); if (*phLock == nullptr) { @@ -1507,18 +1503,17 @@ static int CPLCreateOrAcquireMutexInternal(CPLLock **phLock, *phLock = nullptr; } } - bSuccess = *phLock != nullptr; + const bool bSuccess = *phLock != nullptr; pthread_mutex_unlock(&global_mutex); + if (!bSuccess) + return false; } else { pthread_mutex_unlock(&global_mutex); - - bSuccess = - CPL_TO_BOOL(CPLAcquireMutex((*phLock)->u.hMutex, dfWaitInSeconds)); } - return bSuccess; + return CPL_TO_BOOL(CPLAcquireMutex((*phLock)->u.hMutex, dfWaitInSeconds)); } /************************************************************************/ @@ -1624,20 +1619,23 @@ static CPLMutex *CPLCreateMutexInternal(bool bAlreadyInGlobalLock, int nOptions) psItem->nOptions = nOptions; CPLInitMutex(psItem); - // Mutexes are implicitly acquired when created. - CPLAcquireMutex(reinterpret_cast(psItem), 0.0); - return reinterpret_cast(psItem); } CPLMutex *CPLCreateMutex() { - return CPLCreateMutexInternal(false, CPL_MUTEX_RECURSIVE); + CPLMutex *mutex = CPLCreateMutexInternal(false, CPL_MUTEX_RECURSIVE); + if (mutex) + CPLAcquireMutex(mutex, 0); + return mutex; } CPLMutex *CPLCreateMutexEx(int nOptions) { - return CPLCreateMutexInternal(false, nOptions); + CPLMutex *mutex = CPLCreateMutexInternal(false, nOptions); + if (mutex) + CPLAcquireMutex(mutex, 0); + return mutex; } /************************************************************************/