This code is used to detect too-early accesses of prefs in content processes.
The patch makes the following changes.
- New terminology: "early" prefs are those sent via the command line; "late"
prefs are those sent via IPC. Previously the former were "init" prefs and the
latter didn't have a clear name.
- The phase tracking and checking is now almost completely encapsulated within
Preferences.cpp. The only exposure to outside code is via the
AreAllPrefsSetInContentProcess() method, which has a single use.
- The number of states tracked drops from 5 to 3. There's no need to track the
beginning of the pref-setting operations, because we only need to know if
they've finished. (This also avoids the weirdness where we could transition
from END_INIT_PREFS back to BEGIN_INIT_PREFS because of the way -intPrefs,
-boolPrefs and -stringPrefs were parsed separately.)
MozReview-Commit-ID: IVJWiDxdsDV
--HG--
extra : rebase_source : 8cee1dcbd40847bf052ca9e2b759dd550350e5a1
Preferences::SetPreference() is used when setting prefs in the content process
from dom::Pref values that are passed from the parent process. Currently we
use the high-level Set*InAnyProcess() methods to do this -- basically the same
code path as sets done via the API -- but this has several problems.
- It is subtly broken. If the content process already has a pref of type T with
a default value and then we get a SetPreference() call that tries to change
it to type U, it will erroneously fail. In practice this never(?) happens,
but it shows that things aren't arranged very well.
- SetPreference() also looks up the hashtable twice to get the same pref if
both a default value and a user value are present in the dom::Pref.
- This happens in content processes, while all other pref set operations occur
in the parent process. This is the main reason we have the Set*InAnyProcess()
functions.
In short, the setting of prefs via IPC is quite different to the setting of
prefs via other means -- because it happens in content processes, and it's more
of a clobber that can set both values at once -- and so should be handled
differently.
The solution is to make Preferences::SetPreference() use lower-level operations
to do the update. It now does the hash table lookup/add itself, and then calls
the new Pref::FromDomPref() method. That method then possibly calls the new
PrefValue::FromDomPrefValue() method for both kinds of value, and overwrites
them as necessary. SetValueFromDom() is no longer used and the patch removes it.
MozReview-Commit-ID: 2Rg8VMOc0Cl
--HG--
extra : rebase_source : 0eddc3a4b694a79af3e173aefa7758f8e2ae776b
It represents a pref, so `Pref` is a better name. Within Preferences.cpp the
patch uses domPref/aDomPref to distinguish it from PrefHashEntry values.
MozReview-Commit-ID: HXTl0GX4BtO
--HG--
extra : rebase_source : c1e0726c55e7577720f669f0ed2dbc38627d853e
This requires adding an aPriority argument (defaulting to false) to
Preferences::RegisterCallback(). And RegisterVarCacheCallback() is no longer
necessary.
MozReview-Commit-ID: BMDk3HuaQVV
--HG--
extra : rebase_source : 17a61cfd9a82f24854162fc993223691041ea46d
This splits the measurements into several buckets, like so:
> 718,528 B (00.40%) -- preferences
> ├──262,176 B (00.14%) ── hash-table
> ├──181,952 B (00.10%) ── callbacks
> ├──122,880 B (00.07%) ── pref-name-arena
> ├───91,872 B (00.05%) ── root-branches
> ├───38,296 B (00.02%) ── string-values
> ├───21,272 B (00.01%) ── cache-data
> └───────80 B (00.00%) ── misc
The patch also measures some things that were previously overlooked.
- String pref values. (The old code had a comment that incorrectly claimed they
were allocated out of an arena.)
- The PrefCallback objects pointed to by entries in nsPrefBranch::mObservers.
And it makes the code more like typical reporters.
- It removes the "AndOtherStuff" from Preferences' measuring method, and
measuring those global structures in
PreferenceServiceReporter::CollectReports().
- It adds `const` where appropriate.
MozReview-Commit-ID: dyNg7ldQdh
This patch also adds some Set*InAnyProcess() methods, and makes nsPrefBranch a
friend of Preferences so it can call those methods.
And it moves the thin Set*() wrapper functions to Preferences.h, alongside
SetUint().
MozReview-Commit-ID: 88HhmcTFZNc
--HG--
extra : rebase_source : 88a854d52afce86d93008a6e1a4b5f32bcf24a1a
This will allow other functions to be moved into Preferences and be marked as
`private` in subsequent patches.
The patch also renames SetPrefValue() as SetValueFromDom(), because that's a
clearer name.
MozReview-Commit-ID: CB1xmPSmac6
--HG--
extra : rebase_source : 0d597a800f2295c04af26d5abaac4aea0e0d3373
It's a `final` class, so there's no need for `protected`.
MozReview-Commit-ID: 7n4DLpXo0el
--HG--
extra : rebase_source : b2d3eb9cf0e912689efa29d2255cc018fd8a7c64
This is unused for now, but will be necessary for nsPrefBranch::Set*() to call
into Preferences::Set*().
The patch also renames some arguments from aPref to aPrefName, because that's a
better name.
MozReview-Commit-ID: 2OPB7CHOgpw
--HG--
extra : rebase_source : 232b7be3c33d185f13ce86d91feea3b55069a4e6
This is nicer than a bool for tracking the Default vs. User distinction, and it
replaces the Preferences.cpp-only WhichValue type.
MozReview-Commit-ID: 8CrdDN2vBJQ
--HG--
extra : rebase_source : 0d49148c73e5aeb0a355a6d4189232c89295d2a7
The various getters and setters are in a confusing order. This patch puts them
in a more sensible order. It also streamlines the comments, which were
generally low-value and in some cases incorrect.
MozReview-Commit-ID: 3ngzZDSt0JI
--HG--
extra : rebase_source : 8a5a66f65621889483d2df9f4487194172f70804
The notable part of this change is Shutdown(). I've made it just null out
sPreferences, contrary to the old comment, which was strange for a couple of
reasons:
- ~Preferences() used to null out sPreference, which is backwards compared to
how this sort of thing normally works.
- In both the before and after cases, as far as I can tell,
Preferences::Shutdown() is called but ~Preferences() is never called;
something keeps the singleton Preferences instance alive until process
termination.
MozReview-Commit-ID: Ab0ui31rVcI
sRootBranch and sDefaultRootBranch have the same lifetime as sPreferences, so
this patch makes them non-static nsCOMPtr<> members of Preferences.
MozReview-Commit-ID: 1TLhh13ZpBI
--HG--
extra : rebase_source : 9419cd205b9a06f7ae82722a6732e3fc2722473b
It's unnecessarily general, because we only ever use
Preferences::DirtyCallback() as the callback.
And because it's no longer a callback, the patch renames DirtyCallback() as
HandleDirty().
MozReview-Commit-ID: Hl50dcxfVQq
--HG--
extra : rebase_source : 5807d2ed650466f85cd7325f2adccdc177ccb4d2
Right now, NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR expects singleton
constructors to return already-addrefed raw pointers, and while it accepts
constructors that return already_AddRefed, most existing don't do so.
Meanwhile, the convention elsewhere is that a raw pointer return value is
owned by the callee, and that the caller needs to addref it if it wants to
keep its own reference to it.
The difference in convention makes it easy to leak (I've definitely caused
more than one shutdown leak this way), so it would be better if we required
the singleton getters to return an explicit already_AddRefed, which would
behave the same for all callers.
This also cleans up several singleton constructors that left a dangling
pointer to their singletons when their initialization methods failed, when
they released their references without clearing their global raw pointers.
MozReview-Commit-ID: 9peyG4pRYcr
--HG--
extra : rebase_source : 2f5bd89c17cb554541be38444672a827c1392f3f
It's unnecessarily general, because we only ever use
Preferences::DirtyCallback() as the callback.
And because it's no longer a callback, the patch renames DirtyCallback() as
HandleDirty().
MozReview-Commit-ID: Hl50dcxfVQq
--HG--
extra : rebase_source : f453d31215de3fdb0c5b6176becf2669e7ad55f1
This is detritus from old changes that can be cleaned up now.
The patch removes the declaration of PrefChangedFunc from Preferences.cpp
because it's also in Preferences.h, which is included by Preferences.cpp.
The patch also removes the part of the comment about passing a non-zero result
because it's clearly false -- the callback has no return value.
MozReview-Commit-ID: 72cdauYsRUt
--HG--
extra : rebase_source : 84cbbcea3b0ce3242c629e428be1e81be9cb5792
This is a mixture of clang-format and manual restyling.
MozReview-Commit-ID: 6S6yUDXQJtE
--HG--
extra : rebase_source : f7f52bd4c2fe9de1d5b6d99bf2daf841e511d913
This uses std::atomic rather than mozilla::Atomic since mozilla::Atomic
does not support using different memory synchronization for different
atomic operations on the same variable.
The added comments could use careful review since, while they reflect my
understanding of the issue, I don't consider myself an expert on the
topic.
MozReview-Commit-ID: 7xByCXt17Dr
--HG--
extra : transplant_source : %8DM%88%E8%B7%B4%D8a%D6%F5%3F%9B%DC%09X%F3%7C%98%DE%21
This uses std::atomic rather than mozilla::Atomic since mozilla::Atomic
does not support using different memory synchronization for different
atomic operations on the same variable.
The added comments could use careful review since, while they reflect my
understanding of the issue, I don't consider myself an expert on the
topic.
MozReview-Commit-ID: 7xByCXt17Dr
--HG--
extra : transplant_source : 8%8Ci%CC%EA%0F%CF%C7%3E%F1%93%F5%C9%ED9%84%F9%3Evx
This will allow us to remove the PrefixMatch option from the public API version
of RegisterCallback/RegisterCallbackAndCall.
MozReview-Commit-ID: 6D0S35nv88Z