mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 774388 - Patch 12: make ImageBridgeParent 's refcounting implementation automatically defer destruction to the main thread - r=nical
This commit is contained in:
parent
aa0a4dc9b8
commit
1d691a18f6
@ -8,6 +8,10 @@
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -18,10 +22,21 @@ class AtomicRefCountedWithFinalize
|
||||
AtomicRefCountedWithFinalize()
|
||||
: mRecycleCallback(nullptr)
|
||||
, mRefCount(0)
|
||||
, mMessageLoopToPostDestructionTo(nullptr)
|
||||
{}
|
||||
|
||||
~AtomicRefCountedWithFinalize() {}
|
||||
|
||||
void SetMessageLoopToPostDestructionTo(MessageLoop* l) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mMessageLoopToPostDestructionTo = l;
|
||||
}
|
||||
|
||||
static void DestroyToBeCalledOnMainThread(T* ptr) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
public:
|
||||
void AddRef() {
|
||||
MOZ_ASSERT(mRefCount >= 0);
|
||||
@ -43,7 +58,17 @@ class AtomicRefCountedWithFinalize
|
||||
#endif
|
||||
T* derived = static_cast<T*>(this);
|
||||
derived->Finalize();
|
||||
if (MOZ_LIKELY(!mMessageLoopToPostDestructionTo)) {
|
||||
delete derived;
|
||||
} else {
|
||||
if (MOZ_LIKELY(NS_IsMainThread())) {
|
||||
delete derived;
|
||||
} else {
|
||||
mMessageLoopToPostDestructionTo->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&DestroyToBeCalledOnMainThread, derived));
|
||||
}
|
||||
}
|
||||
} else if (1 == currCount && recycleCallback) {
|
||||
T* derived = static_cast<T*>(this);
|
||||
recycleCallback(derived, mClosure);
|
||||
@ -71,6 +96,7 @@ private:
|
||||
RecycleCallback mRecycleCallback;
|
||||
void *mClosure;
|
||||
Atomic<int> mRefCount;
|
||||
MessageLoop *mMessageLoopToPostDestructionTo;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -54,12 +54,15 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
|
||||
, mChildProcessId(aChildProcessId)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sMainLoop = MessageLoop::current();
|
||||
|
||||
// top-level actors must be destroyed on the main thread.
|
||||
SetMessageLoopToPostDestructionTo(sMainLoop);
|
||||
|
||||
// creates the map only if it has not been created already, so it is safe
|
||||
// with several bridges
|
||||
CompositableMap::Create();
|
||||
sImageBridges[aChildProcessId] = this;
|
||||
sMainLoop = MessageLoop::current();
|
||||
}
|
||||
|
||||
ImageBridgeParent::~ImageBridgeParent()
|
||||
@ -274,21 +277,10 @@ MessageLoop * ImageBridgeParent::GetMessageLoop() const {
|
||||
return mMessageLoop;
|
||||
}
|
||||
|
||||
static void
|
||||
DeferredReleaseImageBridgeParentOnMainThread(ImageBridgeParent* aDyingImageBridgeParent)
|
||||
{
|
||||
aDyingImageBridgeParent->Release();
|
||||
}
|
||||
|
||||
void
|
||||
ImageBridgeParent::DeferredDestroy()
|
||||
{
|
||||
ImageBridgeParent* self;
|
||||
mSelfRef.forget(&self);
|
||||
|
||||
sMainLoop->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(&DeferredReleaseImageBridgeParentOnMainThread, this));
|
||||
mSelfRef = nullptr;
|
||||
}
|
||||
|
||||
ImageBridgeParent*
|
||||
|
Loading…
Reference in New Issue
Block a user