From 6451cce1218208d7d7a9bb08896e8abf90e2c672 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Wed, 4 May 2016 12:26:04 +1200 Subject: [PATCH] Bug 1267868 - Make AddXXXVarCache only match exact prefs, not prefixes. r=froydnj --- modules/libpref/Preferences.cpp | 48 ++++++++++++++++++++------------- modules/libpref/Preferences.h | 16 ++++++++--- 2 files changed, 43 insertions(+), 21 deletions(-) diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 42526ecda685..3b82f798759f 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -103,19 +103,24 @@ public: static PLDHashNumber HashKey(const ValueObserverHashKey *aKey) { PLDHashNumber hash = HashString(aKey->mPrefName); + hash = AddToHash(hash, aKey->mMatchKind); return AddToHash(hash, aKey->mCallback); } - ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback) : - mPrefName(aPref), mCallback(aCallback) { } + ValueObserverHashKey(const char *aPref, PrefChangedFunc aCallback, Preferences::MatchKind aMatchKind) : + mPrefName(aPref), mCallback(aCallback), mMatchKind(aMatchKind) { } explicit ValueObserverHashKey(const ValueObserverHashKey *aOther) : - mPrefName(aOther->mPrefName), mCallback(aOther->mCallback) + mPrefName(aOther->mPrefName), + mCallback(aOther->mCallback), + mMatchKind(aOther->mMatchKind) { } bool KeyEquals(const ValueObserverHashKey *aOther) const { - return mCallback == aOther->mCallback && mPrefName == aOther->mPrefName; + return mCallback == aOther->mCallback && + mPrefName == aOther->mPrefName && + mMatchKind == aOther->mMatchKind; } ValueObserverHashKey *GetKey() const @@ -127,6 +132,7 @@ public: nsCString mPrefName; PrefChangedFunc mCallback; + Preferences::MatchKind mMatchKind; }; class ValueObserver final : public nsIObserver, @@ -140,8 +146,8 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER - ValueObserver(const char *aPref, PrefChangedFunc aCallback) - : ValueObserverHashKey(aPref, aCallback) { } + ValueObserver(const char *aPref, PrefChangedFunc aCallback, Preferences::MatchKind aMatchKind) + : ValueObserverHashKey(aPref, aCallback, aMatchKind) { } void AppendClosure(void *aClosure) { mClosures.AppendElement(aClosure); @@ -168,6 +174,9 @@ ValueObserver::Observe(nsISupports *aSubject, NS_ASSERTION(!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID), "invalid topic"); NS_ConvertUTF16toUTF8 data(aData); + if (mMatchKind == Preferences::ExactMatch && !mPrefName.EqualsASCII(data.get())) { + return NS_OK; + } for (uint32_t i = 0; i < mClosures.Length(); i++) { mCallback(data.get(), mClosures.ElementAt(i)); } @@ -1662,11 +1671,12 @@ Preferences::RemoveObservers(nsIObserver* aObserver, nsresult Preferences::RegisterCallback(PrefChangedFunc aCallback, const char* aPref, - void* aClosure) + void* aClosure, + MatchKind aMatchKind) { NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - ValueObserverHashKey hashKey(aPref, aCallback); + ValueObserverHashKey hashKey(aPref, aCallback, aMatchKind); RefPtr observer; gObserverTable->Get(&hashKey, getter_AddRefs(observer)); if (observer) { @@ -1674,7 +1684,7 @@ Preferences::RegisterCallback(PrefChangedFunc aCallback, return NS_OK; } - observer = new ValueObserver(aPref, aCallback); + observer = new ValueObserver(aPref, aCallback, aMatchKind); observer->AppendClosure(aClosure); nsresult rv = AddStrongObserver(observer, aPref); NS_ENSURE_SUCCESS(rv, rv); @@ -1686,9 +1696,10 @@ Preferences::RegisterCallback(PrefChangedFunc aCallback, nsresult Preferences::RegisterCallbackAndCall(PrefChangedFunc aCallback, const char* aPref, - void* aClosure) + void* aClosure, + MatchKind aMatchKind) { - nsresult rv = RegisterCallback(aCallback, aPref, aClosure); + nsresult rv = RegisterCallback(aCallback, aPref, aClosure, aMatchKind); if (NS_SUCCEEDED(rv)) { (*aCallback)(aPref, aClosure); } @@ -1699,14 +1710,15 @@ Preferences::RegisterCallbackAndCall(PrefChangedFunc aCallback, nsresult Preferences::UnregisterCallback(PrefChangedFunc aCallback, const char* aPref, - void* aClosure) + void* aClosure, + MatchKind aMatchKind) { if (!sPreferences && sShutdown) { return NS_OK; // Observers have been released automatically. } NS_ENSURE_TRUE(sPreferences, NS_ERROR_NOT_AVAILABLE); - ValueObserverHashKey hashKey(aPref, aCallback); + ValueObserverHashKey hashKey(aPref, aCallback, aMatchKind); RefPtr observer; gObserverTable->Get(&hashKey, getter_AddRefs(observer)); if (!observer) { @@ -1743,7 +1755,7 @@ Preferences::AddBoolVarCache(bool* aCache, data->cacheLocation = aCache; data->defaultValueBool = aDefault; gCacheData->AppendElement(data); - return RegisterCallback(BoolVarChanged, aPref, data); + return RegisterCallback(BoolVarChanged, aPref, data, ExactMatch); } static void IntVarChanged(const char* aPref, void* aClosure) @@ -1768,7 +1780,7 @@ Preferences::AddIntVarCache(int32_t* aCache, data->cacheLocation = aCache; data->defaultValueInt = aDefault; gCacheData->AppendElement(data); - return RegisterCallback(IntVarChanged, aPref, data); + return RegisterCallback(IntVarChanged, aPref, data, ExactMatch); } static void UintVarChanged(const char* aPref, void* aClosure) @@ -1793,7 +1805,7 @@ Preferences::AddUintVarCache(uint32_t* aCache, data->cacheLocation = aCache; data->defaultValueUint = aDefault; gCacheData->AppendElement(data); - return RegisterCallback(UintVarChanged, aPref, data); + return RegisterCallback(UintVarChanged, aPref, data, ExactMatch); } template @@ -1820,7 +1832,7 @@ Preferences::AddAtomicUintVarCache(Atomic* aCache, data->cacheLocation = aCache; data->defaultValueUint = aDefault; gCacheData->AppendElement(data); - return RegisterCallback(AtomicUintVarChanged, aPref, data); + return RegisterCallback(AtomicUintVarChanged, aPref, data, ExactMatch); } // Since the definition of this template function is not in a header file, @@ -1852,7 +1864,7 @@ Preferences::AddFloatVarCache(float* aCache, data->cacheLocation = aCache; data->defaultValueFloat = aDefault; gCacheData->AppendElement(data); - return RegisterCallback(FloatVarChanged, aPref, data); + return RegisterCallback(FloatVarChanged, aPref, data, ExactMatch); } // static diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h index 8415bb03392f..9fbddf3477a7 100644 --- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -246,18 +246,28 @@ public: /** * Registers/Unregisters the callback function for the aPref. + * + * Pass ExactMatch for aMatchKind to only get callbacks for + * exact matches and not prefixes. */ + enum MatchKind { + PrefixMatch, + ExactMatch, + }; static nsresult RegisterCallback(PrefChangedFunc aCallback, const char* aPref, - void* aClosure = nullptr); + void* aClosure = nullptr, + MatchKind aMatchKind = PrefixMatch); static nsresult UnregisterCallback(PrefChangedFunc aCallback, const char* aPref, - void* aClosure = nullptr); + void* aClosure = nullptr, + MatchKind aMatchKind = PrefixMatch); // Like RegisterCallback, but also calls the callback immediately for // initialization. static nsresult RegisterCallbackAndCall(PrefChangedFunc aCallback, const char* aPref, - void* aClosure = nullptr); + void* aClosure = nullptr, + MatchKind aMatchKind = PrefixMatch); /** * Adds the aVariable to cache table. aVariable must be a pointer for a