mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Remove racy ImageBridgeChild shutdown/creation checks. (bug 1298938 part 4, r=nical)
--HG-- extra : rebase_source : 47d1a0b3da521d81da9ffea7e259104b508b7415
This commit is contained in:
parent
435ec16468
commit
91559fcffe
@ -147,10 +147,9 @@ OffscreenCanvas::GetContext(JSContext* aCx,
|
||||
mCanvasRenderer->mGLContext = gl;
|
||||
mCanvasRenderer->SetIsAlphaPremultiplied(webGL->IsPremultAlpha() || !gl->Caps().alpha);
|
||||
|
||||
if (ImageBridgeChild::IsCreated()) {
|
||||
if (RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton()) {
|
||||
TextureFlags flags = TextureFlags::ORIGIN_BOTTOM_LEFT;
|
||||
mCanvasClient = ImageBridgeChild::GetSingleton()->
|
||||
CreateCanvasClient(CanvasClient::CanvasClientTypeShSurf, flags);
|
||||
mCanvasClient = imageBridge->CreateCanvasClient(CanvasClient::CanvasClientTypeShSurf, flags);
|
||||
mCanvasRenderer->SetCanvasClient(mCanvasClient);
|
||||
|
||||
gl::GLScreenBuffer* screen = gl->Screen();
|
||||
|
@ -42,7 +42,8 @@ MediaSystemResourceManager::Shutdown()
|
||||
/* static */ void
|
||||
MediaSystemResourceManager::Init()
|
||||
{
|
||||
if (!ImageBridgeChild::IsCreated()) {
|
||||
RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton();
|
||||
if (!imageBridge) {
|
||||
NS_WARNING("ImageBridge does not exist");
|
||||
return;
|
||||
}
|
||||
@ -73,7 +74,7 @@ MediaSystemResourceManager::Init()
|
||||
barrier.NotifyAll();
|
||||
});
|
||||
|
||||
ImageBridgeChild::GetSingleton()->GetMessageLoop()->PostTask(runnable.forget());
|
||||
imageBridge->GetMessageLoop()->PostTask(runnable.forget());
|
||||
|
||||
// should stop the thread until done.
|
||||
while (!done) {
|
||||
|
@ -151,7 +151,7 @@ GPUProcessManager::EnsureGPUReady()
|
||||
void
|
||||
GPUProcessManager::EnsureImageBridgeChild()
|
||||
{
|
||||
if (ImageBridgeChild::IsCreated()) {
|
||||
if (ImageBridgeChild::GetSingleton()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -168,9 +168,6 @@ struct AutoEndTransaction {
|
||||
CompositableTransaction* mTxn;
|
||||
};
|
||||
|
||||
/* static */
|
||||
Atomic<bool> ImageBridgeChild::sIsShutDown(false);
|
||||
|
||||
void
|
||||
ImageBridgeChild::UseTextures(CompositableClient* aCompositable,
|
||||
const nsTArray<TimedTextureClient>& aTextures)
|
||||
@ -500,6 +497,12 @@ ImageBridgeChild::ShutdownStep2(SynchronousTask* aTask)
|
||||
Close();
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mCanSend = false;
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::CreateImageClientSync(SynchronousTask* aTask,
|
||||
RefPtr<ImageClient>* result,
|
||||
@ -523,7 +526,7 @@ ImageBridgeChild::CreateCanvasClientSync(SynchronousTask* aTask,
|
||||
}
|
||||
|
||||
ImageBridgeChild::ImageBridgeChild()
|
||||
: mShuttingDown(false)
|
||||
: mCanSend(false)
|
||||
, mFwdTransactionId(0)
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
, mWaitingFenceHandleMutex("ImageBridgeChild::mWaitingFenceHandleMutex")
|
||||
@ -547,11 +550,10 @@ ImageBridgeChild::~ImageBridgeChild()
|
||||
void
|
||||
ImageBridgeChild::MarkShutDown()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
mTexturesWaitingRecycled.Clear();
|
||||
mTrackersHolder.DestroyAsyncTransactionTrackersHolder();
|
||||
|
||||
mShuttingDown = true;
|
||||
mCanSend = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -559,8 +561,8 @@ ImageBridgeChild::Connect(CompositableClient* aCompositable,
|
||||
ImageContainer* aImageContainer)
|
||||
{
|
||||
MOZ_ASSERT(aCompositable);
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
MOZ_ASSERT(CanSend());
|
||||
|
||||
uint64_t id = 0;
|
||||
|
||||
@ -579,7 +581,7 @@ PCompositableChild*
|
||||
ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo,
|
||||
PImageContainerChild* aChild, uint64_t* aID)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
return AsyncCompositableChild::CreateActor();
|
||||
}
|
||||
|
||||
@ -601,11 +603,6 @@ ImageBridgeChild* ImageBridgeChild::GetSingleton()
|
||||
return sImageBridgeChildSingleton;
|
||||
}
|
||||
|
||||
bool ImageBridgeChild::IsCreated()
|
||||
{
|
||||
return GetSingleton() != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::ReleaseImageContainer(RefPtr<ImageContainerChild> aChild)
|
||||
{
|
||||
@ -661,12 +658,7 @@ ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
|
||||
void
|
||||
ImageBridgeChild::UpdateImageClient(RefPtr<ImageClient> aClient, RefPtr<ImageContainer> aContainer)
|
||||
{
|
||||
if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
|
||||
NS_WARNING("Something is holding on to graphics resources after the shutdown"
|
||||
"of the graphics subsystem!");
|
||||
return;
|
||||
}
|
||||
if (!aClient || !aContainer || !IsCreated()) {
|
||||
if (!aClient || !aContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -680,6 +672,10 @@ ImageBridgeChild::UpdateImageClient(RefPtr<ImageClient> aClient, RefPtr<ImageCon
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CanSend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the client has become disconnected before this event was dispatched,
|
||||
// early return now.
|
||||
if (!aClient->IsConnected()) {
|
||||
@ -725,6 +721,11 @@ void
|
||||
ImageBridgeChild::UpdateAsyncCanvasRendererNow(AsyncCanvasRenderer* aWrapper)
|
||||
{
|
||||
MOZ_ASSERT(aWrapper);
|
||||
|
||||
if (!CanSend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BeginTransaction();
|
||||
aWrapper->GetCanvasClient()->Updated();
|
||||
EndTransaction();
|
||||
@ -744,14 +745,7 @@ ImageBridgeChild::FlushAllImagesSync(SynchronousTask* aTask,
|
||||
|
||||
AutoCompleteTask complete(aTask);
|
||||
|
||||
if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
|
||||
// How sad. If we get into this branch it means that the ImageBridge
|
||||
// got destroyed between the time we ImageBridgeChild::FlushAllImage
|
||||
// was called on some thread, and the time this function was proxied
|
||||
// to the ImageBridge thread. ImageBridge gets destroyed way to late
|
||||
// in the shutdown of gecko for this to be happening for a good reason.
|
||||
NS_WARNING("Something is holding on to graphics resources after the shutdown"
|
||||
"of the graphics subsystem!");
|
||||
if (!CanSend()) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
aWaiter->DecrementWaitCount();
|
||||
#endif
|
||||
@ -777,12 +771,9 @@ ImageBridgeChild::FlushAllImagesSync(SynchronousTask* aTask,
|
||||
void
|
||||
ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer)
|
||||
{
|
||||
if (!IsCreated() || IsShutDown()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(aClient);
|
||||
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
|
||||
MOZ_ASSERT(!InImageBridgeChildThread());
|
||||
|
||||
if (InImageBridgeChildThread()) {
|
||||
NS_ERROR("ImageBridgeChild::FlushAllImages() is called on ImageBridge thread.");
|
||||
return;
|
||||
@ -817,7 +808,7 @@ ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContaine
|
||||
void
|
||||
ImageBridgeChild::BeginTransaction()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
MOZ_ASSERT(mTxn->Finished(), "uncommitted txn?");
|
||||
UpdateFwdTransactionId();
|
||||
mTxn->Begin();
|
||||
@ -826,7 +817,7 @@ ImageBridgeChild::BeginTransaction()
|
||||
void
|
||||
ImageBridgeChild::EndTransaction()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
MOZ_ASSERT(!mTxn->Finished(), "forgot BeginTransaction?");
|
||||
|
||||
AutoEndTransaction _(mTxn);
|
||||
@ -907,6 +898,8 @@ ImageBridgeChild::Bind(Endpoint<PImageBridgeChild>&& aEndpoint)
|
||||
return;
|
||||
}
|
||||
|
||||
mCanSend = true;
|
||||
|
||||
SendImageBridgeThreadId();
|
||||
}
|
||||
|
||||
@ -917,6 +910,8 @@ ImageBridgeChild::BindSameProcess(RefPtr<ImageBridgeParent> aParent)
|
||||
ipc::MessageChannel *parentChannel = aParent->GetIPCChannel();
|
||||
Open(parentChannel, parentMsgLoop, mozilla::ipc::ChildSide);
|
||||
|
||||
mCanSend = true;
|
||||
|
||||
SendImageBridgeThreadId();
|
||||
}
|
||||
|
||||
@ -924,8 +919,6 @@ void ImageBridgeChild::ShutDown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
sIsShutDown = true;
|
||||
|
||||
if (RefPtr<ImageBridgeChild> child = GetSingleton()) {
|
||||
child->WillShutdown();
|
||||
|
||||
@ -939,8 +932,6 @@ void ImageBridgeChild::ShutDown()
|
||||
void
|
||||
ImageBridgeChild::WillShutdown()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
|
||||
{
|
||||
SynchronousTask task("ImageBridge ShutdownStep1 lock");
|
||||
|
||||
@ -1017,7 +1008,7 @@ ImageBridgeChild::InitWithGPUProcess(Endpoint<PImageBridgeChild>&& aEndpoint)
|
||||
|
||||
bool InImageBridgeChildThread()
|
||||
{
|
||||
return ImageBridgeChild::IsCreated() &&
|
||||
return sImageBridgeChildThread &&
|
||||
sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
|
||||
}
|
||||
|
||||
@ -1067,7 +1058,6 @@ ImageBridgeChild::CreateImageClientNow(CompositableType aType,
|
||||
ImageContainer* aImageContainer,
|
||||
ImageContainerChild* aContainerChild)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
|
||||
if (aImageContainer) {
|
||||
@ -1127,12 +1117,12 @@ ImageBridgeChild::AllocUnsafeShmem(size_t aSize,
|
||||
ipc::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aShmem)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
if (InImageBridgeChildThread()) {
|
||||
return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
|
||||
} else {
|
||||
if (!InImageBridgeChildThread()) {
|
||||
return DispatchAllocShmemInternal(aSize, aType, aShmem, true); // true: unsafe
|
||||
}
|
||||
|
||||
MOZ_ASSERT(CanSend());
|
||||
return PImageBridgeChild::AllocUnsafeShmem(aSize, aType, aShmem);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1140,13 +1130,12 @@ ImageBridgeChild::AllocShmem(size_t aSize,
|
||||
ipc::SharedMemory::SharedMemoryType aType,
|
||||
ipc::Shmem* aShmem)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
if (InImageBridgeChildThread()) {
|
||||
return PImageBridgeChild::AllocShmem(aSize, aType,
|
||||
aShmem);
|
||||
} else {
|
||||
if (!InImageBridgeChildThread()) {
|
||||
return DispatchAllocShmemInternal(aSize, aType, aShmem, false); // false: unsafe
|
||||
}
|
||||
|
||||
MOZ_ASSERT(CanSend());
|
||||
return PImageBridgeChild::AllocShmem(aSize, aType, aShmem);
|
||||
}
|
||||
|
||||
// NewRunnableFunction accepts a limited number of parameters so we need a
|
||||
@ -1242,7 +1231,7 @@ ImageBridgeChild::AllocPTextureChild(const SurfaceDescriptor&,
|
||||
const TextureFlags&,
|
||||
const uint64_t& aSerial)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
return TextureClient::CreateIPDLActor();
|
||||
}
|
||||
|
||||
@ -1255,7 +1244,7 @@ ImageBridgeChild::DeallocPTextureChild(PTextureChild* actor)
|
||||
PMediaSystemResourceManagerChild*
|
||||
ImageBridgeChild::AllocPMediaSystemResourceManagerChild()
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
return new mozilla::media::MediaSystemResourceManagerChild();
|
||||
}
|
||||
|
||||
@ -1355,7 +1344,7 @@ ImageBridgeChild::CreateTexture(const SurfaceDescriptor& aSharedData,
|
||||
TextureFlags aFlags,
|
||||
uint64_t aSerial)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial);
|
||||
}
|
||||
|
||||
@ -1392,7 +1381,7 @@ void
|
||||
ImageBridgeChild::RemoveTextureFromCompositable(CompositableClient* aCompositable,
|
||||
TextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
MOZ_ASSERT(aTexture);
|
||||
MOZ_ASSERT(aTexture->IsSharedWithCompositor());
|
||||
MOZ_ASSERT(aCompositable->IsConnected());
|
||||
@ -1416,7 +1405,7 @@ ImageBridgeChild::RemoveTextureFromCompositableAsync(AsyncTransactionTracker* aA
|
||||
CompositableClient* aCompositable,
|
||||
TextureClient* aTexture)
|
||||
{
|
||||
MOZ_ASSERT(!mShuttingDown);
|
||||
MOZ_ASSERT(CanSend());
|
||||
MOZ_ASSERT(aTexture);
|
||||
MOZ_ASSERT(aTexture->IsSharedWithCompositor());
|
||||
MOZ_ASSERT(aCompositable->IsConnected());
|
||||
@ -1456,6 +1445,13 @@ ImageBridgeChild::Destroy(CompositableChild* aCompositable)
|
||||
CompositableForwarder::Destroy(aCompositable);
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBridgeChild::CanSend() const
|
||||
{
|
||||
MOZ_ASSERT(InImageBridgeChildThread());
|
||||
return mCanSend;
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeChild::OnXPCOMShutdown()
|
||||
{
|
||||
@ -1491,6 +1487,5 @@ ImageBridgeChild::ShutdownObserver::Observe(nsISupports* aSubject,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
@ -138,22 +138,6 @@ public:
|
||||
*/
|
||||
static void ShutDown();
|
||||
|
||||
/**
|
||||
* Returns true if the singleton has been created.
|
||||
*
|
||||
* Can be called from any thread.
|
||||
*/
|
||||
static bool IsCreated();
|
||||
/**
|
||||
* Returns true if the singleton's ShutDown() was called.
|
||||
*
|
||||
* Can be called from any thread.
|
||||
*/
|
||||
static bool IsShutDown()
|
||||
{
|
||||
return sIsShutDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the singleton instance.
|
||||
*
|
||||
@ -401,6 +385,10 @@ protected:
|
||||
void MarkShutDown();
|
||||
void FallbackDestroyActors();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
bool CanSend() const;
|
||||
|
||||
private:
|
||||
class ShutdownObserver final : public nsIObserver
|
||||
{
|
||||
@ -422,8 +410,8 @@ private:
|
||||
|
||||
private:
|
||||
CompositableTransaction* mTxn;
|
||||
Atomic<bool> mShuttingDown;
|
||||
static Atomic<bool> sIsShutDown;
|
||||
|
||||
bool mCanSend;
|
||||
|
||||
/**
|
||||
* Transaction id of CompositableForwarder.
|
||||
|
Loading…
Reference in New Issue
Block a user