commit bc281b7f56d822280813210d70908f7d34c94bfa
parent 201ebb959d5cd846ae13dd09999220ed58d6083b
Author: Paul Bone <paul@bone.id.au>
Date: Thu, 16 Oct 2025 22:26:49 +0000
Bug 1984011 - pt 4. Mutex now has a constexpr constructor on all platforms r=glandium
On windows Mutex still needs its Init method called before it can be
used - it's constructor won't fully initalise it.
Differential Revision: https://phabricator.services.mozilla.com/D262270
Diffstat:
3 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/memory/build/BaseAlloc.cpp b/memory/build/BaseAlloc.cpp
@@ -10,7 +10,7 @@
using namespace mozilla;
-Mutex base_mtx;
+MOZ_CONSTINIT Mutex base_mtx;
// Current pages that are being used for internal memory allocations. These
// pages are carved up in cacheline-size quanta, so that there is no chance of
diff --git a/memory/build/Mutex.cpp b/memory/build/Mutex.cpp
@@ -10,7 +10,7 @@
bool Mutex::TryLock() {
#if defined(XP_WIN)
- return !!TryEnterCriticalSection(&mMutex);
+ return !!TryEnterCriticalSection(mMutex.addr());
#elif defined(XP_DARWIN)
return os_unfair_lock_trylock(&mMutex);
#else
diff --git a/memory/build/Mutex.h b/memory/build/Mutex.h
@@ -18,6 +18,7 @@
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
+#include "mozilla/MaybeStorageBase.h"
#include "mozilla/ThreadSafety.h"
#if defined(XP_DARWIN)
@@ -36,13 +37,19 @@ OS_EXPORT OS_NOTHROW OS_NONNULL_ALL void os_unfair_lock_lock_with_options(
}
#endif // defined(XP_DARWIN)
-// Mutexes based on spinlocks. We can't use normal pthread spinlocks in all
+// Mutexes are based on spinlocks. We can't use normal pthread spinlocks in all
// places, because they require malloc()ed memory, which causes bootstrapping
-// issues in some cases. We also can't use constructors, because for statics,
-// they would fire after the first use of malloc, resetting the locks.
+// issues in some cases. We also can't use non-constexpr constructors, because
+// for statics, they would fire after the first use of malloc, resetting the
+// locks.
+//
+// A constexpr constructor is provided so that Mutex can be part of something
+// that is MOZ_CONSTINIT, but the mutex won't be initialised, you must still
+// call Init() before the mutex can be used.
struct MOZ_CAPABILITY("mutex") Mutex {
#if defined(XP_WIN)
- CRITICAL_SECTION mMutex;
+ // MaybeStorageBase provides a constexpr constructor.
+ mozilla::detail::MaybeStorageBase<CRITICAL_SECTION> mMutex;
#elif defined(XP_DARWIN)
os_unfair_lock mMutex = OS_UNFAIR_LOCK_INIT;
#elif defined(XP_LINUX) && !defined(ANDROID)
@@ -51,14 +58,14 @@ struct MOZ_CAPABILITY("mutex") Mutex {
pthread_mutex_t mMutex = PTHREAD_MUTEX_INITIALIZER;
#endif
-#ifndef XP_WIN
+ // Although a constexpr constructor is provided, it will not initialise the
+ // mutex and calling Init() is required.
constexpr Mutex() {}
-#endif
- // Initializes a mutex. Returns whether initialization succeeded.
+ // (Re-)initializes a mutex. Returns whether initialization succeeded.
inline bool Init() {
#if defined(XP_WIN)
- if (!InitializeCriticalSectionAndSpinCount(&mMutex, 5000)) {
+ if (!InitializeCriticalSectionAndSpinCount(mMutex.addr(), 5000)) {
return false;
}
#elif defined(XP_DARWIN)
@@ -84,7 +91,7 @@ struct MOZ_CAPABILITY("mutex") Mutex {
inline void Lock() MOZ_CAPABILITY_ACQUIRE() {
#if defined(XP_WIN)
- EnterCriticalSection(&mMutex);
+ EnterCriticalSection(mMutex.addr());
#elif defined(XP_DARWIN)
// We rely on a non-public function to improve performance here.
// The OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION flag informs the kernel that
@@ -105,7 +112,7 @@ struct MOZ_CAPABILITY("mutex") Mutex {
inline void Unlock() MOZ_CAPABILITY_RELEASE() {
#if defined(XP_WIN)
- LeaveCriticalSection(&mMutex);
+ LeaveCriticalSection(mMutex.addr());
#elif defined(XP_DARWIN)
os_unfair_lock_unlock(&mMutex);
#else