tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mmemory/build/BaseAlloc.cpp | 2+-
Mmemory/build/Mutex.cpp | 2+-
Mmemory/build/Mutex.h | 27+++++++++++++++++----------
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