Bug 1396652: Fix WebRequestService destructor ordering issue. r?mixedpuppy
MozReview-Commit-ID: HYDNYzb5bnM
--- a/toolkit/components/extensions/webrequest/WebRequestService.cpp
+++ b/toolkit/components/extensions/webrequest/WebRequestService.cpp
@@ -9,46 +9,62 @@
#include "mozilla/Assertions.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsCOMPtr.h"
#include "nsIChannel.h"
#include "nsIDOMWindowUtils.h"
#include "nsISupports.h"
#include "nsITabParent.h"
#include "nsITraceableChannel.h"
+#include "nsTArray.h"
#include "mozilla/dom/TabParent.h"
using namespace mozilla;
using namespace mozilla::dom;
+static WebRequestService* sWeakWebRequestService;
+
WebRequestService::WebRequestService()
: mDataLock("WebRequest service data lock")
{
}
WebRequestService::~WebRequestService()
{
+ // Store existing entries in an array, since Detach can't safely remove them
+ // while we're iterating the hashtable.
+ AutoTArray<ChannelEntry*, 32> entries;
for (auto iter = mChannelEntries.Iter(); !iter.Done(); iter.Next()) {
- auto& channel = iter.Data();
+ entries.AppendElement(iter.Data());
+ }
+
+ for (auto channel : entries) {
channel->DetachAll();
}
+
+ sWeakWebRequestService = nullptr;
}
NS_IMPL_ISUPPORTS(WebRequestService, mozIWebRequestService)
/* static */ WebRequestService&
WebRequestService::GetSingleton()
{
static RefPtr<WebRequestService> instance;
- if (!instance) {
+ if (!sWeakWebRequestService) {
instance = new WebRequestService();
ClearOnShutdown(&instance);
+
+ // A separate weak instance that we keep a reference to as long as the
+ // original service is alive, even after our strong reference is cleared to
+ // allow the service to be destroyed.
+ sWeakWebRequestService = instance;
}
- return *instance;
+ return *sWeakWebRequestService;
}
NS_IMETHODIMP
WebRequestService::RegisterTraceableChannel(uint64_t aChannelId,
nsIChannel* aChannel,
const nsAString& aAddonId,
nsITabParent* aTabParent,