Bug 1340665 - Fix warnings on shutdown. r=billm
The code to make a ValidatingDispatcher break cycles when we're done with it
assumes that XPCOM is still up and running. This isn't the case during
shutdown. When XPCOM shuts down, we should avoid do_GetMainThread.
MozReview-Commit-ID: 5Gpko9FbFxl
--- a/dom/base/TabGroup.cpp
+++ b/dom/base/TabGroup.cpp
@@ -162,17 +162,17 @@ TabGroup::Leave(nsPIDOMWindowOuter* aWin
MOZ_ASSERT(mWindows.Contains(aWindow));
mWindows.RemoveElement(aWindow);
// The Chrome TabGroup doesn't have cyclical references through mEventTargets
// to itself, meaning that we don't have to worry about nulling mEventTargets
// out after the last window leaves.
if (!mIsChrome && mWindows.IsEmpty()) {
mLastWindowLeft = true;
- Shutdown();
+ Shutdown(false);
}
}
nsresult
TabGroup::FindItemWithName(const nsAString& aName,
nsIDocShellTreeItem* aRequestor,
nsIDocShellTreeItem* aOriginalRequestor,
nsIDocShellTreeItem** aFoundItem)
--- a/xpcom/threads/Dispatcher.cpp
+++ b/xpcom/threads/Dispatcher.cpp
@@ -147,24 +147,26 @@ ValidatingDispatcher::Dispatch(const cha
{
return LabeledDispatch(aName, aCategory, Move(aRunnable));
}
nsIEventTarget*
ValidatingDispatcher::EventTargetFor(TaskCategory aCategory) const
{
MOZ_ASSERT(aCategory != TaskCategory::Count);
+ MOZ_ASSERT(mEventTargets[size_t(aCategory)]);
return mEventTargets[size_t(aCategory)];
}
AbstractThread*
ValidatingDispatcher::AbstractMainThreadForImpl(TaskCategory aCategory)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aCategory != TaskCategory::Count);
+ MOZ_ASSERT(mEventTargets[size_t(aCategory)]);
if (!mAbstractThreads[size_t(aCategory)]) {
mAbstractThreads[size_t(aCategory)] =
AbstractThread::CreateEventTargetWrapper(mEventTargets[size_t(aCategory)],
/* aDrainDirectTasks = */ true);
}
return mAbstractThreads[size_t(aCategory)];
@@ -182,24 +184,24 @@ ValidatingDispatcher::CreateEventTargets
mEventTargets[i] = do_GetMainThread();
} else {
mEventTargets[i] = CreateEventTargetFor(category);
}
}
}
void
-ValidatingDispatcher::Shutdown()
+ValidatingDispatcher::Shutdown(bool aXPCOMShutdown)
{
// There is a RefPtr cycle TabGroup -> DispatcherEventTarget -> TabGroup. To
// avoid leaks, we need to break the chain somewhere. We shouldn't be using
// the ThrottledEventQueue for this TabGroup when no windows belong to it,
// so it's safe to null out the queue here.
for (size_t i = 0; i < size_t(TaskCategory::Count); i++) {
- mEventTargets[i] = do_GetMainThread();
+ mEventTargets[i] = aXPCOMShutdown ? nullptr : do_GetMainThread();
mAbstractThreads[i] = nullptr;
}
}
already_AddRefed<nsIEventTarget>
ValidatingDispatcher::CreateEventTargetFor(TaskCategory aCategory)
{
RefPtr<DispatcherEventTarget> target =
--- a/xpcom/threads/Dispatcher.h
+++ b/xpcom/threads/Dispatcher.h
@@ -107,17 +107,20 @@ protected:
// function returns |dispatcher|.
static ValidatingDispatcher* FromEventTarget(nsIEventTarget* aEventTarget);
nsresult LabeledDispatch(const char* aName,
TaskCategory aCategory,
already_AddRefed<nsIRunnable>&& aRunnable);
void CreateEventTargets(bool aNeedValidation);
- void Shutdown();
+
+ // Shuts down this dispatcher. If aXPCOMShutdown is true, invalidates this
+ // dispatcher.
+ void Shutdown(bool aXPCOMShutdown);
enum ValidationType {
StartValidation,
EndValidation,
};
void SetValidatingAccess(ValidationType aType);
static ValidatingDispatcher* sRunningDispatcher;
--- a/xpcom/threads/SystemGroup.cpp
+++ b/xpcom/threads/SystemGroup.cpp
@@ -48,17 +48,17 @@ SystemGroupImpl::InitStatic()
MOZ_ASSERT(!sSingleton);
MOZ_ASSERT(NS_IsMainThread());
sSingleton = MakeUnique<SystemGroupImpl>();
}
/* static */ void
SystemGroupImpl::ShutdownStatic()
{
- sSingleton->Shutdown();
+ sSingleton->Shutdown(true);
sSingleton = nullptr;
}
/* static */ SystemGroupImpl*
SystemGroupImpl::Get()
{
MOZ_ASSERT(sSingleton);
return sSingleton.get();