Bug 1389021 - Force CompositorManagerParent to close before shutting down the compositor thread. r=dvander

This commit is contained in:
Andrew Osmond 2017-09-14 10:02:30 -04:00
Родитель f8fda5a9b5
Коммит 32faf18553
3 изменённых файлов: 52 добавлений и 0 удалений

Просмотреть файл

@ -9,12 +9,14 @@
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include "nsAutoPtr.h"
#include "VsyncSource.h"
namespace mozilla {
namespace layers {
StaticRefPtr<CompositorManagerParent> CompositorManagerParent::sInstance;
StaticAutoPtr<nsTArray<CompositorManagerParent*>> CompositorManagerParent::sActiveActors;
StaticMutex CompositorManagerParent::sMutex;
/* static */ already_AddRefed<CompositorManagerParent>
@ -44,6 +46,11 @@ CompositorManagerParent::CreateSameProcess()
// we don't use that in the same process case.
parent.get()->AddRef();
sInstance = parent;
if (!sActiveActors) {
sActiveActors = new nsTArray<CompositorManagerParent*>();
}
sActiveActors->AppendElement(parent);
return parent.forget();
}
@ -127,6 +134,12 @@ CompositorManagerParent::Bind(Endpoint<PCompositorManagerParent>&& aEndpoint)
// Add the IPDL reference to ourself, so we can't get freed until IPDL is
// done with us.
AddRef();
StaticMutexAutoLock lock(sMutex);
if (!sActiveActors) {
sActiveActors = new nsTArray<CompositorManagerParent*>();
}
sActiveActors->AppendElement(this);
}
void
@ -146,6 +159,10 @@ CompositorManagerParent::DeallocPCompositorManagerParent()
this,
&CompositorManagerParent::DeferredDestroy));
StaticMutexAutoLock lock(sMutex);
if (sActiveActors) {
sActiveActors->RemoveElement(this);
}
Release();
}
@ -155,6 +172,36 @@ CompositorManagerParent::DeferredDestroy()
mCompositorThreadHolder = nullptr;
}
/* static */ void
CompositorManagerParent::ShutdownInternal()
{
nsAutoPtr<nsTArray<CompositorManagerParent*>> actors;
// We move here because we may attempt to acquire the same lock during the
// destroy to remove the reference in sActiveActors.
{
StaticMutexAutoLock lock(sMutex);
actors = sActiveActors.forget();
}
if (actors) {
for (auto& actor : *actors) {
actor->Close();
}
}
}
/* static */ void
CompositorManagerParent::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
CompositorThreadHolder::Loop()->PostTask(
NS_NewRunnableFunction("layers::CompositorManagerParent::Shutdown", []() -> void {
CompositorManagerParent::ShutdownInternal();
}));
}
PCompositorBridgeParent*
CompositorManagerParent::AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt)
{

Просмотреть файл

@ -27,6 +27,7 @@ class CompositorManagerParent final : public PCompositorManagerParent
public:
static already_AddRefed<CompositorManagerParent> CreateSameProcess();
static void Create(Endpoint<PCompositorManagerParent>&& aEndpoint);
static void Shutdown();
static already_AddRefed<CompositorBridgeParent>
CreateSameProcessWidgetCompositorBridge(CSSToLayoutDeviceScale aScale,
@ -41,8 +42,11 @@ public:
private:
static StaticRefPtr<CompositorManagerParent> sInstance;
static StaticAutoPtr<nsTArray<CompositorManagerParent*>> sActiveActors;
static StaticMutex sMutex;
static void ShutdownInternal();
CompositorManagerParent();
~CompositorManagerParent() override;

Просмотреть файл

@ -159,6 +159,7 @@ CompositorThreadHolder::Shutdown()
ReleaseImageBridgeParentSingleton();
gfx::ReleaseVRManagerParentSingleton();
MediaSystemResourceService::Shutdown();
CompositorManagerParent::Shutdown();
sCompositorThreadHolder = nullptr;