author | Justin Lebar <justin.lebar@gmail.com> |
Fri, 30 Jul 2010 11:36:30 -0700 | |
changeset 48422 | cc00ee24a25c82ef9bdcbda9d238c72c20626730 |
parent 48420 | 0a469738e2fb747b66073ef7d771ff73d5e47608 (current diff) |
parent 48421 | e06bf6e3bb360cdbd7a1f738093a29ad583edbf8 (diff) |
child 48423 | 4a3e8596e8fcf78ce918dbf3a3b5257b5700d330 |
push id | 14725 |
push user | jlebar@mozilla.com |
push date | Fri, 30 Jul 2010 18:35:12 +0000 |
treeherder | mozilla-central@cc00ee24a25c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 2.0b3pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -64,17 +64,16 @@ #include "nsIScriptGlobalObject.h" #include "nsIDOMEvent.h" #include "nsTArray.h" #include "nsTextFragment.h" #include "nsReadableUtils.h" #include "nsIPrefBranch2.h" #include "mozilla/AutoRestore.h" #include "nsINode.h" -#include "nsHashtable.h" #include "jsapi.h" struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error! class nsIDOMScriptObjectFactory; class nsIXPConnect; class nsIContent; @@ -106,27 +105,25 @@ class nsIContentPolicy; class nsILineBreaker; class nsIWordBreaker; class nsIJSRuntimeService; class nsIEventListenerManager; class nsIScriptContext; class nsIRunnable; class nsIInterfaceRequestor; template<class E> class nsCOMArray; -template<class K, class V> class nsRefPtrHashtable; struct JSRuntime; class nsIUGenCategory; class nsIWidget; class nsIDragSession; class nsPIDOMWindow; class nsPIDOMEventTarget; class nsIPresShell; class nsIXPConnectJSObjectHolder; class nsPrefOldCallback; -class nsPrefObserverHashKey; #ifdef MOZ_XTF class nsIXTFService; #endif #ifdef IBMBIDI class nsIBidiKeyboard; #endif class nsIMIMEHeaderParam; class nsIObserver; @@ -1708,18 +1705,17 @@ private: static nsIIOService *sIOService; #ifdef MOZ_XTF static nsIXTFService *sXTFService; #endif static nsIPrefBranch2 *sPrefBranch; // For old compatibility of RegisterPrefCallback - static nsRefPtrHashtable<nsPrefObserverHashKey, nsPrefOldCallback> - *sPrefCallbackTable; + static nsCOMArray<nsPrefOldCallback> *sPrefCallbackList; static bool sImgLoaderInitialized; static void InitImgLoader(); // The following two members are initialized lazily static imgILoader* sImgLoader; static imgICache* sImgCache;
--- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -257,18 +257,17 @@ nsIInterfaceRequestor* nsContentUtils::s nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService; JSRuntime *nsAutoGCRoot::sJSScriptRuntime; PRBool nsContentUtils::sIsHandlingKeyBoardEvent = PR_FALSE; PRBool nsContentUtils::sInitialized = PR_FALSE; -nsRefPtrHashtable<nsPrefObserverHashKey, nsPrefOldCallback> - *nsContentUtils::sPrefCallbackTable = nsnull; +nsCOMArray<nsPrefOldCallback> *nsContentUtils::sPrefCallbackList = nsnull; static PLDHashTable sEventListenerManagersHash; class EventListenerManagerMapEntry : public PLDHashEntryHdr { public: EventListenerManagerMapEntry(const void *aKey) : mKey(aKey) @@ -309,105 +308,49 @@ EventListenerManagerHashClearEntry(PLDHa class nsSameOriginChecker : public nsIChannelEventSink, public nsIInterfaceRequestor { NS_DECL_ISUPPORTS NS_DECL_NSICHANNELEVENTSINK NS_DECL_NSIINTERFACEREQUESTOR }; -class nsPrefObserverHashKey : public PLDHashEntryHdr { -public: - typedef nsPrefObserverHashKey* KeyType; - typedef const nsPrefObserverHashKey* KeyTypePointer; - - static const nsPrefObserverHashKey* KeyToPointer(nsPrefObserverHashKey *aKey) - { - return aKey; - } - - static PLDHashNumber HashKey(const nsPrefObserverHashKey *aKey) - { - PRUint32 strHash = nsCRT::HashCode(aKey->mPref.BeginReading(), - aKey->mPref.Length()); - return PR_ROTATE_LEFT32(strHash, 4) ^ - NS_PTR_TO_UINT32(aKey->mCallback); - } - - nsPrefObserverHashKey(const char *aPref, PrefChangedFunc aCallback) : - mPref(aPref), mCallback(aCallback) { } - - nsPrefObserverHashKey(const nsPrefObserverHashKey *aOther) : - mPref(aOther->mPref), mCallback(aOther->mCallback) - { } - - PRBool KeyEquals(const nsPrefObserverHashKey *aOther) const - { - return mCallback == aOther->mCallback && - mPref.Equals(aOther->mPref); - } - - nsPrefObserverHashKey *GetKey() const - { - return const_cast<nsPrefObserverHashKey*>(this); - } - - enum { ALLOW_MEMMOVE = PR_TRUE }; - -public: - nsCString mPref; - PrefChangedFunc mCallback; -}; - // For nsContentUtils::RegisterPrefCallback/UnregisterPrefCallback -class nsPrefOldCallback : public nsIObserver, - public nsPrefObserverHashKey +class nsPrefOldCallback : public nsIObserver { public: NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER public: - nsPrefOldCallback(const char *aPref, PrefChangedFunc aCallback) - : nsPrefObserverHashKey(aPref, aCallback) { } - - ~nsPrefOldCallback() { - nsContentUtils::GetPrefBranch()->RemoveObserver(mPref.get(), this); - } - - void AppendClosure(void *aClosure) { - mClosures.AppendElement(aClosure); - } - - void RemoveClosure(void *aClosure) { - mClosures.RemoveElement(aClosure); - } - - PRBool HasNoClosures() { - return mClosures.Length() == 0; + nsPrefOldCallback(const char *aPref, PrefChangedFunc aCallback, void *aClosure) : mPref(aPref), mCallback(aCallback), mClosure(aClosure) { + } + + PRBool IsEqual(const char *aPref, PrefChangedFunc aCallback, void *aClosure) { + return aCallback == mCallback && + aClosure == mClosure && + mPref.Equals(aPref); } public: - nsTObserverArray<void *> mClosures; + nsCString mPref; + PrefChangedFunc mCallback; + void *mClosure; }; NS_IMPL_ISUPPORTS1(nsPrefOldCallback, nsIObserver) NS_IMETHODIMP -nsPrefOldCallback::Observe(nsISupports *aSubject, - const char *aTopic, - const PRUnichar *aData) +nsPrefOldCallback::Observe(nsISupports *aSubject, + const char *aTopic, + const PRUnichar *aData) { NS_ASSERTION(!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID), "invalid topic"); - NS_LossyConvertUTF16toASCII data(aData); - nsTObserverArray<void *>::ForwardIterator iter(mClosures); - while (iter.HasMore()) { - mCallback(data.get(), iter.GetNext()); - } + mCallback(NS_LossyConvertUTF16toASCII(aData).get(), mClosure); return NS_OK; } struct PrefCacheData { void* cacheLocation; union { PRBool defaultValueBool; @@ -1104,19 +1047,26 @@ nsContentUtils::Shutdown() NS_IF_RELEASE(sContentPolicyService); sTriedToGetContentPolicy = PR_FALSE; PRUint32 i; for (i = 0; i < PropertiesFile_COUNT; ++i) NS_IF_RELEASE(sStringBundles[i]); // Clean up c-style's observer - if (sPrefCallbackTable) { - delete sPrefCallbackTable; - sPrefCallbackTable = nsnull; + if (sPrefCallbackList) { + while (sPrefCallbackList->Count() > 0) { + nsRefPtr<nsPrefOldCallback> callback = (*sPrefCallbackList)[0]; + NS_ABORT_IF_FALSE(callback, "Invalid c-style callback is appended"); + if (sPrefBranch) + sPrefBranch->RemoveObserver(callback->mPref.get(), callback); + sPrefCallbackList->RemoveObject(callback); + } + delete sPrefCallbackList; + sPrefCallbackList = nsnull; } delete sPrefCacheData; sPrefCacheData = nsnull; NS_IF_RELEASE(sStringBundleService); NS_IF_RELEASE(sConsoleService); NS_IF_RELEASE(sDOMScriptObjectFactory); @@ -2665,68 +2615,61 @@ nsContentUtils::GetStringPref(const char if (theString) { theString->ToString(getter_Copies(result)); } } return result; } -// RegisterPrefCallback/UnregisterPrefCallback are for backward compatiblity -// with c-style observers. +// RegisterPrefCallback/UnregisterPrefCallback are backward compatiblity for +// c-style observer. // static void nsContentUtils::RegisterPrefCallback(const char *aPref, PrefChangedFunc aCallback, void * aClosure) { if (sPrefBranch) { - if (!sPrefCallbackTable) { - sPrefCallbackTable = - new nsRefPtrHashtable<nsPrefObserverHashKey, nsPrefOldCallback>(); - sPrefCallbackTable->Init(); + if (!sPrefCallbackList) { + sPrefCallbackList = new nsCOMArray<nsPrefOldCallback> (); + if (!sPrefCallbackList) + return; } - nsPrefObserverHashKey hashKey(aPref, aCallback); - nsRefPtr<nsPrefOldCallback> callback; - sPrefCallbackTable->Get(&hashKey, getter_AddRefs(callback)); + nsPrefOldCallback *callback = new nsPrefOldCallback(aPref, aCallback, aClosure); if (callback) { - callback->AppendClosure(aClosure); - return; - } - - callback = new nsPrefOldCallback(aPref, aCallback); - callback->AppendClosure(aClosure); - if (NS_SUCCEEDED(sPrefBranch->AddObserver(aPref, callback, PR_FALSE))) { - sPrefCallbackTable->Put(callback, callback); + if (NS_SUCCEEDED(sPrefBranch->AddObserver(aPref, callback, PR_FALSE))) { + sPrefCallbackList->AppendObject(callback); + return; + } + // error to get/add nsIPrefBranch2. Destroy callback information + delete callback; } } } // static void nsContentUtils::UnregisterPrefCallback(const char *aPref, PrefChangedFunc aCallback, void * aClosure) { if (sPrefBranch) { - if (!sPrefCallbackTable) { + if (!sPrefCallbackList) return; - } - - nsPrefObserverHashKey hashKey(aPref, aCallback); - nsRefPtr<nsPrefOldCallback> callback; - sPrefCallbackTable->Get(&hashKey, getter_AddRefs(callback)); - - if (callback) { - callback->RemoveClosure(aClosure); - if (callback->HasNoClosures()) { - // Delete the callback since its list of closures is empty. - sPrefCallbackTable->Remove(callback); + + int i; + for (i = 0; i < sPrefCallbackList->Count(); i++) { + nsRefPtr<nsPrefOldCallback> callback = (*sPrefCallbackList)[i]; + if (callback && callback->IsEqual(aPref, aCallback, aClosure)) { + sPrefBranch->RemoveObserver(aPref, callback); + sPrefCallbackList->RemoveObject(callback); + return; } } } } static int BoolVarChanged(const char *aPref, void *aClosure) {
--- a/modules/libpref/src/prefapi.cpp +++ b/modules/libpref/src/prefapi.cpp @@ -847,19 +847,19 @@ PREF_UnregisterCallback(const char *pref void * instance_data) { nsresult rv = NS_ERROR_FAILURE; struct CallbackNode* node = gCallbacks; struct CallbackNode* prev_node = NULL; while (node != NULL) { - if ( node->func == callback && - node->data == instance_data && - strcmp(node->domain, pref_node) == 0) + if ( strcmp(node->domain, pref_node) == 0 && + node->func == callback && + node->data == instance_data) { if (gCallbacksInProgress) { // postpone the node removal until after // gCallbacks enumeration is finished. node->func = nsnull; gShouldCleanupDeadNodes = PR_TRUE; prev_node = node;