From f5fb8ddaff7f9f374dd3ec1ededd65bc07a8223d Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Fri, 12 Aug 2005 22:53:22 +0000 Subject: [PATCH] Make nsIChannel implementations follow the rules that prevent them from leaking due to cycles with their notification callbacks. b=303043 r=biesi sr=darin git-svn-id: svn://10.0.0.236/trunk@177663 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/html/document/src/nsWyciwygChannel.cpp | 5 +++++ mozilla/directory/xpcom/base/src/nsLDAPChannel.cpp | 8 ++++++++ mozilla/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp | 5 +++++ mozilla/extensions/datetime/nsDateTimeChannel.cpp | 5 +++++ mozilla/extensions/finger/nsFingerChannel.cpp | 5 +++++ mozilla/mailnews/base/util/nsMsgProtocol.cpp | 4 ++++ mozilla/modules/libjar/nsJARChannel.cpp | 5 +++++ .../modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp | 4 ++++ .../modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp | 3 +++ .../modules/libpr0n/decoders/icon/win/nsIconChannel.cpp | 3 +++ mozilla/netwerk/base/public/nsIChannel.idl | 3 +++ mozilla/netwerk/base/src/nsInputStreamChannel.cpp | 5 +++++ mozilla/netwerk/protocol/data/src/nsDataChannel.cpp | 3 +++ mozilla/netwerk/protocol/file/src/nsFileChannel.cpp | 5 +++++ mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp | 5 +++++ mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp | 6 ++++++ .../uriloader/exthandler/nsExternalProtocolHandler.cpp | 9 +++++++-- 17 files changed, 81 insertions(+), 2 deletions(-) diff --git a/mozilla/content/html/document/src/nsWyciwygChannel.cpp b/mozilla/content/html/document/src/nsWyciwygChannel.cpp index 7dd3702cc6e..7a92295d2f0 100644 --- a/mozilla/content/html/document/src/nsWyciwygChannel.cpp +++ b/mozilla/content/html/document/src/nsWyciwygChannel.cpp @@ -503,6 +503,11 @@ nsWyciwygChannel::OnStopRequest(nsIRequest *request, nsISupports *ctx, nsresult CloseCacheEntry(mStatus); mPump = 0; mIsPending = PR_FALSE; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/directory/xpcom/base/src/nsLDAPChannel.cpp b/mozilla/directory/xpcom/base/src/nsLDAPChannel.cpp index 7d029e4082c..3aa09ced3b9 100644 --- a/mozilla/directory/xpcom/base/src/nsLDAPChannel.cpp +++ b/mozilla/directory/xpcom/base/src/nsLDAPChannel.cpp @@ -236,6 +236,10 @@ nsLDAPChannel::Cancel(nsresult aStatus) return rv; } + // Drop notification callbacks to prevent cycles. + mCallbacks = nsnull; + mEventSink = nsnull; + return NS_OK; } @@ -890,6 +894,10 @@ nsLDAPChannel::OnLDAPSearchResult(nsILDAPMessage *aMessage) } } + // Drop notification callbacks to prevent cycles. + mCallbacks = nsnull; + mEventSink = nsnull; + return NS_OK; } diff --git a/mozilla/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp b/mozilla/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp index 2749a9f90b7..68d039fda81 100644 --- a/mozilla/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp +++ b/mozilla/embedding/tests/wxEmbed/GeckoProtocolHandler.cpp @@ -532,6 +532,11 @@ GeckoProtocolChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult mPump = 0; mContentStream = 0; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/extensions/datetime/nsDateTimeChannel.cpp b/mozilla/extensions/datetime/nsDateTimeChannel.cpp index 03786156a12..3af7983e290 100644 --- a/mozilla/extensions/datetime/nsDateTimeChannel.cpp +++ b/mozilla/extensions/datetime/nsDateTimeChannel.cpp @@ -395,6 +395,11 @@ nsDateTimeChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult sta mPump = 0; mTransport = 0; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/extensions/finger/nsFingerChannel.cpp b/mozilla/extensions/finger/nsFingerChannel.cpp index 69f777f7ee9..460a88c3e67 100644 --- a/mozilla/extensions/finger/nsFingerChannel.cpp +++ b/mozilla/extensions/finger/nsFingerChannel.cpp @@ -417,6 +417,11 @@ nsFingerChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult statu mPump = 0; mTransport = 0; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/mailnews/base/util/nsMsgProtocol.cpp b/mozilla/mailnews/base/util/nsMsgProtocol.cpp index 3fbf672d494..5274bd022ef 100644 --- a/mozilla/mailnews/base/util/nsMsgProtocol.cpp +++ b/mozilla/mailnews/base/util/nsMsgProtocol.cpp @@ -444,6 +444,10 @@ NS_IMETHODIMP nsMsgProtocol::OnStopRequest(nsIRequest *request, nsISupports *ctx } // if we got an error code } // if we have a mailnews url. + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressEventSink = 0; + return rv; } diff --git a/mozilla/modules/libjar/nsJARChannel.cpp b/mozilla/modules/libjar/nsJARChannel.cpp index 4132aac6ba7..f3b1c882c15 100644 --- a/mozilla/modules/libjar/nsJARChannel.cpp +++ b/mozilla/modules/libjar/nsJARChannel.cpp @@ -720,6 +720,11 @@ nsJARChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) NS_IF_RELEASE(mJarInput); mIsPending = PR_FALSE; mDownloader = 0; // this may delete the underlying jar file + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp b/mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp index a9abf199de3..b568960be78 100644 --- a/mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp +++ b/mozilla/modules/libpr0n/decoders/icon/mac/nsIconChannel.cpp @@ -518,6 +518,10 @@ NS_IMETHODIMP nsIconChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports aListener->OnDataAvailable(this, ctxt, inputStr, 0, iconBuffer.Length()); } aListener->OnStopRequest(this, ctxt, rv); + + // Drop notification callbacks to prevent cycles. + mCallbacks = nsnull; + return NS_OK; } diff --git a/mozilla/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp b/mozilla/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp index e41e049665c..4c090f1e126 100644 --- a/mozilla/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp +++ b/mozilla/modules/libpr0n/decoders/icon/os2/nsIconChannel.cpp @@ -737,6 +737,9 @@ NS_IMETHODIMP nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aC if (mLoadGroup) mLoadGroup->RemoveRequest(this, nsnull, aStatus); + // Drop notification callbacks to prevent cycles. + mCallbacks = nsnull; + return NS_OK; } diff --git a/mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp b/mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp index 72102b7111d..0689eb41968 100644 --- a/mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp +++ b/mozilla/modules/libpr0n/decoders/icon/win/nsIconChannel.cpp @@ -500,6 +500,9 @@ NS_IMETHODIMP nsIconChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aC if (mLoadGroup) mLoadGroup->RemoveRequest(this, nsnull, aStatus); + // Drop notification callbacks to prevent cycles. + mCallbacks = nsnull; + return NS_OK; } diff --git a/mozilla/netwerk/base/public/nsIChannel.idl b/mozilla/netwerk/base/public/nsIChannel.idl index aa457421b46..b50bf678367 100644 --- a/mozilla/netwerk/base/public/nsIChannel.idl +++ b/mozilla/netwerk/base/public/nsIChannel.idl @@ -100,6 +100,9 @@ interface nsIChannel : nsIRequest * channel may ignore changes to the notificationCallbacks attribute after * it has been opened. This rule also applies to notificationCallbacks * queried from the channel's loadgroup. + * + * When the channel is done, it must not continue holding references to + * this object. */ attribute nsIInterfaceRequestor notificationCallbacks; diff --git a/mozilla/netwerk/base/src/nsInputStreamChannel.cpp b/mozilla/netwerk/base/src/nsInputStreamChannel.cpp index 895e7788614..50a6ef03fc8 100644 --- a/mozilla/netwerk/base/src/nsInputStreamChannel.cpp +++ b/mozilla/netwerk/base/src/nsInputStreamChannel.cpp @@ -375,6 +375,11 @@ nsInputStreamChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult mPump = 0; mContentStream = 0; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp b/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp index a20f4f788d3..58435e1f922 100644 --- a/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp +++ b/mozilla/netwerk/protocol/data/src/nsDataChannel.cpp @@ -479,6 +479,9 @@ nsDataChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, if (mLoadGroup) mLoadGroup->RemoveRequest(this, nsnull, status); + // Drop notification callbacks to prevent cycles. + mCallbacks = nsnull; + return NS_OK; } diff --git a/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp b/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp index a46e29b316f..415907495bc 100644 --- a/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp +++ b/mozilla/netwerk/protocol/file/src/nsFileChannel.cpp @@ -555,6 +555,11 @@ nsFileChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status) mRequest = 0; mStream = 0; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp b/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp index 5a3102ccaca..be349ba7e28 100644 --- a/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp +++ b/mozilla/netwerk/protocol/ftp/src/nsFTPChannel.cpp @@ -610,6 +610,11 @@ nsFTPChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext, NS_RELEASE(mFTPState); } mIsPending = PR_FALSE; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mEventSink = 0; + return rv; } diff --git a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp index 6a7c9239276..793b19bc59b 100644 --- a/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp +++ b/mozilla/netwerk/protocol/gopher/src/nsGopherChannel.cpp @@ -547,6 +547,12 @@ nsGopherChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext, mTransport->Close(mStatus); mTransport = 0; mPump = 0; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + mPrompter = 0; + mProgressSink = 0; + return NS_OK; } diff --git a/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp b/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp index 988ceff9185..573a39ff26b 100644 --- a/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/mozilla/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -166,6 +166,7 @@ nsresult nsExtProtocolChannel::SetURI(nsIURI* aURI) nsresult nsExtProtocolChannel::OpenURL() { + nsresult rv = NS_ERROR_FAILURE; nsCOMPtr extProtService (do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID)); if (extProtService) @@ -181,9 +182,13 @@ nsresult nsExtProtocolChannel::OpenURL() // get an nsIPrompt from the channel if we can nsCOMPtr prompt; NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, prompt); - return extProtService->LoadURI(mUrl, prompt); + rv = extProtService->LoadURI(mUrl, prompt); } - return NS_ERROR_FAILURE; + + // Drop notification callbacks to prevent cycles. + mCallbacks = 0; + + return rv; } NS_IMETHODIMP nsExtProtocolChannel::Open(nsIInputStream **_retval)