diff --git a/caps/include/nsPrincipal.h b/caps/include/nsPrincipal.h index b58f65bd7282..1a933163efd2 100644 --- a/caps/include/nsPrincipal.h +++ b/caps/include/nsPrincipal.h @@ -42,6 +42,7 @@ #include "nsAutoPtr.h" #include "nsCOMPtr.h" +#include "nsVoidArray.h" #include "nsHashtable.h" #include "nsJSPrincipals.h" #include "nsTArray.h" diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp index 2d2c7509ffb2..2c89c565c3ea 100644 --- a/caps/src/nsPrincipal.cpp +++ b/caps/src/nsPrincipal.cpp @@ -49,6 +49,7 @@ #include "nsIProtocolHandler.h" #include "nsNetUtil.h" #include "nsJSPrincipals.h" +#include "nsVoidArray.h" #include "nsHashtable.h" #include "nsIObjectInputStream.h" #include "nsIObjectOutputStream.h" diff --git a/chrome/src/nsChromeRegistry.cpp b/chrome/src/nsChromeRegistry.cpp index e4a8945ceca7..b84a01796aaf 100644 --- a/chrome/src/nsChromeRegistry.cpp +++ b/chrome/src/nsChromeRegistry.cpp @@ -266,7 +266,7 @@ CanLoadResource(nsIURI* aResourceURI) nsChromeRegistry::ProviderEntry* nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType) { - PRInt32 i = mArray.Length(); + PRInt32 i = mArray.Count(); if (!i) return nsnull; @@ -274,7 +274,7 @@ nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, Mat ProviderEntry* entry; while (i--) { - entry = &mArray[i]; + entry = reinterpret_cast(mArray[i]); if (aPreferred.Equals(entry->provider)) return entry; @@ -329,21 +329,32 @@ nsChromeRegistry::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* } // no existing entries, add a new one - mArray.AppendElement(ProviderEntry(aProvider, aBaseURL)); + provider = new ProviderEntry(aProvider, aBaseURL); + if (!provider) + return; // It's safe to silently fail on OOM + + mArray.AppendElement(provider); } void nsChromeRegistry::nsProviderArray::EnumerateToArray(nsTArray *a) { - PRInt32 i = mArray.Length(); + PRInt32 i = mArray.Count(); while (i--) { - a->AppendElement(mArray[i].provider); + ProviderEntry *entry = reinterpret_cast(mArray[i]); + a->AppendElement(entry->provider); } } void nsChromeRegistry::nsProviderArray::Clear() { + PRInt32 i = mArray.Count(); + while (i--) { + ProviderEntry* entry = reinterpret_cast(mArray[i]); + delete entry; + } + mArray.Clear(); } diff --git a/chrome/src/nsChromeRegistry.h b/chrome/src/nsChromeRegistry.h index 3f1c87c23714..ff0bf41f18a9 100644 --- a/chrome/src/nsChromeRegistry.h +++ b/chrome/src/nsChromeRegistry.h @@ -52,6 +52,7 @@ #include "nsString.h" #include "nsTHashtable.h" #include "nsURIHashKey.h" +#include "nsVoidArray.h" #include "nsTArray.h" #include "nsInterfaceHashtable.h" @@ -170,7 +171,7 @@ public: private: ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType); - nsTArray mArray; + nsVoidArray mArray; }; struct PackageEntry : public PLDHashEntryHdr diff --git a/db/morkreader/nsMorkReader.cpp b/db/morkreader/nsMorkReader.cpp index f6fbcbc6d8a3..b66ac91873d5 100644 --- a/db/morkreader/nsMorkReader.cpp +++ b/db/morkreader/nsMorkReader.cpp @@ -39,6 +39,7 @@ #include "nsMorkReader.h" #include "prio.h" #include "nsNetUtil.h" +#include "nsVoidArray.h" // A FixedString implementation that can hold 2 80-character lines class nsCLineString : public nsFixedCString diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 06470e231209..98f3746e4127 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -813,9 +813,9 @@ void nsDocShell::DestroyChildren() { nsCOMPtr shell; - PRUint32 n = mChildList.Length(); - for (PRUint32 i = 0; i < n; i++) { - shell = do_QueryInterface(mChildList[i]); + PRInt32 n = mChildList.Count(); + for (PRInt32 i = 0; i < n; i++) { + shell = do_QueryInterface(ChildAt(i)); NS_ASSERTION(shell, "docshell has null child"); if (shell) { @@ -1474,10 +1474,10 @@ nsDocShell::FirePageHideNotification(PRBool aIsUnload) mContentViewer->PageHide(aIsUnload); nsAutoTArray, 8> kids; - PRUint32 i, n = mChildList.Length(); + PRInt32 i, n = mChildList.Count(); kids.SetCapacity(n); for (i = 0; i < n; i++) { - kids.AppendElement(do_QueryInterface(mChildList[i])); + kids.AppendElement(do_QueryInterface(ChildAt(i))); } n = kids.Length(); @@ -2129,9 +2129,9 @@ nsDocShell::HistoryPurged(PRInt32 aNumEntries) mPreviousTransIndex = PR_MAX(-1, mPreviousTransIndex - aNumEntries); mLoadedTransIndex = PR_MAX(0, mLoadedTransIndex - aNumEntries); - PRUint32 count = mChildList.Length(); - for (PRUint32 i = 0; i < count; ++i) { - nsCOMPtr shell = do_QueryInterface(mChildList[i]); + PRInt32 count = mChildList.Count(); + for (PRInt32 i = 0; i < count; ++i) { + nsCOMPtr shell = do_QueryInterface(ChildAt(i)); if (shell) { shell->HistoryPurged(aNumEntries); } @@ -2834,9 +2834,9 @@ nsDocShell::SetTreeOwner(nsIDocShellTreeOwner * aTreeOwner) mTreeOwner = aTreeOwner; // Weak reference per API - PRUint32 i, n = mChildList.Length(); + PRInt32 i, n = mChildList.Count(); for (i = 0; i < n; i++) { - nsCOMPtr child = do_QueryInterface(mChildList[i]); + nsCOMPtr child = do_QueryInterface(ChildAt(i)); NS_ENSURE_TRUE(child, NS_ERROR_FAILURE); PRInt32 childType = ~mItemType; // Set it to not us in case the get fails child->GetItemType(&childType); // We don't care if this fails, if it does we won't set the owner @@ -2869,7 +2869,7 @@ NS_IMETHODIMP nsDocShell::GetChildCount(PRInt32 * aChildCount) { NS_ENSURE_ARG_POINTER(aChildCount); - *aChildCount = mChildList.Length(); + *aChildCount = mChildList.Count(); return NS_OK; } @@ -2904,7 +2904,7 @@ nsDocShell::AddChild(nsIDocShellTreeItem * aChild) nsresult res = AddChildLoader(childAsDocLoader); NS_ENSURE_SUCCESS(res, res); - NS_ASSERTION(!mChildList.IsEmpty(), + NS_ASSERTION(mChildList.Count() > 0, "child list must not be empty after a successful add"); // Set the child's index in the parent's children list @@ -2919,11 +2919,11 @@ nsDocShell::AddChild(nsIDocShellTreeItem * aChild) nsCOMPtr domDoc = do_GetInterface(GetAsSupports(this)); nsCOMPtr doc = do_QueryInterface(domDoc); - PRUint32 offset = mChildList.Length() - 1; + PRUint32 offset = mChildList.Count() - 1; if (doc) { PRUint32 oldChildCount = offset; // Current child count - 1 for (PRUint32 i = 0; i < oldChildCount; ++i) { - nsCOMPtr child = do_QueryInterface(mChildList[i]); + nsCOMPtr child = do_QueryInterface(ChildAt(i)); if (doc->FrameLoaderScheduledToBeFinalized(child)) { --offset; } @@ -3043,12 +3043,12 @@ nsDocShell::GetChildAt(PRInt32 aIndex, nsIDocShellTreeItem ** aChild) if (aIndex < 0) { NS_WARNING("Negative index passed to GetChildAt"); } - else if (PRUint32(aIndex) >= mChildList.Length()) { + else if (aIndex >= mChildList.Count()) { NS_WARNING("Too large an index passed to GetChildAt"); } #endif - nsIDocumentLoader* child = mChildList.SafeElementAt(aIndex); + nsIDocumentLoader* child = SafeChildAt(aIndex); NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED); return CallQueryInterface(child, aChild); @@ -3070,9 +3070,9 @@ nsDocShell::FindChildWithName(const PRUnichar * aName, return NS_OK; nsXPIDLString childName; - PRUint32 i, n = mChildList.Length(); + PRInt32 i, n = mChildList.Count(); for (i = 0; i < n; i++) { - nsCOMPtr child = do_QueryInterface(mChildList[i]); + nsCOMPtr child = do_QueryInterface(ChildAt(i)); NS_ENSURE_TRUE(child, NS_ERROR_FAILURE); PRInt32 childType; child->GetItemType(&childType); @@ -3970,10 +3970,10 @@ nsDocShell::Stop(PRUint32 aStopFlags) Stop(); } - PRUint32 n; - PRUint32 count = mChildList.Length(); + PRInt32 n; + PRInt32 count = mChildList.Count(); for (n = 0; n < count; n++) { - nsCOMPtr shellAsNav(do_QueryInterface(mChildList[n])); + nsCOMPtr shellAsNav(do_QueryInterface(ChildAt(n))); if (shellAsNav) shellAsNav->Stop(aStopFlags); } @@ -5408,10 +5408,10 @@ nsDocShell::SuspendRefreshURIs() } // Suspend refresh URIs for our child shells as well. - PRUint32 n = mChildList.Length(); + PRInt32 n = mChildList.Count(); - for (PRUint32 i = 0; i < n; ++i) { - nsCOMPtr shell = do_QueryInterface(mChildList[i]); + for (PRInt32 i = 0; i < n; ++i) { + nsCOMPtr shell = do_QueryInterface(ChildAt(i)); if (shell) shell->SuspendRefreshURIs(); } @@ -5425,10 +5425,10 @@ nsDocShell::ResumeRefreshURIs() RefreshURIFromQueue(); // Resume refresh URIs for our child shells as well. - PRUint32 n = mChildList.Length(); + PRInt32 n = mChildList.Count(); - for (PRUint32 i = 0; i < n; ++i) { - nsCOMPtr shell = do_QueryInterface(mChildList[i]); + for (PRInt32 i = 0; i < n; ++i) { + nsCOMPtr shell = do_QueryInterface(ChildAt(i)); if (shell) shell->ResumeRefreshURIs(); } @@ -6371,9 +6371,9 @@ nsDocShell::CaptureState() // Capture the docshell hierarchy. mOSHE->ClearChildShells(); - PRUint32 childCount = mChildList.Length(); - for (PRUint32 i = 0; i < childCount; ++i) { - nsCOMPtr childShell = do_QueryInterface(mChildList[i]); + PRInt32 childCount = mChildList.Count(); + for (PRInt32 i = 0; i < childCount; ++i) { + nsCOMPtr childShell = do_QueryInterface(ChildAt(i)); NS_ASSERTION(childShell, "null child shell"); mOSHE->AddChildShell(childShell); @@ -6440,9 +6440,9 @@ nsDocShell::BeginRestore(nsIContentViewer *aContentViewer, PRBool aTop) nsresult nsDocShell::BeginRestoreChildren() { - PRUint32 n = mChildList.Length(); - for (PRUint32 i = 0; i < n; ++i) { - nsCOMPtr child = do_QueryInterface(mChildList[i]); + PRInt32 n = mChildList.Count(); + for (PRInt32 i = 0; i < n; ++i) { + nsCOMPtr child = do_QueryInterface(ChildAt(i)); if (child) { nsresult rv = child->BeginRestore(nsnull, PR_FALSE); NS_ENSURE_SUCCESS(rv, rv); @@ -6457,9 +6457,9 @@ nsDocShell::FinishRestore() // First we call finishRestore() on our children. In the simulated load, // all of the child frames finish loading before the main document. - PRUint32 n = mChildList.Length(); - for (PRUint32 i = 0; i < n; ++i) { - nsCOMPtr child = do_QueryInterface(mChildList[i]); + PRInt32 n = mChildList.Count(); + for (PRInt32 i = 0; i < n; ++i) { + nsCOMPtr child = do_QueryInterface(ChildAt(i)); if (child) { child->FinishRestore(); } @@ -6926,9 +6926,9 @@ nsDocShell::RestoreFromHistory() // Meta-refresh timers have been restarted for this shell, but not // for our children. Walk the child shells and restart their timers. - PRInt32 n = mChildList.Length(); + PRInt32 n = mChildList.Count(); for (i = 0; i < n; ++i) { - nsCOMPtr child = do_QueryInterface(mChildList[i]); + nsCOMPtr child = do_QueryInterface(ChildAt(i)); if (child) child->ResumeRefreshURIs(); } @@ -9350,10 +9350,10 @@ nsDocShell::WalkHistoryEntries(nsISHEntry *aRootEntry, // Walk the children of aRootShell and see if one of them // has srcChild as a SHEntry. - PRUint32 childCount = aRootShell->mChildList.Length(); - for (PRUint32 j = 0; j < childCount; ++j) { + PRInt32 childCount = aRootShell->mChildList.Count(); + for (PRInt32 j = 0; j < childCount; ++j) { nsDocShell *child = - static_cast(aRootShell->mChildList[j]); + static_cast(aRootShell->ChildAt(j)); if (child->HasHistoryEntry(childEntry)) { childShell = child; diff --git a/dom/base/nsIDOMClassInfo.h b/dom/base/nsIDOMClassInfo.h index 33d26d96bd5f..d4e121fca466 100644 --- a/dom/base/nsIDOMClassInfo.h +++ b/dom/base/nsIDOMClassInfo.h @@ -40,6 +40,7 @@ #define nsIDOMClassInfo_h___ #include "nsIClassInfoImpl.h" +#include "nsVoidArray.h" #include "nsDOMClassInfoID.h" #include "nsIXPCScriptable.h" #include "nsIServiceManager.h" diff --git a/dom/src/storage/nsDOMStorage.h b/dom/src/storage/nsDOMStorage.h index 170490d43d87..2633f254c998 100644 --- a/dom/src/storage/nsDOMStorage.h +++ b/dom/src/storage/nsDOMStorage.h @@ -48,6 +48,7 @@ #include "nsIDOMStorageList.h" #include "nsIDOMStorageItem.h" #include "nsInterfaceHashtable.h" +#include "nsVoidArray.h" #include "nsTArray.h" #include "nsPIDOMStorage.h" #include "nsIDOMToString.h" diff --git a/editor/libeditor/base/nsSelectionState.cpp b/editor/libeditor/base/nsSelectionState.cpp index 3f98b1ebd3ba..9331c968c4e4 100644 --- a/editor/libeditor/base/nsSelectionState.cpp +++ b/editor/libeditor/base/nsSelectionState.cpp @@ -76,10 +76,27 @@ nsresult nsSelectionState::SaveSelection(nsISelection *aSel) { if (!aSel) return NS_ERROR_NULL_POINTER; - PRInt32 i,rangeCount; + PRInt32 i,rangeCount, arrayCount = mArray.Length(); aSel->GetRangeCount(&rangeCount); - mArray.SetLength(rangeCount); + // if we need more items in the array, new them + if (arrayCountrangeCount) + { + for (i = arrayCount-1; i >= rangeCount; i--) + { + mArray.RemoveElementAt(i); + } + } // now store the selection ranges nsresult res = NS_OK; diff --git a/editor/txmgr/src/nsTransactionManager.cpp b/editor/txmgr/src/nsTransactionManager.cpp index d10b0f8657a8..2f5d44c3a55c 100644 --- a/editor/txmgr/src/nsTransactionManager.cpp +++ b/editor/txmgr/src/nsTransactionManager.cpp @@ -40,6 +40,7 @@ #include "nsTransactionItem.h" #include "nsTransactionStack.h" +#include "nsVoidArray.h" #include "nsTransactionManager.h" #include "nsTransactionList.h" #include "nsAutoPtr.h" diff --git a/embedding/components/commandhandler/src/nsCommandGroup.h b/embedding/components/commandhandler/src/nsCommandGroup.h index 851315d8ea06..0b1dfba7c3a7 100644 --- a/embedding/components/commandhandler/src/nsCommandGroup.h +++ b/embedding/components/commandhandler/src/nsCommandGroup.h @@ -75,7 +75,7 @@ protected: protected: nsHashtable mGroupsHash; // hash keyed on command group. - // Entries are nsTArrays of pointers to char* + // Entries are nsVoidArrays of pointers to PRUnichar* // This could be made more space-efficient, maybe with atoms }; diff --git a/extensions/java/xpcom/src/nsJavaXPTCStub.cpp b/extensions/java/xpcom/src/nsJavaXPTCStub.cpp index d23c1a01f0cb..0eb347516666 100644 --- a/extensions/java/xpcom/src/nsJavaXPTCStub.cpp +++ b/extensions/java/xpcom/src/nsJavaXPTCStub.cpp @@ -177,7 +177,9 @@ nsJavaXPTCStub::Destroy() if (!mMaster) { // delete each child stub - mChildren.Clear(); + for (PRInt32 i = 0; i < mChildren.Count(); i++) { + delete (nsJavaXPTCStub*) mChildren[i]; + } // Since we are destroying this stub, also remove the mapping. // It is possible for mJavaStrongRef to be NULL here. That is why we @@ -377,9 +379,9 @@ nsJavaXPTCStub::FindStubSupportingIID(const nsID &iid) if (SupportsIID(iid)) return this; - for (PRUint32 i = 0; i < mChildren.Length(); i++) + for (PRInt32 i = 0; i < mChildren.Count(); i++) { - nsJavaXPTCStub *child = mChildren[i]; + nsJavaXPTCStub *child = (nsJavaXPTCStub *) mChildren[i]; if (child->SupportsIID(iid)) return child; } diff --git a/extensions/java/xpcom/src/nsJavaXPTCStub.h b/extensions/java/xpcom/src/nsJavaXPTCStub.h index 99ac85b1ff6f..dd65f72b278f 100644 --- a/extensions/java/xpcom/src/nsJavaXPTCStub.h +++ b/extensions/java/xpcom/src/nsJavaXPTCStub.h @@ -40,8 +40,7 @@ #include "nsXPTCUtils.h" #include "jni.h" -#include "nsTArray.h" -#include "nsAutoPtr.h" +#include "nsVoidArray.h" #include "nsIInterfaceInfo.h" #include "nsCOMPtr.h" #include "nsWeakReference.h" @@ -139,7 +138,7 @@ private: jint mJavaRefHashCode; nsCOMPtr mIInfo; - nsTArray > mChildren; // weak references (cleared by the children) + nsVoidArray mChildren; // weak references (cleared by the children) nsJavaXPTCStub *mMaster; // strong reference nsAutoRefCnt mWeakRefCnt; // count for number of associated weak refs diff --git a/extensions/layout-debug/src/nsRegressionTester.cpp b/extensions/layout-debug/src/nsRegressionTester.cpp index 3078b5e5d589..832292eb59f5 100644 --- a/extensions/layout-debug/src/nsRegressionTester.cpp +++ b/extensions/layout-debug/src/nsRegressionTester.cpp @@ -41,6 +41,7 @@ #include "nsXPIDLString.h" #include "nsReadableUtils.h" #include "nsIWindowWatcher.h" +#include "nsVoidArray.h" #include "prmem.h" #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeNode.h" diff --git a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp index ee4525124aab..53f26ab5a666 100644 --- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp +++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.cpp @@ -164,7 +164,7 @@ private: nsSystemPrefService *mSysPrefService; //listeners - nsAutoTArray, 8> mObservers; + nsAutoVoidArray *mObservers; void InitFuncPtrs(); //gconf public func ptrs @@ -205,17 +205,27 @@ private: }; struct SysPrefCallbackData { - nsCOMPtr observer; + nsISupports *observer; PRBool bIsWeakRef; PRUint32 prefAtom; }; +PRBool +sysPrefDeleteObserver(void *aElement, void *aData) { + SysPrefCallbackData *pElement = + static_cast(aElement); + NS_RELEASE(pElement->observer); + nsMemory::Free(pElement); + return PR_TRUE; +} + NS_IMPL_ISUPPORTS2(nsSystemPrefService, nsIPrefBranch, nsIPrefBranch2) /* public */ nsSystemPrefService::nsSystemPrefService() :mInitialized(PR_FALSE), - mGConf(nsnull) + mGConf(nsnull), + mObservers(nsnull) { } @@ -225,6 +235,10 @@ nsSystemPrefService::~nsSystemPrefService() if (mGConf) delete mGConf; + if (mObservers) { + (void)mObservers->EnumerateForwards(sysPrefDeleteObserver, nsnull); + delete mObservers; + } } nsresult @@ -378,10 +392,19 @@ NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom); NS_ENSURE_SUCCESS(rv, rv); - SysPrefCallbackData *cbData = new SysPrefCallbackData(); + if (!mObservers) { + mObservers = new nsAutoVoidArray(); + if (mObservers == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + } - cbData->bIsWeakRef = aHoldWeak; - cbData->prefAtom = prefAtom; + SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *) + nsMemory::Alloc(sizeof(SysPrefCallbackData)); + if (pCallbackData == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + pCallbackData->bIsWeakRef = aHoldWeak; + pCallbackData->prefAtom = prefAtom; // hold a weak reference to the observer if so requested nsCOMPtr observerRef; if (aHoldWeak) { @@ -390,7 +413,7 @@ NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver if (!weakRefFactory) { // the caller didn't give us a object that supports weak reference. // ... tell them - delete cbData; + nsMemory::Free(pCallbackData); return NS_ERROR_INVALID_ARG; } nsCOMPtr tmp = do_GetWeakReference(weakRefFactory); @@ -399,15 +422,16 @@ NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver observerRef = aObserver; } - rv = mGConf->NotifyAdd(prefAtom, cbData); + rv = mGConf->NotifyAdd(prefAtom, pCallbackData); if (NS_FAILED(rv)) { - delete cbData; + nsMemory::Free(pCallbackData); return rv; } - cbData->observer = observerRef; - mObservers.AppendElement(cbData); + pCallbackData->observer = observerRef; + NS_ADDREF(pCallbackData->observer); + mObservers->AppendElement(pCallbackData); return NS_OK; } @@ -419,6 +443,9 @@ NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserv NS_ENSURE_ARG_POINTER(aDomain); NS_ENSURE_ARG_POINTER(aObserver); NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); + + if (!mObservers) + return NS_OK; PRUint32 prefAtom; // make sure the pref name is supported @@ -426,33 +453,38 @@ NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserv NS_ENSURE_SUCCESS(rv, rv); // need to find the index of observer, so we can remove it - PRUint32 count = mObservers.Length(); - if (!count) + PRIntn count = mObservers->Count(); + if (count <= 0) return NS_OK; - PRUint32 i; + PRIntn i; + SysPrefCallbackData *pCallbackData; for (i = 0; i < count; ++i) { - SysPrefCallbackData *cbData = mObservers[i]; - nsCOMPtr observerRef; - if (cbData->bIsWeakRef) { - nsCOMPtr weakRefFactory = - do_QueryInterface(aObserver); - if (weakRefFactory) { - nsCOMPtr tmp = - do_GetWeakReference(aObserver); - observerRef = tmp; + pCallbackData = (SysPrefCallbackData *)mObservers->ElementAt(i); + if (pCallbackData) { + nsCOMPtr observerRef; + if (pCallbackData->bIsWeakRef) { + nsCOMPtr weakRefFactory = + do_QueryInterface(aObserver); + if (weakRefFactory) { + nsCOMPtr tmp = + do_GetWeakReference(aObserver); + observerRef = tmp; + } } - } - if (!observerRef) - observerRef = aObserver; + if (!observerRef) + observerRef = aObserver; - if (cbData->observer == observerRef && - cbData->prefAtom == prefAtom) { - rv = mGConf->NotifyRemove(prefAtom, cbData); - if (NS_SUCCEEDED(rv)) { - mObservers.RemoveElementAt(i); + if (pCallbackData->observer == observerRef && + pCallbackData->prefAtom == prefAtom) { + rv = mGConf->NotifyRemove(prefAtom, pCallbackData); + if (NS_SUCCEEDED(rv)) { + mObservers->RemoveElementAt(i); + NS_RELEASE(pCallbackData->observer); + nsMemory::Free(pCallbackData); + } + return rv; } - return rv; } } return NS_OK; @@ -478,7 +510,9 @@ nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData) // this weak referenced observer went away, remove it from the list nsresult rv = mGConf->NotifyRemove(aPrefAtom, pData); if (NS_SUCCEEDED(rv)) { - mObservers.RemoveElement(pData); + mObservers->RemoveElement(pData); + NS_RELEASE(pData->observer); + nsMemory::Free(pData); } return; } @@ -553,12 +587,18 @@ static const PrefNamePair sPrefNameMapping[] = { {nsnull, nsnull}, }; +PRBool +gconfDeleteObserver(void *aElement, void *aData) { + nsMemory::Free(aElement); + return PR_TRUE; +} GConfProxy::GConfProxy(nsSystemPrefService *aSysPrefService): mGConfClient(nsnull), mGConfLib(nsnull), mInitialized(PR_FALSE), - mSysPrefService(aSysPrefService) + mSysPrefService(aSysPrefService), + mObservers(nsnull) { } @@ -567,6 +607,11 @@ GConfProxy::~GConfProxy() if (mGConfClient) g_object_unref(G_OBJECT(mGConfClient)); + if (mObservers) { + (void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull); + delete mObservers; + } + // bug 379666: can't unload GConf-2 since it registers atexit handlers //PR_UnloadLibrary(mGConfLib); } @@ -719,13 +764,20 @@ GConfProxy::NotifyAdd (PRUint32 aAtom, void *aUserData) if (!gconfKey) return NS_ERROR_FAILURE; - GConfCallbackData *pData = new GConfCallbackData(); + if (!mObservers) { + mObservers = new nsAutoVoidArray(); + if (mObservers == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + } + + GConfCallbackData *pData = (GConfCallbackData *) + nsMemory::Alloc(sizeof(GConfCallbackData)); NS_ENSURE_TRUE(pData, NS_ERROR_OUT_OF_MEMORY); pData->proxy = this; pData->userData = aUserData; pData->atom = aAtom; - mObservers.AppendElement(pData); + mObservers->AppendElement(pData); GConfClientAddDir(mGConfClient, gconfKey, 0, // GCONF_CLIENT_PRELOAD_NONE, don't preload anything @@ -742,18 +794,20 @@ GConfProxy::NotifyRemove (PRUint32 aAtom, const void *aUserData) { NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE); - PRUint32 count = mObservers.Length(); - if (!count) + PRIntn count = mObservers->Count(); + if (count <= 0) return NS_OK; - PRUint32 i; + PRIntn i; + GConfCallbackData *pData; for (i = 0; i < count; ++i) { - GConfCallbackData *pData = mObservers[i]; - if (pData->atom == aAtom && pData->userData == aUserData) { + pData = (GConfCallbackData *)mObservers->ElementAt(i); + if (pData && pData->atom == aAtom && pData->userData == aUserData) { GConfClientNotifyRemove(mGConfClient, pData->notifyId); GConfClientRemoveDir(mGConfClient, GetGConfKey(pData->atom), NULL); - mObservers.RemoveElementAt(i); + mObservers->RemoveElementAt(i); + nsMemory::Free(pData); break; } } diff --git a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h index 57ed79117469..59107c59b03d 100644 --- a/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h +++ b/extensions/pref/system-pref/src/gconf/nsSystemPrefService.h @@ -43,14 +43,12 @@ #define __SYSTEM_PREF_SERVICE_H__ #include "prlink.h" -#include "nsTArray.h" -#include "nsAutoPtr.h" +#include "nsVoidArray.h" #include "nsWeakPtr.h" #include "nsIPrefBranch.h" #include "nsIPrefBranch2.h" class GConfProxy; -struct SysPrefCallbackData; //////////////////////////////////////////////////////////////////////////// // nsSystemPrefService provide a interface for read system prefs. It is @@ -76,7 +74,7 @@ private: GConfProxy *mGConf; //listeners - nsAutoTArray, 8> mObservers; + nsAutoVoidArray *mObservers; }; #define NS_SYSTEMPREF_SERVICE_CID \ diff --git a/extensions/spellcheck/src/mozPersonalDictionary.h b/extensions/spellcheck/src/mozPersonalDictionary.h index aa42a0e3af06..876d8ed85cc8 100644 --- a/extensions/spellcheck/src/mozPersonalDictionary.h +++ b/extensions/spellcheck/src/mozPersonalDictionary.h @@ -40,6 +40,7 @@ #include "nsCOMPtr.h" #include "nsString.h" +#include "nsVoidArray.h" #include "mozIPersonalDictionary.h" #include "nsIUnicodeEncoder.h" #include "nsIObserver.h" diff --git a/extensions/spellcheck/src/mozSpellChecker.h b/extensions/spellcheck/src/mozSpellChecker.h index ce6b4362f794..9d67e4c6ae00 100644 --- a/extensions/spellcheck/src/mozSpellChecker.h +++ b/extensions/spellcheck/src/mozSpellChecker.h @@ -45,6 +45,7 @@ #include "mozIPersonalDictionary.h" #include "mozISpellCheckingEngine.h" #include "nsClassHashtable.h" +#include "nsVoidArray.h" #include "nsTArray.h" #include "mozISpellI18NUtil.h" diff --git a/intl/locale/src/nsLocale.cpp b/intl/locale/src/nsLocale.cpp index d559c8b7acf0..466c9571c6e9 100644 --- a/intl/locale/src/nsLocale.cpp +++ b/intl/locale/src/nsLocale.cpp @@ -44,6 +44,7 @@ #include "nsLocale.h" #include "nsLocaleCID.h" #include "nsCOMPtr.h" +#include "nsVoidArray.h" #include "nsMemory.h" #include "nsCRT.h" diff --git a/layout/inspector/src/inCSSValueSearch.cpp b/layout/inspector/src/inCSSValueSearch.cpp index f246db3a42a5..1ce03182c099 100644 --- a/layout/inspector/src/inCSSValueSearch.cpp +++ b/layout/inspector/src/inCSSValueSearch.cpp @@ -39,6 +39,7 @@ #include "nsIComponentManager.h" #include "nsIServiceManager.h" +#include "nsVoidArray.h" #include "nsReadableUtils.h" #include "nsIDOMDocumentStyle.h" #include "nsIDOM3Node.h" diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 64419b288c42..d3bcfb66385a 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -942,12 +942,13 @@ RuleProcessorData::~RuleProcessorData() // Destroy potentially long chains of previous sibling and parent data // without more than one level of recursion. if (mPreviousSiblingData || mParentData) { - nsAutoTArray destroyQueue; + nsAutoVoidArray destroyQueue; destroyQueue.AppendElement(this); do { - RuleProcessorData *d = destroyQueue[destroyQueue.Length() - 1]; - destroyQueue.RemoveElementAt(destroyQueue.Length() - 1); + RuleProcessorData *d = static_cast + (destroyQueue.FastElementAt(destroyQueue.Count() - 1)); + destroyQueue.RemoveElementAt(destroyQueue.Count() - 1); if (d->mPreviousSiblingData) { destroyQueue.AppendElement(d->mPreviousSiblingData); @@ -960,7 +961,7 @@ RuleProcessorData::~RuleProcessorData() if (d != this) d->Destroy(); - } while (destroyQueue.Length()); + } while (destroyQueue.Count()); } delete mLanguage; diff --git a/modules/libpref/src/nsPrefBranch.cpp b/modules/libpref/src/nsPrefBranch.cpp index 566f022afd13..e4a3f7ab53aa 100644 --- a/modules/libpref/src/nsPrefBranch.cpp +++ b/modules/libpref/src/nsPrefBranch.cpp @@ -64,7 +64,7 @@ // Definitions struct EnumerateData { const char *parent; - nsTArray *pref_list; + nsVoidArray *pref_list; }; struct PrefCallbackData { @@ -562,11 +562,11 @@ NS_IMETHODIMP nsPrefBranch::DeleteBranch(const char *aStartingAt) NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray) { char** outArray; - const char* theElement; - PRUint32 numPrefs; - PRUint32 dwIndex; + char* theElement; + PRInt32 numPrefs; + PRInt32 dwIndex; EnumerateData ed; - nsAutoTArray prefArray; + nsAutoVoidArray prefArray; NS_ENSURE_ARG_POINTER(aStartingAt); NS_ENSURE_ARG_POINTER(aCount); @@ -587,7 +587,7 @@ NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCou // now that we've built up the list, run the callback on // all the matching elements - numPrefs = prefArray.Length(); + numPrefs = prefArray.Count(); if (numPrefs) { outArray = (char **)nsMemory::Alloc(numPrefs * sizeof(char *)); @@ -597,7 +597,7 @@ NS_IMETHODIMP nsPrefBranch::GetChildList(const char *aStartingAt, PRUint32 *aCou for (dwIndex = 0; dwIndex < numPrefs; ++dwIndex) { // we need to lop off mPrefRoot in case the user is planning to pass this // back to us because if they do we are going to add mPrefRoot again. - theElement = (prefArray.ElementAt(dwIndex)) + mPrefRootLength; + theElement = ((char *)prefArray.ElementAt(dwIndex)) + mPrefRootLength; outArray[dwIndex] = (char *)nsMemory::Clone(theElement, strlen(theElement) + 1); if (!outArray[dwIndex]) { @@ -629,7 +629,7 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser NS_ENSURE_ARG_POINTER(aObserver); if (!mObservers) { - mObservers = new nsAutoTArray(); + mObservers = new nsAutoVoidArray(); if (nsnull == mObservers) return NS_ERROR_OUT_OF_MEMORY; } @@ -669,8 +669,8 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb { const char *pref; PrefCallbackData *pCallback; - PRUint32 count; - PRUint32 i; + PRInt32 count; + PRInt32 i; nsresult rv; nsCAutoString domain; @@ -681,12 +681,12 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb return NS_OK; // need to find the index of observer, so we can remove it from the domain list too - count = mObservers->Length(); + count = mObservers->Count(); if (count == 0) return NS_OK; for (i = 0; i < count; i++) { - pCallback = mObservers->ElementAt(i); + pCallback = (PrefCallbackData *)mObservers->ElementAt(i); if (pCallback) { if (pCallback->pObserver == aObserver) { domain = mObserverDomains[i]; @@ -759,21 +759,21 @@ void nsPrefBranch::freeObserverList(void) if (mObservers) { // unregister the observers - PRUint32 count; + PRInt32 count; - count = mObservers->Length(); + count = mObservers->Count(); if (count > 0) { - PRUint32 i; + PRInt32 i; nsCAutoString domain; for (i = 0; i < count; ++i) { - pCallback = mObservers->ElementAt(i); + pCallback = (PrefCallbackData *)mObservers->ElementAt(i); if (pCallback) { domain = mObserverDomains[i]; // We must pass a fully qualified preference name to remove the callback pref = getPrefName(domain.get()); // can't fail because domain must be valid // Remove this observer from our array so that nobody else can remove // what we're trying to remove right now. - mObservers->ElementAt(i) = nsnull; + mObservers->ReplaceElementAt(nsnull, i); PREF_UnregisterCallback(pref, NotifyObserver, pCallback); if (pCallback->pWeakRef) { NS_RELEASE(pCallback->pWeakRef); @@ -788,7 +788,7 @@ void nsPrefBranch::freeObserverList(void) mObserverDomains.Clear(); } delete mObservers; - mObservers = nsnull; + mObservers = 0; } } @@ -872,7 +872,7 @@ pref_enumChild(PLDHashTable *table, PLDHashEntryHdr *heh, PrefHashEntry *he = static_cast(heh); EnumerateData *d = reinterpret_cast(arg); if (PL_strncmp(he->key, d->parent, PL_strlen(d->parent)) == 0) { - d->pref_list->AppendElement(he->key); + d->pref_list->AppendElement((void*)he->key); } return PL_DHASH_NEXT; } diff --git a/modules/libpref/src/nsPrefBranch.h b/modules/libpref/src/nsPrefBranch.h index 1269c80c181a..07f757c22ee8 100644 --- a/modules/libpref/src/nsPrefBranch.h +++ b/modules/libpref/src/nsPrefBranch.h @@ -49,11 +49,10 @@ #include "nsIRelativeFilePref.h" #include "nsILocalFile.h" #include "nsString.h" +#include "nsVoidArray.h" #include "nsTArray.h" #include "nsWeakReference.h" -struct PrefCallbackData; - class nsPrefBranch : public nsIPrefBranchInternal, public nsISecurityPref, public nsIObserver, @@ -82,7 +81,7 @@ protected: private: PRInt32 mPrefRootLength; - nsAutoTArray *mObservers; + nsAutoVoidArray *mObservers; nsCString mPrefRoot; nsTArray mObserverDomains; PRBool mIsDefault; diff --git a/netwerk/cache/src/nsCacheService.cpp b/netwerk/cache/src/nsCacheService.cpp index beec69271801..e4be27e0469e 100644 --- a/netwerk/cache/src/nsCacheService.cpp +++ b/netwerk/cache/src/nsCacheService.cpp @@ -66,6 +66,7 @@ #include "nsAppDirectoryServiceDefs.h" #include "nsThreadUtils.h" #include "nsProxyRelease.h" +#include "nsVoidArray.h" #include "nsDeleteDir.h" #include "nsIPrivateBrowsingService.h" #include "nsNetCID.h" diff --git a/security/manager/ssl/src/nsKeygenHandler.cpp b/security/manager/ssl/src/nsKeygenHandler.cpp index c01c0efb6ca4..fcf1ac533c35 100644 --- a/security/manager/ssl/src/nsKeygenHandler.cpp +++ b/security/manager/ssl/src/nsKeygenHandler.cpp @@ -53,6 +53,7 @@ extern "C" { } #include "nsProxiedService.h" #include "nsKeygenHandler.h" +#include "nsVoidArray.h" #include "nsIServiceManager.h" #include "nsIDOMHTMLSelectElement.h" #include "nsIContent.h" diff --git a/security/manager/ssl/src/nsKeygenHandler.h b/security/manager/ssl/src/nsKeygenHandler.h index 3211537e402d..0f35f5277ff4 100644 --- a/security/manager/ssl/src/nsKeygenHandler.h +++ b/security/manager/ssl/src/nsKeygenHandler.h @@ -41,6 +41,7 @@ #define _NSKEYGENHANDLER_H_ // Form Processor #include "nsIFormProcessor.h" +#include "nsVoidArray.h" #include "nsTArray.h" nsresult GetSlotWithMechanism(PRUint32 mechanism, diff --git a/tools/trace-malloc/leaksoup.cpp b/tools/trace-malloc/leaksoup.cpp index 319409f7a1c1..4a3ea6d2cab2 100644 --- a/tools/trace-malloc/leaksoup.cpp +++ b/tools/trace-malloc/leaksoup.cpp @@ -40,7 +40,7 @@ #include #include "plhash.h" -#include "nsTArray.h" +#include "nsVoidArray.h" #include "nsQuickSort.h" /* @@ -57,10 +57,10 @@ struct AllocationNode { // Other |AllocationNode| objects whose memory has a pointer to // this object. - nsAutoTArray pointers_to; + nsAutoVoidArray pointers_to; // The reverse. - nsAutoTArray pointers_from; + nsAutoVoidArray pointers_from; // Early on in the algorithm, the pre-order index from a DFS. // Later on, set to the index of the strongly connected component to @@ -195,7 +195,7 @@ int main(int argc, char **argv) // |pointers_to|) and assign the post-order index to |index|. { PRUint32 dfs_index = 0; - nsAutoTArray stack; + nsVoidArray stack; for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) { if (n->reached) { @@ -204,8 +204,9 @@ int main(int argc, char **argv) stack.AppendElement(n); do { - PRUint32 pos = stack.Length() - 1; - AllocationNode *n = stack[pos]; + PRUint32 pos = stack.Count() - 1; + AllocationNode *n = + static_cast(stack[pos]); if (n->reached) { n->index = dfs_index++; stack.RemoveElementAt(pos); @@ -214,14 +215,14 @@ int main(int argc, char **argv) // When doing post-order processing, we have to be // careful not to put reached nodes into the stack. - nsAutoTArray &pt = n->pointers_to; - for (PRInt32 i = pt.Length() - 1; i >= 0; --i) { - if (!pt[i]->reached) { + nsVoidArray &pt = n->pointers_to; + for (PRInt32 i = pt.Count() - 1; i >= 0; --i) { + if (!static_cast(pt[i])->reached) { stack.AppendElement(pt[i]); } } } - } while (stack.Length() > 0); + } while (stack.Count() > 0); } } @@ -247,7 +248,7 @@ int main(int argc, char **argv) for (size_t i = 0; i < count; ++i) { nodes[i].reached = PR_FALSE; } - nsAutoTArray stack; + nsVoidArray stack; for (AllocationNode **sn = sorted_nodes, **sn_end = sorted_nodes + count; sn != sn_end; ++sn) { if ((*sn)->reached) { @@ -257,8 +258,9 @@ int main(int argc, char **argv) // We found a new strongly connected index. stack.AppendElement(*sn); do { - PRUint32 pos = stack.Length() - 1; - AllocationNode *n = stack[pos]; + PRUint32 pos = stack.Count() - 1; + AllocationNode *n = + static_cast(stack[pos]); stack.RemoveElementAt(pos); if (!n->reached) { @@ -266,7 +268,7 @@ int main(int argc, char **argv) n->index = num_sccs; stack.AppendElements(n->pointers_from); } - } while (stack.Length() > 0); + } while (stack.Count() > 0); ++num_sccs; } } @@ -279,7 +281,7 @@ int main(int argc, char **argv) nodes[i].is_root = PR_TRUE; } - nsAutoTArray stack; + nsVoidArray stack; for (AllocationNode *n = nodes, *n_end = nodes+count; n != n_end; ++n) { if (!n->is_root) { continue; @@ -287,16 +289,18 @@ int main(int argc, char **argv) // Loop through pointers_to, and add any that are in a // different SCC to stack: - for (int i = n->pointers_to.Length() - 1; i >= 0; --i) { - AllocationNode *target = n->pointers_to[i]; + for (int i = n->pointers_to.Count() - 1; i >= 0; --i) { + AllocationNode *target = + static_cast(n->pointers_to[i]); if (n->index != target->index) { stack.AppendElement(target); } } - while (stack.Length() > 0) { - PRUint32 pos = stack.Length() - 1; - AllocationNode *n = stack[pos]; + while (stack.Count() > 0) { + PRUint32 pos = stack.Count() - 1; + AllocationNode *n = + static_cast(stack[pos]); stack.RemoveElementAt(pos); if (n->is_root) { @@ -394,11 +398,12 @@ int main(int argc, char **argv) } } - if (n->pointers_from.Length()) { + if (n->pointers_from.Count()) { printf("\nPointers from:\n"); - for (PRUint32 i = 0, i_end = n->pointers_from.Length(); + for (PRUint32 i = 0, i_end = n->pointers_from.Count(); i != i_end; ++i) { - AllocationNode *t = n->pointers_from[i]; + AllocationNode *t = static_cast + (n->pointers_from[i]); const ADLog::Entry *te = t->entry; printf(" %s (Object %d, ", t - nodes, te->type, t - nodes); diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index b6ea6ba86d93..80736937fa9d 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -117,8 +117,25 @@ RequestInfoHashInitEntry(PLDHashTable *table, PLDHashEntryHdr *entry, return PR_TRUE; } + +struct nsListenerInfo { + nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask) + : mWeakListener(aListener), + mNotifyMask(aNotifyMask) + { + } + + // Weak pointer for the nsIWebProgressListener... + nsWeakPtr mWeakListener; + + // Mask indicating which notifications the listener wants to receive. + unsigned long mNotifyMask; +}; + + nsDocLoader::nsDocLoader() : mParent(nsnull), + mListenerInfoList(8), mIsLoadingDocument(PR_FALSE), mIsRestoringDocument(PR_FALSE), mIsFlushingLayout(PR_FALSE) @@ -276,16 +293,16 @@ NS_IMETHODIMP nsDocLoader::Stop(void) { nsresult rv = NS_OK; - PRUint32 count, i; + PRInt32 count, i; PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: Stop() called\n", this)); - count = mChildList.Length(); + count = mChildList.Count(); nsCOMPtr loader; for (i=0; i < count; i++) { - loader = mChildList[i]; + loader = ChildAt(i); if (loader) { (void) loader->Stop(); @@ -352,12 +369,12 @@ nsDocLoader::IsBusy() } /* check its child document loaders... */ - PRUint32 count, i; + PRInt32 count, i; - count = mChildList.Length(); + count = mChildList.Count(); for (i=0; i < count; i++) { - nsIDocumentLoader* loader = mChildList[i]; + nsIDocumentLoader* loader = ChildAt(i); // This is a safe cast, because we only put nsDocLoader objects into the // array @@ -404,6 +421,15 @@ nsDocLoader::Destroy() // Release all the information about network requests... ClearRequestInfoHash(); + // Release all the information about registered listeners... + PRInt32 count = mListenerInfoList.Count(); + for(PRInt32 i = 0; i < count; i++) { + nsListenerInfo *info = + static_cast(mListenerInfoList.ElementAt(i)); + + delete info; + } + mListenerInfoList.Clear(); mListenerInfoList.Compact(); @@ -418,15 +444,15 @@ nsDocLoader::Destroy() void nsDocLoader::DestroyChildren() { - PRUint32 i, count; + PRInt32 i, count; - count = mChildList.Length(); + count = mChildList.Count(); // if the doc loader still has children...we need to enumerate the // children and make them null out their back ptr to the parent doc // loader for (i=0; i < count; i++) { - nsIDocumentLoader* loader = mChildList[i]; + nsIDocumentLoader* loader = ChildAt(i); if (loader) { // This is a safe cast, as we only put nsDocLoader objects into the @@ -886,8 +912,12 @@ nsDocLoader::AddProgressListener(nsIWebProgressListener *aListener, return NS_ERROR_INVALID_ARG; } - rv = mListenerInfoList.AppendElement(nsListenerInfo(listener, aNotifyMask)) ? - NS_OK : NS_ERROR_OUT_OF_MEMORY; + info = new nsListenerInfo(listener, aNotifyMask); + if (!info) { + return NS_ERROR_OUT_OF_MEMORY; + } + + rv = mListenerInfoList.AppendElement(info) ? NS_OK : NS_ERROR_FAILURE; return rv; } @@ -898,8 +928,8 @@ nsDocLoader::RemoveProgressListener(nsIWebProgressListener *aListener) nsListenerInfo* info = GetListenerInfo(aListener); if (info) { - mListenerInfoList.RemoveElementAt(info - mListenerInfoList.Elements()); - rv = NS_OK; + rv = mListenerInfoList.RemoveElement(info) ? NS_OK : NS_ERROR_FAILURE; + delete info; } else { // The listener is not registered! rv = NS_ERROR_FAILURE; @@ -925,12 +955,12 @@ PRInt64 nsDocLoader::GetMaxTotalProgress() { nsInt64 newMaxTotal = 0; - PRUint32 count = mChildList.Length(); + PRInt32 count = mChildList.Count(); nsCOMPtr webProgress; - for (PRUint32 i=0; i < count; i++) + for (PRInt32 i=0; i < count; i++) { nsInt64 individualProgress = 0; - nsIDocumentLoader* docloader = mChildList[i]; + nsIDocumentLoader* docloader = ChildAt(i); if (docloader) { // Cast is safe since all children are nsDocLoader too @@ -1125,20 +1155,28 @@ void nsDocLoader::FireOnProgressChange(nsDocLoader *aLoadInitiator, this, buffer.get(), aProgress, aProgressMax, aTotalProgress, aMaxTotalProgress)); #endif /* DEBUG */ - // First notify any listeners of the new progress info... + /* + * First notify any listeners of the new progress info... + * + * Operate the elements from back to front so that if items get + * get removed from the list it won't affect our iteration + */ nsCOMPtr listener; - nsAutoTObserverArray::EndLimitedIterator iter(mListenerInfoList); + PRInt32 count = mListenerInfoList.Count(); - while (iter.HasMore()) { - nsListenerInfo &info = iter.GetNext(); - if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) { + while (--count >= 0) { + nsListenerInfo *info; + + info = static_cast(mListenerInfoList.SafeElementAt(count)); + if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) { continue; } - listener = do_QueryReferent(info.mWeakListener); + listener = do_QueryReferent(info->mWeakListener); if (!listener) { // the listener went away. gracefully pull it out of the list. - mListenerInfoList.RemoveElementAt(&info - mListenerInfoList.Elements()); + mListenerInfoList.RemoveElementAt(count); + delete info; continue; } @@ -1147,6 +1185,7 @@ void nsDocLoader::FireOnProgressChange(nsDocLoader *aLoadInitiator, PRInt32(aProgress), PRInt32(aProgressMax), PRInt32(aTotalProgress), PRInt32(aMaxTotalProgress)); } + mListenerInfoList.Compact(); // Pass the notification up to the parent... @@ -1192,25 +1231,34 @@ void nsDocLoader::FireOnStateChange(nsIWebProgress *aProgress, NS_ASSERTION(aRequest, "Firing OnStateChange(...) notification with a NULL request!"); - // First notify any listeners of the new state info... + /* + * First notify any listeners of the new state info... + * + * Operate the elements from back to front so that if items get + * get removed from the list it won't affect our iteration + */ nsCOMPtr listener; - nsAutoTObserverArray::EndLimitedIterator iter(mListenerInfoList); + PRInt32 count = mListenerInfoList.Count(); - while (iter.HasMore()) { - nsListenerInfo &info = iter.GetNext(); - if (!(info.mNotifyMask & (aStateFlags >>16))) { + while (--count >= 0) { + nsListenerInfo *info; + + info = static_cast(mListenerInfoList.SafeElementAt(count)); + if (!info || !(info->mNotifyMask & (aStateFlags >>16))) { continue; } - listener = do_QueryReferent(info.mWeakListener); + listener = do_QueryReferent(info->mWeakListener); if (!listener) { // the listener went away. gracefully pull it out of the list. - mListenerInfoList.RemoveElementAt(&info - mListenerInfoList.Elements()); + mListenerInfoList.RemoveElementAt(count); + delete info; continue; } listener->OnStateChange(aProgress, aRequest, aStateFlags, aStatus); } + mListenerInfoList.Compact(); // Pass the notification up to the parent... @@ -1226,25 +1274,34 @@ nsDocLoader::FireOnLocationChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, nsIURI *aUri) { - // First notify any listeners of the new state info... + /* + * First notify any listeners of the new state info... + * + * Operate the elements from back to front so that if items get + * get removed from the list it won't affect our iteration + */ nsCOMPtr listener; - nsAutoTObserverArray::EndLimitedIterator iter(mListenerInfoList); + PRInt32 count = mListenerInfoList.Count(); - while (iter.HasMore()) { - nsListenerInfo &info = iter.GetNext(); - if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) { + while (--count >= 0) { + nsListenerInfo *info; + + info = static_cast(mListenerInfoList.SafeElementAt(count)); + if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) { continue; } - listener = do_QueryReferent(info.mWeakListener); + listener = do_QueryReferent(info->mWeakListener); if (!listener) { // the listener went away. gracefully pull it out of the list. - mListenerInfoList.RemoveElementAt(&info - mListenerInfoList.Elements()); + mListenerInfoList.RemoveElementAt(count); + delete info; continue; } listener->OnLocationChange(aWebProgress, aRequest, aUri); } + mListenerInfoList.Compact(); // Pass the notification up to the parent... @@ -1259,27 +1316,35 @@ nsDocLoader::FireOnStatusChange(nsIWebProgress* aWebProgress, nsresult aStatus, const PRUnichar* aMessage) { - // First notify any listeners of the new state info... + /* + * First notify any listeners of the new state info... + * + * Operate the elements from back to front so that if items get + * get removed from the list it won't affect our iteration + */ nsCOMPtr listener; - nsAutoTObserverArray::EndLimitedIterator iter(mListenerInfoList); + PRInt32 count = mListenerInfoList.Count(); - while (iter.HasMore()) { - nsListenerInfo &info = iter.GetNext(); - if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) { + while (--count >= 0) { + nsListenerInfo *info; + + info = static_cast(mListenerInfoList.SafeElementAt(count)); + if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) { continue; } - listener = do_QueryReferent(info.mWeakListener); + listener = do_QueryReferent(info->mWeakListener); if (!listener) { // the listener went away. gracefully pull it out of the list. - mListenerInfoList.RemoveElementAt(&info - mListenerInfoList.Elements()); + mListenerInfoList.RemoveElementAt(count); + delete info; continue; } listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); } mListenerInfoList.Compact(); - + // Pass the notification up to the parent... if (mParent) { mParent->FireOnStatusChange(aWebProgress, aRequest, aStatus, aMessage); @@ -1297,26 +1362,32 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress, * false if the refresh should be blocked. * * First notify any listeners of the refresh attempt... + * + * Iterate the elements from back to front so that if items + * get removed from the list it won't affect our iteration */ PRBool allowRefresh = PR_TRUE; - nsAutoTObserverArray::EndLimitedIterator iter(mListenerInfoList); + PRInt32 count = mListenerInfoList.Count(); - while (iter.HasMore()) { - nsListenerInfo &info = iter.GetNext(); - if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) { + while (--count >= 0) { + nsListenerInfo *info; + + info = static_cast(mListenerInfoList.SafeElementAt(count)); + if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) { continue; } nsCOMPtr listener = - do_QueryReferent(info.mWeakListener); + do_QueryReferent(info->mWeakListener); if (!listener) { // the listener went away. gracefully pull it out of the list. - mListenerInfoList.RemoveElementAt(&info - mListenerInfoList.Elements()); + mListenerInfoList.RemoveElementAt(count); + delete info; continue; } nsCOMPtr listener2 = - do_QueryReferent(info.mWeakListener); + do_QueryReferent(info->mWeakListener); if (!listener2) continue; @@ -1328,6 +1399,7 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress, allowRefresh = allowRefresh && listenerAllowedRefresh; } + mListenerInfoList.Compact(); // Pass the notification up to the parent... @@ -1339,19 +1411,23 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress, return allowRefresh; } -nsDocLoader::nsListenerInfo * +nsListenerInfo * nsDocLoader::GetListenerInfo(nsIWebProgressListener *aListener) { - PRUint32 i, count; + PRInt32 i, count; nsListenerInfo *info; nsCOMPtr listener1 = do_QueryInterface(aListener); - count = mListenerInfoList.Length(); + count = mListenerInfoList.Count(); for (i=0; i listener2 = do_QueryReferent(info->mWeakListener); - if (listener1 == listener2) - return info; + info = static_cast(mListenerInfoList.SafeElementAt(i)); + + NS_ASSERTION(info, "There should NEVER be a null listener in the list"); + if (info) { + nsCOMPtr listener2 = do_QueryReferent(info->mWeakListener); + if (listener1 == listener2) + return info; + } } return nsnull; } @@ -1478,25 +1554,34 @@ NS_IMETHODIMP nsDocLoader::OnSecurityChange(nsISupports * aContext, nsCOMPtr request = do_QueryInterface(aContext); nsIWebProgress* webProgress = static_cast(this); - // First notify any listeners of the new state info... + /* + * First notify any listeners of the new state info... + * + * Operate the elements from back to front so that if items get + * get removed from the list it won't affect our iteration + */ nsCOMPtr listener; - nsAutoTObserverArray::EndLimitedIterator iter(mListenerInfoList); + PRInt32 count = mListenerInfoList.Count(); - while (iter.HasMore()) { - nsListenerInfo &info = iter.GetNext(); - if (!(info.mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) { + while (--count >= 0) { + nsListenerInfo *info; + + info = static_cast(mListenerInfoList.SafeElementAt(count)); + if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) { continue; } - listener = do_QueryReferent(info.mWeakListener); + listener = do_QueryReferent(info->mWeakListener); if (!listener) { // the listener went away. gracefully pull it out of the list. - mListenerInfoList.RemoveElementAt(&info - mListenerInfoList.Elements()); + mListenerInfoList.RemoveElementAt(count); + delete info; continue; } listener->OnSecurityChange(webProgress, request, aState); } + mListenerInfoList.Compact(); // Pass the notification up to the parent... @@ -1534,11 +1619,11 @@ NS_IMETHODIMP nsDocLoader::SetPriority(PRInt32 aPriority) if (p) p->SetPriority(aPriority); - PRUint32 count = mChildList.Length(); + PRInt32 count = mChildList.Count(); nsDocLoader *loader; - for (PRUint32 i=0; i < count; i++) { - loader = static_cast(mChildList[i]); + for (PRInt32 i=0; i < count; i++) { + loader = static_cast(ChildAt(i)); if (loader) { loader->SetPriority(aPriority); } @@ -1556,11 +1641,11 @@ NS_IMETHODIMP nsDocLoader::AdjustPriority(PRInt32 aDelta) if (p) p->AdjustPriority(aDelta); - PRUint32 count = mChildList.Length(); + PRInt32 count = mChildList.Count(); nsDocLoader *loader; - for (PRUint32 i=0; i < count; i++) { - loader = static_cast(mChildList[i]); + for (PRInt32 i=0; i < count; i++) { + loader = static_cast(ChildAt(i)); if (loader) { loader->AdjustPriority(aDelta); } diff --git a/uriloader/base/nsDocLoader.h b/uriloader/base/nsDocLoader.h index ffb7a6e18117..0d7df3624035 100644 --- a/uriloader/base/nsDocLoader.h +++ b/uriloader/base/nsDocLoader.h @@ -48,8 +48,7 @@ #include "nsWeakReference.h" #include "nsILoadGroup.h" #include "nsCOMArray.h" -#include "nsTPtrArray.h" -#include "nsTObserverArray.h" +#include "nsVoidArray.h" #include "nsString.h" #include "nsIChannel.h" #include "nsIProgressEventSink.h" @@ -63,6 +62,7 @@ #include "pldhash.h" struct nsRequestInfo; +struct nsListenerInfo; /**************************************************************************** * nsDocLoader implementation... @@ -128,20 +128,6 @@ public: nsresult AddChildLoader(nsDocLoader* aChild); nsDocLoader* GetParent() const { return mParent; } - struct nsListenerInfo { - nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask) - : mWeakListener(aListener), - mNotifyMask(aNotifyMask) - { - } - - // Weak pointer for the nsIWebProgressListener... - nsWeakPtr mWeakListener; - - // Mask indicating which notifications the listener wants to receive. - unsigned long mNotifyMask; - }; - protected: virtual ~nsDocLoader(); @@ -152,6 +138,14 @@ protected: void Destroy(); virtual void DestroyChildren(); + nsIDocumentLoader* ChildAt(PRInt32 i) { + return static_cast(mChildList[i]); + } + + nsIDocumentLoader* SafeChildAt(PRInt32 i) { + return static_cast(mChildList.SafeElementAt(i)); + } + void FireOnProgressChange(nsDocLoader* aLoadInitiator, nsIRequest *request, PRInt64 aProgress, @@ -222,11 +216,11 @@ protected: nsDocLoader* mParent; // [WEAK] - nsAutoTObserverArray mListenerInfoList; + nsVoidArray mListenerInfoList; - nsCOMPtr mLoadGroup; + nsCOMPtr mLoadGroup; // We hold weak refs to all our kids - nsTPtrArray mChildList; + nsVoidArray mChildList; // The following member variables are related to the new nsIWebProgress // feedback interfaces that travis cooked up. diff --git a/view/src/nsViewManager.cpp b/view/src/nsViewManager.cpp index 10254e2a094e..5252dd3508ef 100644 --- a/view/src/nsViewManager.cpp +++ b/view/src/nsViewManager.cpp @@ -148,10 +148,11 @@ nsViewManager::PostInvalidateEvent() #undef DEBUG_MOUSE_LOCATION +PRInt32 nsViewManager::mVMCount = 0; nsIRenderingContext* nsViewManager::gCleanupContext = nsnull; // Weakly held references to all of the view managers -nsTArray* nsViewManager::gViewManagers = nsnull; +nsVoidArray* nsViewManager::gViewManagers = nsnull; PRUint32 nsViewManager::gLastUserEventTime = 0; nsViewManager::nsViewManager() @@ -160,8 +161,9 @@ nsViewManager::nsViewManager() , mRootViewManager(this) { if (gViewManagers == nsnull) { + NS_ASSERTION(mVMCount == 0, "View Manager count is incorrect"); // Create an array to hold a list of view managers - gViewManagers = new nsTArray; + gViewManagers = new nsVoidArray; } if (gCleanupContext == nsnull) { @@ -173,7 +175,7 @@ nsViewManager::nsViewManager() gViewManagers->AppendElement(this); - if (gViewManagers->Length() == 1) { + if (++mVMCount == 1) { NS_AddFocusSuppressorCallback(&nsViewManager::SuppressFocusEvents); } // NOTE: we use a zeroing operator new, so all data members are @@ -203,13 +205,16 @@ nsViewManager::~nsViewManager() mRootScrollable = nsnull; + NS_ASSERTION((mVMCount > 0), "underflow of viewmanagers"); + --mVMCount; + #ifdef DEBUG PRBool removed = #endif gViewManagers->RemoveElement(this); - NS_ASSERTION(removed, "Viewmanager instance was not in the global list of viewmanagers"); + NS_ASSERTION(removed, "Viewmanager instance not was not in the global list of viewmanagers"); - if (gViewManagers->IsEmpty()) { + if (0 == mVMCount) { // There aren't any more view managers so // release the global array of view managers @@ -2167,9 +2172,9 @@ nsViewManager::FlushPendingInvalidates() mRefreshEnabled = PR_FALSE; ++mUpdateBatchCnt; - PRUint32 index; - for (index = 0; index < gViewManagers->Length(); index++) { - nsViewManager* vm = gViewManagers->ElementAt(index); + PRInt32 index; + for (index = 0; index < mVMCount; index++) { + nsViewManager* vm = (nsViewManager*)gViewManagers->ElementAt(index); if (vm->RootViewManager() == this) { // One of our kids nsIViewObserver* observer = vm->GetViewObserver(); diff --git a/view/src/nsViewManager.h b/view/src/nsViewManager.h index c01aad3882c7..c34ed20a93a2 100644 --- a/view/src/nsViewManager.h +++ b/view/src/nsViewManager.h @@ -43,7 +43,7 @@ #include "nsITimer.h" #include "prtime.h" #include "prinrval.h" -#include "nsTArray.h" +#include "nsVoidArray.h" #include "nsThreadUtils.h" #include "nsIScrollableView.h" #include "nsIRegion.h" @@ -456,12 +456,13 @@ private: PRPackedBool mInScroll; //from here to public should be static and locked... MMP + static PRInt32 mVMCount; //number of viewmanagers //Rendering context used to cleanup the blending buffers static nsIRenderingContext* gCleanupContext; //list of view managers - static nsTArray *gViewManagers; + static nsVoidArray *gViewManagers; void PostInvalidateEvent(); diff --git a/xpcom/glue/nsTObserverArray.h b/xpcom/glue/nsTObserverArray.h index 03844944c9db..7d4ccb006c52 100644 --- a/xpcom/glue/nsTObserverArray.h +++ b/xpcom/glue/nsTObserverArray.h @@ -123,20 +123,6 @@ class nsAutoTObserverArray : protected nsTObserverArray_base { return mArray.IsEmpty(); } - // This method provides direct access to the array elements. - // @return A pointer to the first element of the array. If the array is - // empty, then this pointer must not be dereferenced. - elem_type* Elements() { - return mArray.Elements(); - } - - // This method provides direct, readonly access to the array elements. - // @return A pointer to the first element of the array. If the array is - // empty, then this pointer must not be dereferenced. - const elem_type* Elements() const { - return mArray.Elements(); - } - // This method provides direct access to the i'th element of the array. // The given index must be within the array bounds. // @param i The index of an element in the array. @@ -257,11 +243,6 @@ class nsAutoTObserverArray : protected nsTObserverArray_base { ClearIterators(); } - // Compact the array to minimize the memory it uses - void Compact() { - mArray.Compact(); - } - // // Iterators // diff --git a/xpinstall/src/nsXPITriggerInfo.h b/xpinstall/src/nsXPITriggerInfo.h index 78a12eaab9d0..3ec47113cf2b 100644 --- a/xpinstall/src/nsXPITriggerInfo.h +++ b/xpinstall/src/nsXPITriggerInfo.h @@ -41,7 +41,7 @@ #define nsXPITriggerInfo_h #include "nsString.h" -#include "nsTArray.h" +#include "nsVoidArray.h" #include "nsCOMPtr.h" #include "nsISupportsUtils.h" #include "nsILocalFile.h" @@ -113,14 +113,14 @@ class nsXPITriggerInfo ~nsXPITriggerInfo(); void Add( nsXPITriggerItem *aItem ) - { if ( aItem ) mItems.AppendElement( aItem ); } + { if ( aItem ) mItems.AppendElement( (void*)aItem ); } nsXPITriggerItem* Get( PRUint32 aIndex ) - { return mItems.ElementAt(aIndex);} + { return (nsXPITriggerItem*)mItems.ElementAt(aIndex);} void SaveCallback( JSContext *aCx, jsval aVal ); - PRUint32 Size() { return mItems.Length(); } + PRUint32 Size() { return mItems.Count(); } void SendStatus(const PRUnichar* URL, PRInt32 status); @@ -128,7 +128,7 @@ class nsXPITriggerInfo private: - nsTArray mItems; + nsVoidArray mItems; JSContext *mCx; nsCOMPtr mContextWrapper; jsval mCbval;