Named mutex: Use flock instead of pthread process-shared mutex in some more cases
authorKoundinya Veluri <kouvel@microsoft.com>
Mon, 27 Jun 2016 17:53:28 +0000 (10:53 -0700)
committerKoundinya Veluri <kouvel@microsoft.com>
Tue, 5 Jul 2016 23:10:15 +0000 (16:10 -0700)
Workaround for dotnet/coreclr#5456:
- Sometimes, a timed wait operation is not getting released, causing a hang
- Due to the hang, it is not possible to detect this issue with code
- Temporarily disabled the use of pthread process-shared mutexes on ARM/ARM64. File locks will be used instead.

Workaround for dotnet/coreclr#5872:
- On Alpine Linux, a pthread process-shared robust mutex is detecting the case where a process abandons the mutex when it exits while holding the lock, but is putting the mutex into an unrecoverable state (ENOTRECOVERABLE) instead of assigning lock ownership to the next thread that is released from a wait for a lock and notifying of abandonment (EOWNERDEAD).
- Added a test case to detect this issue, to have it use file locks instead

Close dotnet/coreclr#5456

Commit migrated from https://github.com/dotnet/coreclr/commit/f63816767aee67509ac3c61e94ff95d371471493

src/coreclr/src/pal/src/config.h.in
src/coreclr/src/pal/src/configure.cmake
src/coreclr/src/pal/src/include/pal/mutex.hpp
src/coreclr/src/pal/src/synchobj/mutex.cpp

index c3bf974..7997a6f 100644 (file)
 #cmakedefine01 HAS_FTRUNCATE_LENGTH_ISSUE
 #cmakedefine01 UNWIND_CONTEXT_IS_UCONTEXT_T
 #cmakedefine01 HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#cmakedefine01 HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES
 #cmakedefine BSD_REGS_STYLE(reg, RR, rr) @BSD_REGS_STYLE@
 #cmakedefine01 HAVE_SCHED_OTHER_ASSIGNABLE
 
index b4e7489..d8eadac 100644 (file)
@@ -1025,6 +1025,195 @@ int main()
 }" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
 set(CMAKE_REQUIRED_LIBRARIES)
 
