From 038cdde0c281e233e802e6f1135cebcf109ebf2d Mon Sep 17 00:00:00 2001 From: "valeski%netscape.com" Date: Wed, 31 Jan 2001 21:02:08 +0000 Subject: [PATCH] r=ccarlen, sr=rpotts. 65925. making webprogress implementation store weak refs to listeners. git-svn-id: svn://10.0.0.236/trunk@85867 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/uriloader/base/nsDocLoader.cpp | 135 +++++++++++++++---------- mozilla/uriloader/base/nsDocLoader.h | 2 +- 2 files changed, 83 insertions(+), 54 deletions(-) diff --git a/mozilla/uriloader/base/nsDocLoader.cpp b/mozilla/uriloader/base/nsDocLoader.cpp index a5ec8c215c0..223b4062983 100644 --- a/mozilla/uriloader/base/nsDocLoader.cpp +++ b/mozilla/uriloader/base/nsDocLoader.cpp @@ -34,6 +34,7 @@ #include "nsIURL.h" #include "nsCOMPtr.h" #include "nsCom.h" +#include "nsWeakPtr.h" #include "nsIDOMWindow.h" @@ -139,8 +140,9 @@ nsDocLoaderImpl::Init() ("DocLoader:%p: load group %x.\n", this, mLoadGroup.get())); rv = NS_NewISupportsArray(getter_AddRefs(mChildList)); - - return rv; + if (NS_FAILED(rv)) return rv; + + return NS_NewISupportsArray(getter_AddRefs(mListenerList)); } NS_IMETHODIMP nsDocLoaderImpl::ClearParentDocLoader() @@ -958,10 +960,13 @@ nsDocLoaderImpl::AddProgressListener(nsIWebProgressListener *aListener) { nsresult rv; - if (mListenerList.IndexOf(aListener) == -1) { + nsWeakPtr listener = getter_AddRefs(NS_GetWeakReference(aListener)); + if (!listener) return NS_ERROR_INVALID_ARG; + + if (mListenerList->IndexOf(listener) == -1) { // XXX this method incorrectly returns a bool - rv = mListenerList.AppendElement(aListener) ? NS_OK : NS_ERROR_FAILURE; + rv = mListenerList->AppendElement(listener) ? NS_OK : NS_ERROR_FAILURE; } else { // The listener is already in the list... rv = NS_ERROR_FAILURE; @@ -972,12 +977,11 @@ nsDocLoaderImpl::AddProgressListener(nsIWebProgressListener *aListener) NS_IMETHODIMP nsDocLoaderImpl::RemoveProgressListener(nsIWebProgressListener *aListener) { - nsresult rv; + nsWeakPtr listener = getter_AddRefs(NS_GetWeakReference(aListener)); + if (!listener) return NS_ERROR_INVALID_ARG; // XXX this method incorrectly returns a bool - rv = mListenerList.RemoveElement(aListener) ? NS_OK : NS_ERROR_FAILURE; - - return rv; + return mListenerList->RemoveElement(listener) ? NS_OK : NS_ERROR_FAILURE; } NS_IMETHODIMP @@ -1181,7 +1185,7 @@ void nsDocLoaderImpl::FireOnProgressChange(nsDocLoaderImpl *aLoadInitiator, PRInt32 aTotalProgress, PRInt32 aMaxTotalProgress) { - PRInt32 count; + PRUint32 count; if (mIsLoadingDocument) { mCurrentTotalProgress += aProgressDelta; @@ -1206,16 +1210,19 @@ void nsDocLoaderImpl::FireOnProgressChange(nsDocLoaderImpl *aLoadInitiator, * Operate the elements from back to front so that if items get * get removed from the list it won't affect our iteration */ - count = mListenerList.Count(); + (void)mListenerList->Count(&count); while (count > 0) { - nsIWebProgressListener *listener; + nsCOMPtr supports; + nsresult rv = mListenerList->GetElementAt(--count, getter_AddRefs(supports)); + if (NS_FAILED(rv)) return; + nsWeakPtr weakPtr = do_QueryInterface(supports); - listener = NS_STATIC_CAST(nsIWebProgressListener*, - mListenerList.ElementAt(--count)); - - NS_ASSERTION(listener, "NULL listener found in list."); - if (! listener) { - continue; + nsCOMPtr listener; + listener = do_QueryReferent(weakPtr); + if (!listener) { + // the listener went away. gracefully pull it out of the list. + mListenerList->RemoveElementAt(count); + continue; } listener->OnProgressChange(aLoadInitiator,aChannel, @@ -1223,6 +1230,8 @@ void nsDocLoaderImpl::FireOnProgressChange(nsDocLoaderImpl *aLoadInitiator, aTotalProgress, aMaxTotalProgress); } + mListenerList->Compact(); + // Pass the notification up to the parent... if (mParent) { mParent->FireOnProgressChange(aLoadInitiator, aChannel, @@ -1239,7 +1248,7 @@ void nsDocLoaderImpl::FireOnStateChange(nsIWebProgress *aProgress, PRInt32 aStateFlags, nsresult aStatus) { - PRInt32 count; + PRUint32 count; // // Remove the STATE_IS_NETWORK bit if necessary. @@ -1270,21 +1279,26 @@ void nsDocLoaderImpl::FireOnStateChange(nsIWebProgress *aProgress, * Operate the elements from back to front so that if items get * get removed from the list it won't affect our iteration */ - count = mListenerList.Count(); + (void)mListenerList->Count(&count); while (count > 0) { - nsIWebProgressListener *listener; + nsCOMPtr supports; + nsresult rv = mListenerList->GetElementAt(--count, getter_AddRefs(supports)); + if (NS_FAILED(rv)) return; + nsWeakPtr weakPtr = do_QueryInterface(supports); - listener = NS_STATIC_CAST(nsIWebProgressListener*, - mListenerList.ElementAt(--count)); - - NS_ASSERTION(listener, "NULL listener found in list."); - if (! listener) { - continue; + nsCOMPtr listener; + listener = do_QueryReferent(weakPtr); + if (!listener) { + // the listener went away, gracefully pull it out of the list. + mListenerList->RemoveElementAt(count); + continue; } listener->OnStateChange(aProgress, aRequest, aStateFlags, aStatus); } + mListenerList->Compact(); + // Pass the notification up to the parent... if (mParent) { mParent->FireOnStateChange(aProgress, aRequest, aStateFlags, aStatus); @@ -1298,24 +1312,28 @@ nsDocLoaderImpl::FireOnLocationChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest, nsIURI *aUri) { - PRInt32 count; + PRUint32 count; - - count = mListenerList.Count(); + (void)mListenerList->Count(&count); while (count > 0) { - nsIWebProgressListener *listener; + nsCOMPtr supports; + nsresult rv = mListenerList->GetElementAt(--count, getter_AddRefs(supports)); + if (NS_FAILED(rv)) return rv; + nsWeakPtr weakPtr = do_QueryInterface(supports); - listener = NS_STATIC_CAST(nsIWebProgressListener*, - mListenerList.ElementAt(--count)); - - NS_ASSERTION(listener, "NULL listener found in list."); - if (! listener) { - continue; + nsCOMPtr listener; + listener = do_QueryReferent(weakPtr); + if (!listener) { + // the listener went away. gracefully pull it out of the list. + mListenerList->RemoveElementAt(count); + continue; } listener->OnLocationChange(aWebProgress, aRequest, aUri); } + mListenerList->Compact(); + return NS_OK; } @@ -1325,22 +1343,26 @@ nsDocLoaderImpl::FireOnStatusChange(nsIWebProgress* aWebProgress, nsresult aStatus, const PRUnichar* aMessage) { - PRInt32 count; + PRUint32 count; - count = mListenerList.Count(); + (void)mListenerList->Count(&count); while (count > 0) { - nsIWebProgressListener *listener; + nsCOMPtr supports; + nsresult rv = mListenerList->GetElementAt(--count, getter_AddRefs(supports)); + if (NS_FAILED(rv)) return rv; + nsWeakPtr weakPtr = do_QueryInterface(supports); - listener = NS_STATIC_CAST(nsIWebProgressListener*, - mListenerList.ElementAt(--count)); - - NS_ASSERTION(listener, "NULL listener found in list."); - if (! listener) { - continue; + nsCOMPtr listener; + listener = do_QueryReferent(weakPtr); + if (!listener) { + // the listener went away. gracefully pull it out of the list. + mListenerList->RemoveElementAt(count); + continue; } listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage); } + mListenerList->Compact(); return NS_OK; } @@ -1475,20 +1497,27 @@ NS_IMETHODIMP nsDocLoaderImpl::OnSecurityChange(nsISupports * aContext, nsCOMPtr request = do_QueryInterface(aContext); nsIWebProgress* webProgress = NS_STATIC_CAST(nsIWebProgress*, this); - PRInt32 count = mListenerList.Count(); + PRUint32 count; + (void)mListenerList->Count(&count); + while (count > 0) { - nsIWebProgressListener *listener; + nsCOMPtr supports; + nsresult rv = mListenerList->GetElementAt(--count, getter_AddRefs(supports)); + if (NS_FAILED(rv)) return rv; + nsWeakPtr weakPtr = do_QueryInterface(supports); - listener = NS_STATIC_CAST(nsIWebProgressListener*, - mListenerList.ElementAt(--count)); - - NS_ASSERTION(listener, "NULL listener found in list."); - if (! listener) { - continue; + nsCOMPtr listener; + listener = do_QueryReferent(weakPtr); + if (!listener) { + // the listener went away. gracefully pull it out of the list. + mListenerList->RemoveElementAt(count); + continue; } listener->OnSecurityChange(webProgress, request, state); } + mListenerList->Compact(); + // Pass the notification up to the parent... if (mParent) { mParent->OnSecurityChange(aContext, state); diff --git a/mozilla/uriloader/base/nsDocLoader.h b/mozilla/uriloader/base/nsDocLoader.h index 3b613aea61f..819e874b3aa 100644 --- a/mozilla/uriloader/base/nsDocLoader.h +++ b/mozilla/uriloader/base/nsDocLoader.h @@ -135,7 +135,7 @@ protected: nsCOMPtr mDocumentChannel; // [OWNER] ???compare with document nsVoidArray mDocObservers; - nsVoidArray mListenerList; + nsCOMPtr mListenerList; nsISupports* mContainer; // [WEAK] it owns me! nsDocLoaderImpl* mParent; // [WEAK]