diff --git a/content/html/content/src/nsHTMLDNSPrefetch.cpp b/content/html/content/src/nsHTMLDNSPrefetch.cpp
--- a/content/html/content/src/nsHTMLDNSPrefetch.cpp
+++ b/content/html/content/src/nsHTMLDNSPrefetch.cpp
@@ -50,16 +50,17 @@
#include "nsIDNSService.h"
#include "nsICancelable.h"
#include "nsContentUtils.h"
#include "nsGkAtoms.h"
#include "nsIDocument.h"
#include "nsThreadUtils.h"
#include "nsGenericHTMLElement.h"
#include "nsITimer.h"
+#include "nsIObserverService.h"
static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
static PRBool sDisablePrefetchHTTPSPref;
static PRBool sInitialized = PR_FALSE;
static nsIDNSService *sDNSService = nsnull;
static nsHTMLDNSPrefetch::nsDeferrals *sPrefetches = nsnull;
nsresult
@@ -204,31 +205,44 @@ nsHTMLDNSPrefetch::nsDeferrals::nsDeferr
mActiveLoaderCount(0),
mTimerArmed(PR_FALSE)
{
mTimer = do_CreateInstance("@mozilla.org/timer;1");
}
nsHTMLDNSPrefetch::nsDeferrals::~nsDeferrals()
{
+ nsresult rv;
+ nsCOMPtr observerService =
+ do_GetService("@mozilla.org/observer-service;1", &rv);
+ if (NS_SUCCEEDED(rv))
+ observerService->RemoveObserver(this, "xpcom-shutdown");
+
if (mTimerArmed) {
mTimerArmed = PR_FALSE;
mTimer->Cancel();
}
+ Flush();
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS4(nsHTMLDNSPrefetch::nsDeferrals,
+ nsIDNSListener,
+ nsIWebProgressListener,
+ nsISupportsWeakReference,
+ nsIObserver)
+
+void
+nsHTMLDNSPrefetch::nsDeferrals::Flush()
+{
while (mHead != mTail) {
mEntries[mTail].mElement = nsnull;
mTail = (mTail + 1) & sMaxDeferredMask;
}
}
-
-NS_IMPL_THREADSAFE_ISUPPORTS3(nsHTMLDNSPrefetch::nsDeferrals,
- nsIDNSListener,
- nsIWebProgressListener,
- nsISupportsWeakReference)
nsresult
nsHTMLDNSPrefetch::nsDeferrals::Add(PRUint16 flags, nsGenericHTMLElement *aElement)
{
// The FIFO has no lock, so it can only be accessed on main thread
NS_ASSERTION(NS_IsMainThread(), "nsDeferrals::Add must be on main thread");
if (((mHead + 1) & sMaxDeferredMask) == mTail)
@@ -279,16 +293,23 @@ void
void
nsHTMLDNSPrefetch::nsDeferrals::Activate()
{
// Register as an observer for the document loader
nsCOMPtr progress =
do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
if (progress)
progress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
+
+ // Register as an observer for xpcom shutdown events so we can drop any element refs
+ nsresult rv;
+ nsCOMPtr observerService =
+ do_GetService("@mozilla.org/observer-service;1", &rv);
+ if (NS_SUCCEEDED(rv))
+ observerService->AddObserver(this, "xpcom-shutdown", PR_TRUE);
}
// nsITimer related method
void
nsHTMLDNSPrefetch::nsDeferrals::Tick(nsITimer *aTimer, void *aClosure)
{
nsHTMLDNSPrefetch::nsDeferrals *self = (nsHTMLDNSPrefetch::nsDeferrals *) aClosure;
@@ -374,8 +395,21 @@ nsHTMLDNSPrefetch::nsDeferrals::OnStatus
NS_IMETHODIMP
nsHTMLDNSPrefetch::nsDeferrals::OnSecurityChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 state)
{
return NS_OK;
}
+
+//////////// nsIObserver method
+
+NS_IMETHODIMP
+nsHTMLDNSPrefetch::nsDeferrals::Observe(nsISupports *subject,
+ const char *topic,
+ const PRUnichar *data)
+{
+ if (!strcmp(topic, "xpcom-shutdown"))
+ Flush();
+
+ return NS_OK;
+}
diff --git a/content/html/content/src/nsHTMLDNSPrefetch.h b/content/html/content/src/nsHTMLDNSPrefetch.h
--- a/content/html/content/src/nsHTMLDNSPrefetch.h
+++ b/content/html/content/src/nsHTMLDNSPrefetch.h
@@ -41,16 +41,17 @@
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsString.h"
#include "nsIDNSListener.h"
#include "nsIWebProgressListener.h"
#include "nsWeakReference.h"
+#include "nsIObserver.h"
class nsIDocument;
class nsGenericHTMLElement;
class nsITimer;
class nsHTMLDNSPrefetch
{
public:
@@ -81,29 +82,32 @@ private:
static nsresult Prefetch(nsAString &host, PRUint16 flags);
static nsresult Prefetch(nsGenericHTMLElement *aElement, PRUint16 flags);
static PRBool IsSecureBaseContext(nsIDocument *aDocument);
public:
class nsDeferrals : public nsIDNSListener
, public nsIWebProgressListener
, public nsSupportsWeakReference
+ , public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDNSLISTENER
NS_DECL_NSIWEBPROGRESSLISTENER
-
+ NS_DECL_NSIOBSERVER
+
nsDeferrals();
void Activate();
nsresult Add(PRUint16 flags, nsGenericHTMLElement *aElement);
private:
~nsDeferrals();
+ void Flush();
void SubmitQueue();
PRUint16 mHead;
PRUint16 mTail;
PRUint32 mActiveLoaderCount;
nsCOMPtr mTimer;