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)