existing shared memory, naming, and waiting infrastructure is not suitable for this purpose, and is not used.
*/
-// 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/runtime/issues/6014.
-#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && !(defined(HOST_ARM) || defined(HOST_ARM64) || defined(__FreeBSD__))
+// - 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/runtime/issues/6014.
+// - On FreeBSD, pthread process-shared robust mutexes cannot be placed in shared memory mapped independently by the processes
+// involved. See https://github.com/dotnet/runtime/issues/10519.
+// - On OSX, pthread robust mutexes were/are not available at the time of this writing. In case they are made available in the
+// future, their use is disabled for compatibility.
+#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && \
+ HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && \
+ !(defined(HOST_ARM) || defined(HOST_ARM64) || defined(__FreeBSD__) || defined(TARGET_OSX))
+
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 1
#else
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 0
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SharedMemorySharedDataHeader
-SIZE_T SharedMemorySharedDataHeader::DetermineTotalByteCount(SIZE_T dataByteCount)
+SIZE_T SharedMemorySharedDataHeader::GetUsedByteCount(SIZE_T dataByteCount)
{
- return SharedMemoryHelpers::AlignUp(sizeof(SharedMemorySharedDataHeader) + dataByteCount, GetVirtualPageSize());
+ return sizeof(SharedMemorySharedDataHeader) + dataByteCount;
+}
+
+SIZE_T SharedMemorySharedDataHeader::GetTotalByteCount(SIZE_T dataByteCount)
+{
+ return SharedMemoryHelpers::AlignUp(GetUsedByteCount(dataByteCount), GetVirtualPageSize());
}
SharedMemorySharedDataHeader::SharedMemorySharedDataHeader(SharedMemoryType type, UINT8 version)
{
_ASSERTE(
processDataHeader->GetSharedDataTotalByteCount() ==
- SharedMemorySharedDataHeader::DetermineTotalByteCount(sharedDataByteCount));
+ SharedMemorySharedDataHeader::GetTotalByteCount(sharedDataByteCount));
processDataHeader->IncRefCount();
return processDataHeader;
}
}
// Set or validate the file length
- SIZE_T sharedDataTotalByteCount = SharedMemorySharedDataHeader::DetermineTotalByteCount(sharedDataByteCount);
+ SIZE_T sharedDataUsedByteCount = SharedMemorySharedDataHeader::GetUsedByteCount(sharedDataByteCount);
+ SIZE_T sharedDataTotalByteCount = SharedMemorySharedDataHeader::GetTotalByteCount(sharedDataByteCount);
if (createdFile)
{
SharedMemoryHelpers::SetFileSize(fileDescriptor, sharedDataTotalByteCount);
}
- else if (SharedMemoryHelpers::GetFileSize(fileDescriptor) != sharedDataTotalByteCount)
+ else
{
- throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::HeaderMismatch));
+ SIZE_T currentFileSize = SharedMemoryHelpers::GetFileSize(fileDescriptor);
+ if (currentFileSize < sharedDataUsedByteCount)
+ {
+ throw SharedMemoryException(static_cast<DWORD>(SharedMemoryError::HeaderMismatch));
+ }
+ if (currentFileSize < sharedDataTotalByteCount)
+ {
+ SharedMemoryHelpers::SetFileSize(fileDescriptor, sharedDataTotalByteCount);
+ }
}
// Acquire and hold a shared file lock on the shared memory file as long as it is open, to indicate that this process is
{
if (clearContents)
{
- memset(mappedBuffer, 0, sharedDataTotalByteCount);
+ memset(mappedBuffer, 0, sharedDataUsedByteCount);
}
sharedDataHeader = new(mappedBuffer) SharedMemorySharedDataHeader(requiredSharedDataHeader);
}