Fix ImageBridgeChild memory tracking errors on shutdown. (bug 1323957 part 6, r=mattwoodrow)

--HG--
extra : rebase_source : 58a8df18d964cbe1b216cc7e8dbceb39760e632e
This commit is contained in:
David Anderson 2017-01-17 18:47:07 -08:00
Родитель 3d7a9b6ee1
Коммит 22504df44c
5 изменённых файлов: 41 добавлений и 9 удалений

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

@ -78,7 +78,7 @@ protected:
virtual ~CompositableHost();
public:
NS_INLINE_DECL_REFCOUNTING(CompositableHost)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositableHost)
explicit CompositableHost(const TextureInfo& aTextureInfo);
static already_AddRefed<CompositableHost> Create(const TextureInfo& aTextureInfo);

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

@ -295,18 +295,17 @@ ImageBridgeChild::ShutdownStep2(SynchronousTask* aTask)
MOZ_ASSERT(InImageBridgeChildThread(),
"Should be in ImageBridgeChild thread.");
if (!mCalledClose) {
Close();
mCalledClose = true;
}
Close();
}
void
ImageBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
{
mCanSend = false;
mCalledClose = true;
{
MutexAutoLock lock(mContainerMapLock);
mImageContainers.Clear();
}
}
void
@ -338,7 +337,7 @@ ImageBridgeChild::CreateCanvasClientSync(SynchronousTask* aTask,
ImageBridgeChild::ImageBridgeChild()
: mCanSend(false)
, mCalledClose(false)
, mDestroyed(false)
, mFwdTransactionId(0)
, mContainerMapLock("ImageBridgeChild.mContainerMapLock")
{
@ -736,6 +735,8 @@ ImageBridgeChild::WillShutdown()
task.Wait();
}
mDestroyed = true;
}
void
@ -998,6 +999,12 @@ ImageBridgeChild::DeallocShmem(ipc::Shmem& aShmem)
return PImageBridgeChild::DeallocShmem(aShmem);
}
// If we can't post a task, then we definitely cannot send, so there's
// no reason to queue up this send.
if (!CanPostTask()) {
return false;
}
SynchronousTask task("AllocatorProxy Dealloc");
bool result = false;
@ -1150,10 +1157,32 @@ bool ImageBridgeChild::IsSameProcess() const
return OtherPid() == base::GetCurrentProcId();
}
bool
ImageBridgeChild::CanPostTask() const
{
// During shutdown, the cycle collector may free objects that are holding a
// reference to ImageBridgeChild. Since this happens on the main thread,
// ImageBridgeChild will attempt to post a task to the ImageBridge thread.
// However the thread manager has already been shut down, so the task cannot
// post.
//
// It's okay if this races. We only care about the shutdown case where
// everything's happening on the main thread. Even if it races outside of
// shutdown, it's still harmless to post the task, since the task must
// check CanSend().
return !mDestroyed;
}
void
ImageBridgeChild::ReleaseCompositable(const CompositableHandle& aHandle)
{
if (!InImageBridgeChildThread()) {
// If we can't post a task, then we definitely cannot send, so there's
// no reason to queue up this send.
if (!CanPostTask()) {
return;
}
RefPtr<Runnable> runnable = WrapRunnable(
RefPtr<ImageBridgeChild>(this),
&ImageBridgeChild::ReleaseCompositable,

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

@ -360,6 +360,7 @@ protected:
void DeallocPImageBridgeChild() override;
bool CanSend() const;
bool CanPostTask() const;
static void ShutdownSingleton();
@ -367,7 +368,7 @@ private:
CompositableTransaction* mTxn;
bool mCanSend;
bool mCalledClose;
mozilla::Atomic<bool> mDestroyed;
/**
* Transaction id of CompositableForwarder.

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

@ -104,6 +104,7 @@ ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{
// Can't alloc/dealloc shmems from now on.
mClosed = true;
mCompositables.clear();
MessageLoop::current()->PostTask(NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));

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

@ -94,6 +94,7 @@ void
LayerTransactionParent::Destroy()
{
mDestroyed = true;
mCompositables.clear();
}
mozilla::ipc::IPCResult