+if(NOT CLR_CMAKE_PLATFORM_ARCH_ARM AND NOT CLR_CMAKE_PLATFORM_ARCH_ARM64)
+  set(CMAKE_REQUIRED_LIBRARIES pthread)
+  check_cxx_source_runs("
+  // This test case verifies the pthread process-shared robust mutex's cross-process abandon detection. The parent process starts
+  // a child process that locks the mutex, the process process then waits to acquire the lock, and the child process abandons the
+  // mutex by exiting the process while holding the lock. The parent process should then be released from its wait, be assigned
+  // ownership of the lock, and be notified that the mutex was abandoned.
+  
+  #include <sys/mman.h>
+  #include <sys/time.h>
+  
+  #include <errno.h>
+  #include <pthread.h>
+  #include <stdio.h>
+  #include <unistd.h>
+  
+  #include <new>
+  using namespace std;
+  
+  struct Shm
+  {
+      pthread_mutex_t syncMutex;
+      pthread_cond_t syncCondition;
+      pthread_mutex_t robustMutex;
+      int conditionValue;
+  
+      Shm() : conditionValue(0)
+      {
+      }
+  } *shm;
+  
+  int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
+  {
+      int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
+      if (getTimeResult != 0)
+      {
+          struct timeval tv;
+          getTimeResult = gettimeofday(&tv, NULL);
+          if (getTimeResult != 0)
+              return 1;
+          timeoutTimeRef->tv_sec = tv.tv_sec;
+          timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
+      }
+      timeoutTimeRef->tv_sec += 30;
+      return 0;
+  }
+  
+  int WaitForConditionValue(int desiredConditionValue)
+  {
+      struct timespec timeoutTime;
+      if (GetFailTimeoutTime(&timeoutTime) != 0)
+          return 1;
+      if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
+          return 1;
+  
+      if (shm->conditionValue != desiredConditionValue)
+      {
+          if (GetFailTimeoutTime(&timeoutTime) != 0)
+              return 1;
+          if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
+              return 1;
+          if (shm->conditionValue != desiredConditionValue)
+              return 1;
+      }
+  
+      if (pthread_mutex_unlock(&shm->syncMutex) != 0)
+          return 1;
+      return 0;
+  }
+  
+  int SetConditionValue(int newConditionValue)
+  {
+      struct timespec timeoutTime;
+      if (GetFailTimeoutTime(&timeoutTime) != 0)
+          return 1;
+      if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
+          return 1;
+  
+      shm->conditionValue = newConditionValue;
+      if (pthread_cond_signal(&shm->syncCondition) != 0)
+          return 1;
+  
+      if (pthread_mutex_unlock(&shm->syncMutex) != 0)
+          return 1;
+      return 0;
+  }
+  
+  void DoTest_Child();
+  
+  int DoTest()
+  {
+      // Map some shared memory
+      void *shmBuffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+      if (shmBuffer == MAP_FAILED)
+          return 1;
+      shm = new(shmBuffer) Shm;
+  
+      // Create sync mutex
+      pthread_mutexattr_t syncMutexAttributes;
+      if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
+          return 1;
+      if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
+          return 1;
+      if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
+          return 1;
+      if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
+          return 1;
+  
+      // Create sync condition
+      pthread_condattr_t syncConditionAttributes;
+      if (pthread_condattr_init(&syncConditionAttributes) != 0)
+          return 1;
+      if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
+          return 1;
+      if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
+          return 1;
+      if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
+          return 1;
+  
+      // Create the robust mutex that will be tested
+      pthread_mutexattr_t robustMutexAttributes;
+      if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
+          return 1;
+      if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
+          return 1;
+      if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
+          return 1;
+      if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
+          return 1;
+      if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
+          return 1;
+  
+      // Start child test process
+      int error = fork();
+      if (error == -1)
+          return 1;
+      if (error == 0)
+      {
+          DoTest_Child();
+          return -1;
+      }
+  
+      // Wait for child to take a lock
+      WaitForConditionValue(1);
+  
+      // Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
+      struct timespec timeoutTime;
+      if (GetFailTimeoutTime(&timeoutTime) != 0)
+          return 1;
+      error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
+      if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
+          return 1;
+      if (pthread_mutex_consistent(&shm->robustMutex) != 0)
+          return 1;
+  
+      if (pthread_mutex_unlock(&shm->robustMutex) != 0)
+          return 1;
+      if (pthread_mutex_destroy(&shm->robustMutex) != 0)
+          return 1;
+      return 0;
+  }
+  
+  void DoTest_Child()
+  {
+      // Lock the robust mutex
+      struct timespec timeoutTime;
+      if (GetFailTimeoutTime(&timeoutTime) != 0)
+          return;
+      if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
+          return;
+  
+      // Notify parent that robust mutex is locked
+      if (SetConditionValue(1) != 0)
+          return;
+  
+      // Wait a short period to let the parent block on waiting for a lock
+      sleep(1);
+  
+      // Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
+  }
+  
+  int main()
+  {
+      int result = DoTest();
+      return result >= 0 ? result : 0;
+  }" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
+  set(CMAKE_REQUIRED_LIBRARIES)
+endif()
+
 if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
   if(NOT HAVE_LIBUUID_H)
     unset(HAVE_LIBUUID_H CACHE)
index 3d082d5..6a46689 100644 (file)
@@ -69,6 +69,14 @@ DWORD SPINLOCKTryAcquire (LONG * lock);
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Named mutex
 
+// Temporarily disabling usage of pthread process-shared mutexes on ARM/ARM64 due to functional issues that cannot easily be
+// detected with code due to hangs. See https://github.com/dotnet/coreclr/issues/5456.
+#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && !(defined(_ARM_) || defined(_ARM64_))
+    #define NAMED_MUTEX_USE_PTHREAD_MUTEX 1
+#else
+    #define NAMED_MUTEX_USE_PTHREAD_MUTEX 0
+#endif
+
 enum class NamedMutexError : DWORD
 {
     MaximumRecursiveLocksReached = ERROR_NOT_ENOUGH_MEMORY,
@@ -83,7 +91,7 @@ enum class MutexTryAcquireLockResult
     TimedOut
 };
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
 class MutexHelpers
 {
 public:
@@ -93,16 +101,16 @@ public:
     static MutexTryAcquireLockResult TryAcquireLock(pthread_mutex_t *mutex, DWORD timeoutMilliseconds);
     static void ReleaseLock(pthread_mutex_t *mutex);
 };
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 
 class NamedMutexSharedData
 {
 private:
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
     pthread_mutex_t m_lock;
-#else // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     UINT32 m_timedWaiterCount;
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
     UINT32 m_lockOwnerProcessId;
     UINT64 m_lockOwnerThreadId;
     bool m_isAbandoned;
@@ -111,15 +119,15 @@ public:
     NamedMutexSharedData();
     ~NamedMutexSharedData();
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
 public:
     pthread_mutex_t *GetLock();
-#else // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 public:
     bool HasAnyTimedWaiters() const;
     void IncTimedWaiterCount();
     void DecTimedWaiterCount();
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 
 public:
     bool IsAbandoned() const;
@@ -142,10 +150,10 @@ private:
     SharedMemoryProcessDataHeader *m_processDataHeader;
     NamedMutexSharedData *m_sharedData;
     SIZE_T m_lockCount;
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     HANDLE m_processLockHandle;
     int m_sharedLockFileDescriptor;
-#endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     CorUnix::CPalThread *m_lockOwnerThread;
     NamedMutexProcessData *m_nextInThreadOwnedNamedMutexList;
 
@@ -158,10 +166,10 @@ private:
 public:
     NamedMutexProcessData(
         SharedMemoryProcessDataHeader *processDataHeader
-    #if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+    #if !NAMED_MUTEX_USE_PTHREAD_MUTEX
         ,
         int sharedLockFileDescriptor
-    #endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+    #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     );
     virtual void Close(bool isAbruptShutdown, bool releaseSharedData) override;
 
index 1db4303..d929eaa 100644 (file)
@@ -31,6 +31,7 @@ SET_DEFAULT_DEBUG_CHANNEL(SYNC); // some headers have code with asserts, so do t
 
 #include "../synchmgr/synchmanager.hpp"
 
+#include <sys/file.h>
 #include <sys/types.h>
 
 #include <errno.h>
@@ -785,7 +786,7 @@ DWORD SPINLOCKTryAcquire (LONG * lock)
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // MutexHelpers
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
 void MutexHelpers::InitializeProcessSharedRobustRecursiveMutex(pthread_mutex_t *mutex)
 {
     _ASSERTE(mutex != nullptr);
@@ -901,30 +902,30 @@ void MutexHelpers::ReleaseLock(pthread_mutex_t *mutex)
     int unlockResult = pthread_mutex_unlock(mutex);
     _ASSERTE(unlockResult == 0);
 }
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 // NamedMutexSharedData
 
 NamedMutexSharedData::NamedMutexSharedData()
     :
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     m_timedWaiterCount(0),
-#endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     m_lockOwnerProcessId(SharedMemoryHelpers::InvalidProcessId),
     m_lockOwnerThreadId(SharedMemoryHelpers::InvalidSharedThreadId),
     m_isAbandoned(false)
 {
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     static_assert_no_msg(sizeof(m_timedWaiterCount) == sizeof(LONG)); // for interlocked operations
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 
     _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
     _ASSERTE(SharedMemoryManager::IsCreationDeletionFileLockAcquired());
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
     MutexHelpers::InitializeProcessSharedRobustRecursiveMutex(&m_lock);
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 }
 
 NamedMutexSharedData::~NamedMutexSharedData()
@@ -932,17 +933,17 @@ NamedMutexSharedData::~NamedMutexSharedData()
     _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
     _ASSERTE(SharedMemoryManager::IsCreationDeletionFileLockAcquired());
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
     MutexHelpers::DestroyMutex(&m_lock);
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 }
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
 pthread_mutex_t *NamedMutexSharedData::GetLock()
 {
     return &m_lock;
 }
-#else // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 bool NamedMutexSharedData::HasAnyTimedWaiters() const
 {
     return
@@ -966,7 +967,7 @@ void NamedMutexSharedData::DecTimedWaiterCount()
     ULONG newValue = InterlockedDecrement(reinterpret_cast<LONG *>(&m_timedWaiterCount));
     _ASSERTE(newValue + 1 != 0);
 }
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 
 bool NamedMutexSharedData::IsAbandoned() const
 {
@@ -1043,31 +1044,31 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
         bool m_acquiredCreationDeletionProcessLock;
         bool m_acquiredCreationDeletionFileLock;
         SharedMemoryProcessDataHeader *m_processDataHeader;
-    #if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+    #if !NAMED_MUTEX_USE_PTHREAD_MUTEX
         char *m_lockFilePath;
         SIZE_T m_sessionDirectoryPathCharCount;
         bool m_createdLockFile;
         int m_lockFileDescriptor;
-    #endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+    #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
         bool m_cancel;
 
         AutoCleanup()
             : m_acquiredCreationDeletionProcessLock(false),
             m_acquiredCreationDeletionFileLock(false),
             m_processDataHeader(nullptr),
-        #if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+        #if !NAMED_MUTEX_USE_PTHREAD_MUTEX
             m_lockFilePath(nullptr),
             m_sessionDirectoryPathCharCount(0),
             m_createdLockFile(false),
             m_lockFileDescriptor(-1),
-        #endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+        #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
             m_cancel(false)
         {
         }
 
         ~AutoCleanup()
         {
-        #if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+        #if !NAMED_MUTEX_USE_PTHREAD_MUTEX
             if (!m_cancel)
             {
                 if (m_lockFileDescriptor != -1)
@@ -1088,7 +1089,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
                     rmdir(m_lockFilePath);
                 }
             }
-        #endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+        #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 
             if (m_acquiredCreationDeletionFileLock)
             {
@@ -1145,7 +1146,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
 
     if (processDataHeader->GetData() == nullptr)
     {
-    #if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+    #if !NAMED_MUTEX_USE_PTHREAD_MUTEX
         // Create the lock files directory
         char lockFilePath[SHARED_MEMORY_MAX_FILE_PATH_CHAR_COUNT + 1];
         SIZE_T lockFilePathCharCount =
@@ -1182,7 +1183,7 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
         }
         autoCleanup.m_createdLockFile = created;
         autoCleanup.m_lockFileDescriptor = lockFileDescriptor;
-    #endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+    #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 
         // Create the process data
         void *processDataBuffer = SharedMemoryHelpers::Alloc(sizeof(NamedMutexProcessData));
@@ -1191,10 +1192,10 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
             new(processDataBuffer)
             NamedMutexProcessData(
                 processDataHeader
-            #if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+            #if !NAMED_MUTEX_USE_PTHREAD_MUTEX
                 ,
                 lockFileDescriptor
-            #endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+            #endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
             );
         autoFreeProcessDataBuffer.Cancel();
         processDataHeader->SetData(processData);
@@ -1213,24 +1214,24 @@ SharedMemoryProcessDataHeader *NamedMutexProcessData::CreateOrOpen(
 
 NamedMutexProcessData::NamedMutexProcessData(
     SharedMemoryProcessDataHeader *processDataHeader
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     ,
     int sharedLockFileDescriptor
-#endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 )
     :
     m_processDataHeader(processDataHeader),
     m_lockCount(0),
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     m_sharedLockFileDescriptor(sharedLockFileDescriptor),
-#endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     m_lockOwnerThread(nullptr),
     m_nextInThreadOwnedNamedMutexList(nullptr)
 {
     _ASSERTE(SharedMemoryManager::IsCreationDeletionProcessLockAcquired());
     _ASSERTE(processDataHeader != nullptr);
 
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     _ASSERTE(sharedLockFileDescriptor != -1);
 
     m_processLockHandle = CreateMutex(nullptr /* lpMutexAttributes */, false /* bInitialOwner */, nullptr /* lpName */);
@@ -1238,7 +1239,7 @@ NamedMutexProcessData::NamedMutexProcessData(
     {
         throw SharedMemoryException(GetLastError());
     }
-#endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 }
 
 void NamedMutexProcessData::Close(bool isAbruptShutdown, bool releaseSharedData)
@@ -1272,7 +1273,7 @@ void NamedMutexProcessData::Close(bool isAbruptShutdown, bool releaseSharedData)
         }
     }
 
-#if !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if !NAMED_MUTEX_USE_PTHREAD_MUTEX
     if (!isAbruptShutdown)
     {
         CloseHandle(m_processLockHandle);
@@ -1295,7 +1296,7 @@ void NamedMutexProcessData::Close(bool isAbruptShutdown, bool releaseSharedData)
     unlink(path);
     path[sessionDirectoryPathCharCount] = '\0';
     rmdir(path);
-#endif // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // !NAMED_MUTEX_USE_PTHREAD_MUTEX
 }
 
 NamedMutexSharedData *NamedMutexProcessData::GetSharedData() const
@@ -1325,7 +1326,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(DWORD timeoutMil
 {
     NamedMutexSharedData *sharedData = GetSharedData();
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
     MutexTryAcquireLockResult result = MutexHelpers::TryAcquireLock(sharedData->GetLock(), timeoutMilliseconds);
     if (result == MutexTryAcquireLockResult::TimedOut)
     {
@@ -1355,7 +1356,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(DWORD timeoutMil
     }
 
     // The non-recursive case is handled below (skip the #else and see below that)
-#else // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     // If a timeout is specified, determine the start time
     DWORD startTime = 0;
     if (timeoutMilliseconds != static_cast<DWORD>(-1) && timeoutMilliseconds != 0)
@@ -1515,7 +1516,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(DWORD timeoutMil
         sharedData->IsLockOwnedByAnyThread()
             ? MutexTryAcquireLockResult::AcquiredLockButMutexWasAbandoned
             : MutexTryAcquireLockResult::AcquiredLock;
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 
     sharedData->SetLockOwnerToCurrentThread();
     m_lockCount = 1;
@@ -1574,10 +1575,10 @@ void NamedMutexProcessData::ActuallyReleaseLock()
 
     sharedData->ClearLockOwner();
 
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#if NAMED_MUTEX_USE_PTHREAD_MUTEX
     MutexHelpers::ReleaseLock(sharedData->GetLock());
-#else // !HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#else // !NAMED_MUTEX_USE_PTHREAD_MUTEX
     SharedMemoryHelpers::ReleaseFileLock(m_sharedLockFileDescriptor);
     ReleaseMutex(m_processLockHandle);
-#endif // HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
+#endif // NAMED_MUTEX_USE_PTHREAD_MUTEX
 }