From 56c104a8a309054a7ccba6ea5fdcd853cce8ab84 Mon Sep 17 00:00:00 2001 From: "vidur%netscape.com" Date: Thu, 9 Sep 1999 23:53:55 +0000 Subject: [PATCH] Fixed circular references. nsDocLoader now supports weak references to it. Init() method moves out of constructor. nsDocLoader now has Destroy() method to start breakdown process. --- docshell/base/nsWebShell.cpp | 1 + uriloader/base/nsDocLoader.cpp | 40 +++++++++++++++++++++-------- webshell/public/nsIDocumentLoader.h | 2 ++ webshell/src/nsDocLoader.cpp | 40 +++++++++++++++++++++-------- webshell/src/nsWebShell.cpp | 1 + 5 files changed, 62 insertions(+), 22 deletions(-) diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index 6105ece53832..f4c99c30f4a3 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -1267,6 +1267,7 @@ nsWebShell::Destroy() // Stop any URLs that are currently being loaded... Stop(); + mDocLoader->Destroy(); SetContainer(nsnull); SetObserver(nsnull); diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp index c2b7bee2fdec..a68ac231ef7f 100644 --- a/uriloader/base/nsDocLoader.cpp +++ b/uriloader/base/nsDocLoader.cpp @@ -58,6 +58,8 @@ #include "prlog.h" #include "prprf.h" +#include "nsWeakReference.h" + #include "nsIStreamConverterService.h" #include "nsIStreamConverter.h" static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID); @@ -205,7 +207,8 @@ protected: class nsDocLoaderImpl : public nsIDocumentLoader, public nsIStreamObserver, - public nsILoadGroupListenerFactory + public nsILoadGroupListenerFactory, + public nsSupportsWeakReference { public: @@ -246,6 +249,7 @@ public: NS_IMETHOD GetContainer(nsIContentViewerContainer** aResult); NS_IMETHOD GetContentViewerContainer(PRUint32 aDocumentID, nsIContentViewerContainer** aResult); + NS_IMETHOD Destroy(); // nsILoadGroup interface... NS_IMETHOD CreateURL(nsIURI** aInstancePtrResult, @@ -362,13 +366,6 @@ nsDocLoaderImpl::nsDocLoaderImpl() mIsLoadingDocument = PR_FALSE; - // XXX I wanted to pull this initialization code out of this constructor - // because it could fail... but the web shell uses this implementation - // as a service too. Since it's a service, it really can't have any - // initialization. We're sort of screwed here. - nsresult rv = Init(); - NS_ASSERTION(NS_SUCCEEDED(rv), "nsDocLoaderImpl::Init failed"); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: created.\n", this)); } @@ -456,6 +453,11 @@ nsDocLoaderImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_OK; } #endif // NECKO + if (aIID.Equals(nsCOMTypeInfo::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsISupportsWeakReference*,this); + NS_ADDREF_THIS(); + return NS_OK; + } return NS_NOINTERFACE; } @@ -480,12 +482,16 @@ nsDocLoaderImpl::CreateDocumentLoader(nsIDocumentLoader** anInstance) rv = newLoader->QueryInterface(kIDocumentLoaderIID, (void**)anInstance); if (NS_SUCCEEDED(rv)) { + // Initialize now that we have a reference + rv = newLoader->Init(); + if (NS_SUCCEEDED(rv)) { #ifdef NECKO - AddChildGroup(newLoader->GetLoadGroup()); + AddChildGroup(newLoader->GetLoadGroup()); #else - AddChildGroup(newLoader); + AddChildGroup(newLoader); #endif - newLoader->SetParent(this); + newLoader->SetParent(this); + } } done: @@ -778,6 +784,15 @@ nsDocLoaderImpl::GetContentViewerContainer(PRUint32 aDocumentID, return rv; } +NS_IMETHODIMP +nsDocLoaderImpl::Destroy() +{ + Stop(); + NS_IF_RELEASE(mDocumentChannel); + + return NS_OK; +} + NS_IMETHODIMP nsDocLoaderImpl::CreateURL(nsIURI** aInstancePtrResult, nsIURI* aBaseURL, @@ -2302,6 +2317,9 @@ nsDocLoaderImpl::Create(nsISupports *aOuter, const nsIID &aIID, void **aResult) NS_ADDREF(inst); rv = inst->QueryInterface(aIID, aResult); + if (NS_SUCCEEDED(rv)) { + rv = inst->Init(); + } NS_RELEASE(inst); done: diff --git a/webshell/public/nsIDocumentLoader.h b/webshell/public/nsIDocumentLoader.h index 0a879e3778d7..4e565a6961ed 100644 --- a/webshell/public/nsIDocumentLoader.h +++ b/webshell/public/nsIDocumentLoader.h @@ -131,6 +131,8 @@ public: NS_IMETHOD GetContainer(nsIContentViewerContainer** aResult) = 0; NS_IMETHOD GetContentViewerContainer(PRUint32 aDocumentID, nsIContentViewerContainer** aResult) = 0; + + NS_IMETHOD Destroy() = 0; }; /* 057b04d0-0ccf-11d2-beba-00805f8a66dc */ diff --git a/webshell/src/nsDocLoader.cpp b/webshell/src/nsDocLoader.cpp index c2b7bee2fdec..a68ac231ef7f 100644 --- a/webshell/src/nsDocLoader.cpp +++ b/webshell/src/nsDocLoader.cpp @@ -58,6 +58,8 @@ #include "prlog.h" #include "prprf.h" +#include "nsWeakReference.h" + #include "nsIStreamConverterService.h" #include "nsIStreamConverter.h" static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID); @@ -205,7 +207,8 @@ protected: class nsDocLoaderImpl : public nsIDocumentLoader, public nsIStreamObserver, - public nsILoadGroupListenerFactory + public nsILoadGroupListenerFactory, + public nsSupportsWeakReference { public: @@ -246,6 +249,7 @@ public: NS_IMETHOD GetContainer(nsIContentViewerContainer** aResult); NS_IMETHOD GetContentViewerContainer(PRUint32 aDocumentID, nsIContentViewerContainer** aResult); + NS_IMETHOD Destroy(); // nsILoadGroup interface... NS_IMETHOD CreateURL(nsIURI** aInstancePtrResult, @@ -362,13 +366,6 @@ nsDocLoaderImpl::nsDocLoaderImpl() mIsLoadingDocument = PR_FALSE; - // XXX I wanted to pull this initialization code out of this constructor - // because it could fail... but the web shell uses this implementation - // as a service too. Since it's a service, it really can't have any - // initialization. We're sort of screwed here. - nsresult rv = Init(); - NS_ASSERTION(NS_SUCCEEDED(rv), "nsDocLoaderImpl::Init failed"); - PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader:%p: created.\n", this)); } @@ -456,6 +453,11 @@ nsDocLoaderImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr) return NS_OK; } #endif // NECKO + if (aIID.Equals(nsCOMTypeInfo::GetIID())) { + *aInstancePtr = NS_STATIC_CAST(nsISupportsWeakReference*,this); + NS_ADDREF_THIS(); + return NS_OK; + } return NS_NOINTERFACE; } @@ -480,12 +482,16 @@ nsDocLoaderImpl::CreateDocumentLoader(nsIDocumentLoader** anInstance) rv = newLoader->QueryInterface(kIDocumentLoaderIID, (void**)anInstance); if (NS_SUCCEEDED(rv)) { + // Initialize now that we have a reference + rv = newLoader->Init(); + if (NS_SUCCEEDED(rv)) { #ifdef NECKO - AddChildGroup(newLoader->GetLoadGroup()); + AddChildGroup(newLoader->GetLoadGroup()); #else - AddChildGroup(newLoader); + AddChildGroup(newLoader); #endif - newLoader->SetParent(this); + newLoader->SetParent(this); + } } done: @@ -778,6 +784,15 @@ nsDocLoaderImpl::GetContentViewerContainer(PRUint32 aDocumentID, return rv; } +NS_IMETHODIMP +nsDocLoaderImpl::Destroy() +{ + Stop(); + NS_IF_RELEASE(mDocumentChannel); + + return NS_OK; +} + NS_IMETHODIMP nsDocLoaderImpl::CreateURL(nsIURI** aInstancePtrResult, nsIURI* aBaseURL, @@ -2302,6 +2317,9 @@ nsDocLoaderImpl::Create(nsISupports *aOuter, const nsIID &aIID, void **aResult) NS_ADDREF(inst); rv = inst->QueryInterface(aIID, aResult); + if (NS_SUCCEEDED(rv)) { + rv = inst->Init(); + } NS_RELEASE(inst); done: diff --git a/webshell/src/nsWebShell.cpp b/webshell/src/nsWebShell.cpp index 6105ece53832..f4c99c30f4a3 100644 --- a/webshell/src/nsWebShell.cpp +++ b/webshell/src/nsWebShell.cpp @@ -1267,6 +1267,7 @@ nsWebShell::Destroy() // Stop any URLs that are currently being loaded... Stop(); + mDocLoader->Destroy(); SetContainer(nsnull); SetObserver(nsnull);