commit 6670c30e05cd77aa6aa716957793f0e5dcbaeab4
parent 5278a541b3b5cbf16190208389f2fb904d4914b3
Author: Markus Stange <mstange.moz@gmail.com>
Date: Thu, 23 Oct 2025 20:44:35 +0000
Bug 1996126 - Make nsCocoaFeatures::macOSVersion() handle concurrent calls. r=jrmuizel
Differential Revision: https://phabricator.services.mozilla.com/D269881
Diffstat:
2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/widget/cocoa/nsCocoaFeatures.h b/widget/cocoa/nsCocoaFeatures.h
@@ -42,9 +42,7 @@ class nsCocoaFeatures {
private:
nsCocoaFeatures() = delete; // Prevent instantiation.
- static void InitializeVersionNumbers();
-
- static int32_t mOSVersion;
+ static int32_t ComputeVersion();
};
#endif // nsCocoaFeatures_h_
diff --git a/widget/cocoa/nsCocoaFeatures.mm b/widget/cocoa/nsCocoaFeatures.mm
@@ -34,10 +34,12 @@
#include "nsDebug.h"
#include "nsObjCExceptions.h"
+#include <atomic>
#import <Cocoa/Cocoa.h>
#include <sys/sysctl.h>
-/*static*/ int32_t nsCocoaFeatures::mOSVersion = 0;
+// The lazily-initialized version. 0 before initialization, non-zero after.
+static std::atomic<int32_t> sOSVersion = 0;
// This should not be called with unchecked aMajor, which should be >= 10.
inline int32_t AssembleVersion(int32_t aMajor, int32_t aMinor,
@@ -117,8 +119,8 @@ int32_t nsCocoaFeatures::GetVersion(int32_t aMajor, int32_t aMinor,
return macOSVersion;
}
-/*static*/ void nsCocoaFeatures::InitializeVersionNumbers() {
- NS_OBJC_BEGIN_TRY_IGNORE_BLOCK;
+/*static*/ int32_t nsCocoaFeatures::ComputeVersion() {
+ NS_OBJC_BEGIN_TRY_BLOCK_RETURN;
// Provide an autorelease pool to avoid leaking Cocoa objects,
// as this gets called before the main autorelease pool is in place.
@@ -126,19 +128,25 @@ int32_t nsCocoaFeatures::GetVersion(int32_t aMajor, int32_t aMinor,
int major, minor, bugfix;
GetSystemVersion(major, minor, bugfix);
- mOSVersion = GetVersion(major, minor, bugfix);
+ return GetVersion(major, minor, bugfix);
- NS_OBJC_END_TRY_IGNORE_BLOCK;
+ NS_OBJC_END_TRY_BLOCK_RETURN(0);
}
/* static */ int32_t nsCocoaFeatures::macOSVersion() {
- // Don't let this be called while we're first setting the value...
- MOZ_ASSERT((mOSVersion & MACOS_VERSION_MASK) >= 0);
- if (!mOSVersion) {
- mOSVersion = -1;
- InitializeVersionNumbers();
+ int32_t version = sOSVersion.load(std::memory_order_relaxed);
+ if (version != 0) {
+ return version;
}
- return mOSVersion;
+
+ // Compute the version. Multiple threads might do the computation
+ // concurrently. That's ok; they will all compute the same value.
+ version = ComputeVersion();
+ if (version != 0) {
+ sOSVersion.store(version, std::memory_order_relaxed);
+ }
+
+ return version;
}
/* static */ int32_t nsCocoaFeatures::macOSVersionMajor() {