зеркало из https://github.com/mozilla/gecko-dev.git
Fix ImageBridgeChild memory tracking errors on shutdown. (bug 1323957 part 6, r=mattwoodrow)
--HG-- extra : rebase_source : 58a8df18d964cbe1b216cc7e8dbceb39760e632e
This commit is contained in:
Родитель
3d7a9b6ee1
Коммит
22504df44c
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче