Skip to content

Commit 4f01ff5

Browse files
authored
Fix named mutexes on OSX to work between arm64 and emulated x64 processes (#62765)
- The page size is different between arm64 processes and emulated x64 processes - The shared memory file size is set to the page size and there was a strict check on the file size, leading to an exception from the second process of a different arch that tries to share the same mutex - Made the file size check less strict, and allowed an arch to increase but not decrease the file size such that it can be mapped at page size granularity - Fix for #62140 in main
1 parent dc6a86d commit 4f01ff5

File tree

3 files changed

+33
-11
lines changed

3 files changed

+33
-11
lines changed

src/coreclr/pal/src/include/pal/mutex.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,16 @@ Miscellaneous
120120
existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
121121
*/
122122

123-
// Temporarily disabling usage of pthread process-shared mutexes on ARM/ARM64 due to functional issues that cannot easily be
124-
// detected with code due to hangs. See https://github.com/dotnet/runtime/issues/6014.
125-
#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && !(defined(HOST_ARM) || defined(HOST_ARM64) || defined(__FreeBSD__))
123+
// - Temporarily disabling usage of pthread process-shared mutexes on ARM/ARM64 due to functional issues that cannot easily be
124+
// detected with code due to hangs. See https://github.com/dotnet/runtime/issues/6014.
125+
// - On FreeBSD, pthread process-shared robust mutexes cannot be placed in shared memory mapped independently by the processes
126+
// involved. See https://github.com/dotnet/runtime/issues/10519.
127+
// - On OSX, pthread robust mutexes were/are not available at the time of this writing. In case they are made available in the
128+
// future, their use is disabled for compatibility.
129+
#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && \
130+
HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && \
131+
!(defined(HOST_ARM) || defined(HOST_ARM64) || defined(__FreeBSD__) || defined(TARGET_OSX))
132+
126133
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 1
127134
#else
128135
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 0

src/coreclr/pal/src/include/pal/sharedmemory.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ class SharedMemorySharedDataHeader
173173
};
174174

175175
public:
176-
static SIZE_T DetermineTotalByteCount(SIZE_T dataByteCount);
176+
static SIZE_T GetUsedByteCount(SIZE_T dataByteCount);
177+
static SIZE_T GetTotalByteCount(SIZE_T dataByteCount);
177178

178179
public:
179180
SharedMemorySharedDataHeader(SharedMemoryType type, UINT8 version);

src/coreclr/pal/src/sharedmemory/sharedmemory.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,14 @@ bool SharedMemoryId::AppendSessionDirectoryName(PathCharString& path) const
519519
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
520520
// SharedMemorySharedDataHeader
521521

522-
SIZE_T SharedMemorySharedDataHeader::DetermineTotalByteCount(SIZE_T dataByteCount)
522+
SIZE_T SharedMemorySharedDataHeader::GetUsedByteCount(SIZE_T dataByteCount)
523523
{
524-
return SharedMemoryHelpers::AlignUp(sizeof(SharedMemorySharedDataHeader) + dataByteCount, GetVirtualPageSize());
524+
return sizeof(SharedMemorySharedDataHeader) + dataByteCount;
525+
}
526+
527+
SIZE_T SharedMemorySharedDataHeader::GetTotalByteCount(SIZE_T dataByteCount)
528+
{
529+
return SharedMemoryHelpers::AlignUp(GetUsedByteCount(dataByteCount), GetVirtualPageSize());
525530
}
526531

527532
SharedMemorySharedDataHeader::SharedMemorySharedDataHeader(SharedMemoryType type, UINT8 version)
@@ -642,7 +647,7 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
642647
{
643648
_ASSERTE(
644649
processDataHeader->GetSharedDataTotalByteCount() ==
645-
SharedMemorySharedDataHeader::DetermineTotalByteCount(sharedDataByteCount));
650+
SharedMemorySharedDataHeader::GetTotalByteCount(sharedDataByteCount));
646651
processDataHeader->IncRefCount();
647652
return processDataHeader;
648653
}
@@ -697,14 +702,23 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
697702
}
698703

699704
// Set or validate the file length
700-
SIZE_T sharedDataTotalByteCount = SharedMemorySharedDataHeader::DetermineTotalByteCount(sharedDataByteCount);
705+
SIZE_T sharedDataUsedByteCount = SharedMemorySharedDataHeader::GetUsedByteCount(sharedDataByteCount);
706+
SIZE_T sharedDataTotalByteCount = SharedMemorySharedDataHeader::GetTotalByteCount(sharedDataByteCount);
701707
if (createdFile)
702708
{
703709
SharedMemoryHelpers::SetFileSize(fileDescriptor, sharedDataTotalByteCount);
704710
}
705-
else if (SharedMemoryHelpers::GetFileSize(fileDescriptor) != sharedDataTotalByteCount)
711+
else
706712
{
707-
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::HeaderMismatch));
713+
SIZE_T currentFileSize = SharedMemoryHelpers::GetFileSize(fileDescriptor);
714+
if (currentFileSize < sharedDataUsedByteCount)
715+
{
716+
throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::HeaderMismatch));
717+
}
718+
if (currentFileSize < sharedDataTotalByteCount)
719+
{
720+
SharedMemoryHelpers::SetFileSize(fileDescriptor, sharedDataTotalByteCount);
721+
}
708722
}
709723

710724
// Acquire and hold a shared file lock on the shared memory file as long as it is open, to indicate that this process is
@@ -726,7 +740,7 @@ SharedMemoryProcessDataHeader *SharedMemoryProcessDataHeader::CreateOrOpen(
726740
{
727741
if (clearContents)
728742
{
729-
memset(mappedBuffer, 0, sharedDataTotalByteCount);
743+
memset(mappedBuffer, 0, sharedDataUsedByteCount);
730744
}
731745
sharedDataHeader = new(mappedBuffer) SharedMemorySharedDataHeader(requiredSharedDataHeader);
732746
}

0 commit comments

Comments
 (0)