mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
Bug 1570575 - Some libpref tidy-ups. r=KrisWright
This commit: - improves the wording of some comments; - renames `UpdatePolicy` as `MirrorKind`, to reflect the new terminology we are starting to use; - does a couple of other minor clean-ups. Differential Revision: https://phabricator.services.mozilla.com/D40161 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
905c456380
commit
605fd328b4
@ -1201,8 +1201,8 @@ using PrefsHashTable = HashSet<UniquePtr<Pref>, PrefHasher>;
|
||||
static PrefsHashTable* gHashTable;
|
||||
|
||||
#ifdef DEBUG
|
||||
// This defines the datatype used to store our `Once` StaticPrefs checker.
|
||||
// We can't use HashMap for now due to alignment restrictions when dealing with
|
||||
// This defines the type used to store our `once` mirrors checker. We can't use
|
||||
// HashMap for now due to alignment restrictions when dealing with
|
||||
// std::function<void()> (see bug 1557617).
|
||||
typedef std::function<void()> AntiFootgunCallback;
|
||||
struct CompareStr {
|
||||
@ -1707,9 +1707,9 @@ static void NotifyCallbacks(const char* aPrefName, const PrefWrapper* aPref) {
|
||||
if (XRE_IsParentProcess() &&
|
||||
!StaticPrefs::preferences_force_disable_check_once_policy() &&
|
||||
(StaticPrefs::preferences_check_once_policy() || xpc::IsInAutomation())) {
|
||||
// Check that we aren't modifying a `Once` pref using that prefName.
|
||||
// We have about 100 `Once` StaticPrefs defined. std::map performs a search
|
||||
// in O(log n), so this is fast enough for our case.
|
||||
// Check that we aren't modifying a `once`-mirrored pref using that pref
|
||||
// name. We have about 100 `once`-mirrored prefs. std::map performs a
|
||||
// search in O(log n), so this is fast enough.
|
||||
MOZ_ASSERT(gOnceStaticPrefsAntiFootgun);
|
||||
auto search = gOnceStaticPrefsAntiFootgun->find(aPrefName);
|
||||
if (search != gOnceStaticPrefsAntiFootgun->end()) {
|
||||
@ -3724,8 +3724,8 @@ FileDescriptor Preferences::EnsureSnapshot(size_t* aSize) {
|
||||
iter.get()->AddToMap(builder);
|
||||
}
|
||||
|
||||
// Store the current value of Once StaticPrefs. Following this those
|
||||
// StaticPrefs will become immutable.
|
||||
// Store the current value of `once`-mirrored prefs. After this point they
|
||||
// will be immutable.
|
||||
StaticPrefs::RegisterOncePrefs(builder);
|
||||
|
||||
gSharedMap = new SharedPrefMap(std::move(builder));
|
||||
@ -5371,34 +5371,24 @@ static void InitPref(const char* aName, float aDefaultValue) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void InitVarCachePref(StaticPrefs::UpdatePolicy aPolicy,
|
||||
static void InitMirroredPref(StaticPrefs::MirrorKind aPolicy,
|
||||
const nsACString& aName, T* aCache,
|
||||
StripAtomic<T> aDefaultValue, bool aIsStartup,
|
||||
bool aIsParent) {
|
||||
// aIsStartup will be true when we first initialize the StaticPrefs and false
|
||||
// when we want to reset the Preferences/StaticPrefs to their default value.
|
||||
|
||||
// InitVarCachePref is called under the following scenarios:
|
||||
// aIsParent | aIsStartup | Action
|
||||
// true | true | Set underlying preference and StaticPrefs to
|
||||
// | | their default value, set callback for Live pref.
|
||||
// true | false | reset underlying preference and StaticPref to
|
||||
// | | default value.
|
||||
// false | true | set callback for Live pref.
|
||||
// false | false | none.
|
||||
//
|
||||
// We only set *aCache if the policy is Live as:
|
||||
// 1- On startup, `Once` prefs will be initialized lazily in InitOncePrefs(),
|
||||
// 2- After that, `Once` prefs are immutable.
|
||||
|
||||
// In the parent process, set/reset the pref value and the `always` mirror (if
|
||||
// there is one) to the default value.
|
||||
// - `once` mirrors will be initialized lazily in InitOncePrefs().
|
||||
// - In child processes, the parent sends the correct initial values via
|
||||
// shared memory, so we do not re-initialize them here.
|
||||
if (aIsParent) {
|
||||
InitPref(PromiseFlatCString(aName).get(), aDefaultValue);
|
||||
if (MOZ_LIKELY(aPolicy == StaticPrefs::UpdatePolicy::Live)) {
|
||||
if (MOZ_LIKELY(aPolicy == StaticPrefs::MirrorKind::Always)) {
|
||||
*aCache = aDefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
if (MOZ_LIKELY(aPolicy == StaticPrefs::UpdatePolicy::Live) &&
|
||||
// At startup, setup the callback for the `always` mirror (if there is one).
|
||||
if (MOZ_LIKELY(aPolicy == StaticPrefs::MirrorKind::Always) &&
|
||||
MOZ_LIKELY(aIsStartup)) {
|
||||
AddVarCacheNoAssignment(aCache, aName, aDefaultValue);
|
||||
}
|
||||
@ -5411,7 +5401,8 @@ namespace StaticPrefs {
|
||||
|
||||
void MaybeInitOncePrefs() {
|
||||
if (MOZ_LIKELY(sOncePrefRead)) {
|
||||
// `Once` StaticPrefs have already been initialized to their default value.
|
||||
// `once`-mirrored prefs have already been initialized to their default
|
||||
// value.
|
||||
return;
|
||||
}
|
||||
StaticMutexAutoLock lock(sOncePrefMutex);
|
||||
@ -5429,14 +5420,14 @@ void MaybeInitOncePrefs() {
|
||||
|
||||
// For a pref like this:
|
||||
//
|
||||
// VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
// VARCACHE_PREF($MIRROR, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
//
|
||||
// we generate a variable definition like this:
|
||||
//
|
||||
// int32_t sVarCache_my_pref(99);
|
||||
//
|
||||
#define PREF(name, cpp_type, value)
|
||||
#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, default_value) \
|
||||
#define VARCACHE_PREF(mirror, name, base_id, full_id, cpp_type, default_value) \
|
||||
cpp_type sVarCache_##full_id(default_value);
|
||||
#include "mozilla/StaticPrefListAll.h"
|
||||
#undef PREF
|
||||
@ -5450,19 +5441,19 @@ static void InitAll(bool aIsStartup) {
|
||||
// For prefs like these:
|
||||
//
|
||||
// PREF("foo.bar.baz", bool, true)
|
||||
// VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
// VARCACHE_PREF($MIRROR, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
//
|
||||
// we generate registration calls like this:
|
||||
//
|
||||
// if (isParent) {
|
||||
// InitPref_bool("foo.bar.baz", true);
|
||||
// }
|
||||
// InitVarCachePref(UpdatePolicy::Live, "my.pref", &sVarCache_my_pref,
|
||||
// 99, aIsStartup, isParent);
|
||||
// InitMirroredPref($MIRROR, "my.pref", &sVarCache_my_pref, 99, aIsStartup,
|
||||
// isParent);
|
||||
//
|
||||
// The InitPref_*() functions have a type suffix to avoid ambiguity between
|
||||
// prefs having int32_t and float default values. That suffix is not needed
|
||||
// for the InitVarCachePref() functions because they take a pointer parameter,
|
||||
// for the InitMirroredPref() functions because they take a pointer parameter,
|
||||
// which prevents automatic int-to-float coercion.
|
||||
//
|
||||
// In content processes, we rely on the parent to send us the correct initial
|
||||
@ -5471,8 +5462,8 @@ static void InitAll(bool aIsStartup) {
|
||||
if (isParent) { \
|
||||
InitPref_##cpp_type(name, value); \
|
||||
}
|
||||
#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
|
||||
InitVarCachePref(UpdatePolicy::policy, NS_LITERAL_CSTRING(name), \
|
||||
#define VARCACHE_PREF(mirror, name, base_id, full_id, cpp_type, value) \
|
||||
InitMirroredPref(MirrorKind::mirror, NS_LITERAL_CSTRING(name), \
|
||||
&sVarCache_##full_id, value, aIsStartup, isParent);
|
||||
#include "mozilla/StaticPrefListAll.h"
|
||||
#undef PREF
|
||||
@ -5482,26 +5473,27 @@ static void InitAll(bool aIsStartup) {
|
||||
static void InitOncePrefs() {
|
||||
// For a pref like this:
|
||||
//
|
||||
// VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
// VARCACHE_PREF($MIRROR, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
//
|
||||
// we generate an initialization (in a non-DEBUG build) like this:
|
||||
// we generate a non-DEBUG initialization like this:
|
||||
//
|
||||
// if (UpdatePolicy::$POLICY == UpdatePolicy::Once) {
|
||||
// if (MirrorKind::$MIRROR == MirrorKind::Once) {
|
||||
// sVarCache_my_pref = Internals::GetPref("my.pref", 99);
|
||||
// }
|
||||
//
|
||||
// This is done to get the potentially updated Preference value as we didn't
|
||||
// register a callback method for the `Once` policy.
|
||||
// This is done in case the pref value was updated when reading pref data
|
||||
// files. It's necessary because we don't have callbacks registered for
|
||||
// `once`-mirrored prefs.
|
||||
//
|
||||
// On debug build, we also install a mechanism that allows to check if the
|
||||
// original Preference is being modified once `Once` StaticPrefs have been
|
||||
// initialized as this would indicate a likely misuse of `Once` StaticPrefs
|
||||
// and that maybe instead they should have been made `Live`.
|
||||
// In debug builds, we also install a mechanism that can check if the
|
||||
// preference value is modified after `once`-mirrored prefs are initialized.
|
||||
// In tests this would indicate a likely misuse of a `once`-mirrored pref and
|
||||
// suggest that it should instead be `always`-mirrored.
|
||||
//
|
||||
#define PREF(name, cpp_type, value)
|
||||
#ifdef DEBUG
|
||||
# define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
|
||||
if (UpdatePolicy::policy == UpdatePolicy::Once) { \
|
||||
# define VARCACHE_PREF(mirror, name, base_id, full_id, cpp_type, value) \
|
||||
if (MirrorKind::mirror == MirrorKind::Once) { \
|
||||
MOZ_ASSERT(gOnceStaticPrefsAntiFootgun); \
|
||||
sVarCache_##full_id = \
|
||||
Internals::GetPref(name, StripAtomic<cpp_type>(value)); \
|
||||
@ -5521,8 +5513,8 @@ static void InitOncePrefs() {
|
||||
std::move(checkPref))); \
|
||||
}
|
||||
#else
|
||||
# define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
|
||||
if (UpdatePolicy::policy == UpdatePolicy::Once) { \
|
||||
# define VARCACHE_PREF(mirror, name, base_id, full_id, cpp_type, value) \
|
||||
if (MirrorKind::mirror == MirrorKind::Once) { \
|
||||
sVarCache_##full_id = \
|
||||
Internals::GetPref(name, StripAtomic<cpp_type>(value)); \
|
||||
}
|
||||
@ -5596,24 +5588,25 @@ static void RegisterOncePrefs(SharedPrefMapBuilder& aBuilder) {
|
||||
|
||||
// For a pref like this:
|
||||
//
|
||||
// VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
// VARCACHE_PREF($MIRROR, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
//
|
||||
// we generate a save call like this:
|
||||
//
|
||||
// if (UpdatePolicy::$POLICY == UpdatePolicy::Once) {
|
||||
// if (MirrorKind::$MIRROR == MirrorKind::Once) {
|
||||
// SaveOncePrefToSharedMap(aBuilder, ONCE_PREF_NAME(my.pref),
|
||||
// sVarCache_my_pref);
|
||||
// }
|
||||
//
|
||||
// `Once` StaticPrefs values will be stored in a hidden and locked preferences
|
||||
// in the global SharedPreferenceMap. In order for those preferences to be
|
||||
// hidden and not appear in about:config nor ever be stored to disk, we add
|
||||
// the "$$$" prefix and suffix to the preference name and set the IsVisible
|
||||
// flag to false.
|
||||
// This saves the `once`-mirrored value as it was at parent startup. It is
|
||||
// stored in a special (hidden and locked) entry in the global
|
||||
// SharedPreferenceMap. In order for the entry to be hidden and not appear in
|
||||
// about:config nor ever be stored to disk, we set its IsSkippedByIteration
|
||||
// flag to true. We also distinguish it by adding a "$$$" prefix and suffix
|
||||
// to the preference name.
|
||||
//
|
||||
#define PREF(name, cpp_type, value)
|
||||
#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
|
||||
if (UpdatePolicy::policy == UpdatePolicy::Once) { \
|
||||
#define VARCACHE_PREF(mirror, name, base_id, full_id, cpp_type, value) \
|
||||
if (MirrorKind::mirror == MirrorKind::Once) { \
|
||||
SaveOncePrefToSharedMap(aBuilder, ONCE_PREF_NAME(name), \
|
||||
StripAtomic<cpp_type>(sVarCache_##full_id)); \
|
||||
}
|
||||
@ -5629,43 +5622,37 @@ static void InitStaticPrefsFromShared() {
|
||||
|
||||
// For a prefs like this:
|
||||
//
|
||||
// VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
// VARCACHE_PREF($MIRROR, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
//
|
||||
// we generate an initialization like this:
|
||||
//
|
||||
// {
|
||||
// int32_t val;
|
||||
// nsresult rv;
|
||||
// if (UpdatePolicy::$POLICY == UpdatePolicy::Once) {
|
||||
// rv = Internals::GetSharedPrefValue(
|
||||
// "$$$my.pref$$$", &val);
|
||||
// } else if (UpdatePolicy::Once == UpdatePolicy::Live) {
|
||||
// rv = Internals::GetSharedPrefValue("my.pref", &val);
|
||||
// }
|
||||
// nsresult rv = (MirrorKind::$MIRROR == MirrorKind::Once)
|
||||
// ? Internals::GetSharedPrefValue("$$$my.pref$$$", &val)
|
||||
// : Internals::GetSharedPrefValue("my.pref", &val);
|
||||
// MOZ_DIAGNOSTIC_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
// sVarCache_my_pref = val;
|
||||
// }
|
||||
//
|
||||
#define PREF(name, cpp_type, value)
|
||||
#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
|
||||
{ \
|
||||
StripAtomic<cpp_type> val; \
|
||||
nsresult rv; \
|
||||
if (UpdatePolicy::policy == UpdatePolicy::Once) { \
|
||||
rv = Internals::GetSharedPrefValue(ONCE_PREF_NAME(name), &val); \
|
||||
} else { \
|
||||
rv = Internals::GetSharedPrefValue(name, &val); \
|
||||
} \
|
||||
MOZ_DIAGNOSTIC_ALWAYS_TRUE(NS_SUCCEEDED(rv)); \
|
||||
StaticPrefs::sVarCache_##full_id = val; \
|
||||
#define VARCACHE_PREF(mirror, name, base_id, full_id, cpp_type, value) \
|
||||
{ \
|
||||
StripAtomic<cpp_type> val; \
|
||||
nsresult rv = \
|
||||
(MirrorKind::mirror == MirrorKind::Once) \
|
||||
? Internals::GetSharedPrefValue(ONCE_PREF_NAME(name), &val) \
|
||||
: Internals::GetSharedPrefValue(name, &val); \
|
||||
MOZ_DIAGNOSTIC_ALWAYS_TRUE(NS_SUCCEEDED(rv)); \
|
||||
StaticPrefs::sVarCache_##full_id = val; \
|
||||
}
|
||||
#include "mozilla/StaticPrefListAll.h"
|
||||
#undef PREF
|
||||
#undef VARCACHE_PREF
|
||||
|
||||
// `Once` StaticPrefs have been set to their value in the step above and
|
||||
// outside the parent process they are immutable. So we set sOncePrefRead
|
||||
// so that we can directly skip any lazy initializations.
|
||||
// `once`-mirrored prefs have been set to their value in the step above and
|
||||
// outside the parent process they are immutable. We set sOncePrefRead so
|
||||
// that we can directly skip any lazy initializations.
|
||||
sOncePrefRead = true;
|
||||
}
|
||||
|
||||
|
@ -64,10 +64,17 @@ struct IsAtomic<std::atomic<T>> : TrueType {};
|
||||
|
||||
namespace StaticPrefs {
|
||||
|
||||
// Undo X11/X.h's definition of `Always` so we can use it in `MirrorKind`.
|
||||
#undef Always
|
||||
|
||||
// Enums for the update policy.
|
||||
enum class UpdatePolicy {
|
||||
Once, // Evaluate the preference once, unchanged during the session.
|
||||
Live // Evaluate the preference and set callback so it stays current/live.
|
||||
enum class MirrorKind {
|
||||
// Mirror the pref value once, at startup.
|
||||
Once,
|
||||
|
||||
// Mirror the pref vale always, with live updating. This would be `Always`,
|
||||
// but /usr/include/X11/X.h defines a macro with that name.
|
||||
Always
|
||||
};
|
||||
|
||||
void MaybeInitOncePrefs();
|
||||
|
@ -16,14 +16,14 @@ namespace StaticPrefs {
|
||||
|
||||
// For a VarCache pref like this:
|
||||
//
|
||||
// VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
// VARCACHE_PREF($MIRROR, "my.pref", my_pref, my_pref, int32_t, 99)
|
||||
//
|
||||
// we generate an extern variable declaration and three getter
|
||||
// declarations/definitions.
|
||||
//
|
||||
// extern int32_t sVarCache_my_pref;
|
||||
// inline int32_t my_pref() {
|
||||
// if (UpdatePolicy::$POLICY != UpdatePolicy::Once) {
|
||||
// if (MirrorKind::$MIRROR != MirrorKind::Once) {
|
||||
// return sVarCache_my_pref;
|
||||
// }
|
||||
// MaybeInitOncePrefs();
|
||||
@ -39,7 +39,7 @@ namespace StaticPrefs {
|
||||
#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, default_value) \
|
||||
extern cpp_type sVarCache_##full_id; \
|
||||
inline StripAtomic<cpp_type> full_id() { \
|
||||
if (UpdatePolicy::policy != UpdatePolicy::Once) { \
|
||||
if (MirrorKind::policy != MirrorKind::Once) { \
|
||||
MOZ_DIAGNOSTIC_ASSERT( \
|
||||
IsAtomic<cpp_type>::value || NS_IsMainThread(), \
|
||||
"Non-atomic static pref '" name \
|
||||
|
@ -65,7 +65,7 @@ VARCACHE_PREF(
|
||||
|
||||
'always': '''\
|
||||
VARCACHE_PREF(
|
||||
Live,
|
||||
Always,
|
||||
"{name}",
|
||||
{base_id},
|
||||
{full_id},
|
||||
|
@ -100,7 +100,7 @@ VARCACHE_PREF(
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
Live,
|
||||
Always,
|
||||
"my.uint",
|
||||
my_uint,
|
||||
my_uint,
|
||||
@ -120,7 +120,7 @@ PREF("my.string", String, "foo\\"bar")
|
||||
PREF("my.string2", String, "foobar")
|
||||
|
||||
VARCACHE_PREF(
|
||||
Live,
|
||||
Always,
|
||||
"my.atomic.bool",
|
||||
my_atomic_bool,
|
||||
my_atomic_bool,
|
||||
@ -128,7 +128,7 @@ VARCACHE_PREF(
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
Live,
|
||||
Always,
|
||||
"my.atomic.int",
|
||||
my_atomic_int,
|
||||
my_atomic_int_DoNotUseDirectly,
|
||||
|
Loading…
Reference in New Issue
Block a user