mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 774388 - Patch 9: Introduce NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION - r=mattwoodrow
This commit is contained in:
parent
ed54a8ae99
commit
0e7c7e1602
@ -17,6 +17,7 @@
|
||||
#include "nsCOMPtr.h" // for nsCOMPtr
|
||||
#include "nsHashKeys.h" // for nsUint64HashKey
|
||||
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
|
||||
class nsIObserver;
|
||||
|
||||
@ -29,7 +30,8 @@ struct FrameMetrics;
|
||||
|
||||
class CompositorChild MOZ_FINAL : public PCompositorChild
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(CompositorChild)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorChild)
|
||||
|
||||
public:
|
||||
CompositorChild(ClientLayerManager *aLayerManager);
|
||||
|
||||
|
@ -103,7 +103,7 @@ void ReleaseImageBridgeParentSingleton();
|
||||
|
||||
class CompositorThreadHolder MOZ_FINAL
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorThreadHolder)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorThreadHolder)
|
||||
|
||||
public:
|
||||
CompositorThreadHolder()
|
||||
@ -138,13 +138,10 @@ private:
|
||||
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
|
||||
static bool sFinishedCompositorShutDown = false;
|
||||
|
||||
static MessageLoop* sMainLoop = nullptr;
|
||||
|
||||
/* static */ Thread*
|
||||
CompositorThreadHolder::CreateCompositorThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
sMainLoop = MessageLoop::current();
|
||||
|
||||
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
||||
|
||||
@ -321,20 +318,11 @@ CompositorParent::RecvWillStop()
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeferredDeleteCompositorParentOnMainThread(CompositorParent* aNowReadyToDie)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
aNowReadyToDie->mCompositorThreadHolder = nullptr;
|
||||
aNowReadyToDie->Release();
|
||||
}
|
||||
|
||||
static void DeferredDeleteCompositorParentOnIOThread(CompositorParent* aToBeDeletedOnMainThread)
|
||||
void CompositorParent::DeferredDestroy()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(sMainLoop);
|
||||
sMainLoop->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(&DeferredDeleteCompositorParentOnMainThread,
|
||||
aToBeDeletedOnMainThread));
|
||||
mCompositorThreadHolder = nullptr;
|
||||
Release();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -346,10 +334,9 @@ CompositorParent::RecvStop()
|
||||
// this thread.
|
||||
// We must keep the compositor parent alive untill the code handling message
|
||||
// reception is finished on this thread.
|
||||
this->AddRef(); // Corresponds to DeferredDeleteCompositorParentOnMainThread's Release
|
||||
this->AddRef(); // Corresponds to DeferredDestroy's Release
|
||||
MessageLoop::current()->PostTask(FROM_HERE,
|
||||
NewRunnableFunction(&DeferredDeleteCompositorParentOnIOThread,
|
||||
this));
|
||||
NewRunnableMethod(this,&CompositorParent::DeferredDestroy));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1129,7 +1116,7 @@ class CrossProcessCompositorParent MOZ_FINAL : public PCompositorParent,
|
||||
{
|
||||
friend class CompositorParent;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrossProcessCompositorParent)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CrossProcessCompositorParent)
|
||||
public:
|
||||
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
|
||||
: mTransport(aTransport)
|
||||
@ -1201,7 +1188,7 @@ private:
|
||||
// Child side's process Id.
|
||||
base::ProcessId mChildProcessId;
|
||||
|
||||
const nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
||||
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
||||
};
|
||||
|
||||
void
|
||||
@ -1463,12 +1450,8 @@ CrossProcessCompositorParent::GetCompositionManager(LayerTransactionParent* aLay
|
||||
void
|
||||
CrossProcessCompositorParent::DeferredDestroy()
|
||||
{
|
||||
CrossProcessCompositorParent* self;
|
||||
mSelfRef.forget(&self);
|
||||
|
||||
MOZ_ASSERT(sMainLoop);
|
||||
sMainLoop->PostTask(FROM_HERE,
|
||||
NewRunnableMethod(self, &CrossProcessCompositorParent::Release));
|
||||
mCompositorThreadHolder = nullptr;
|
||||
mSelfRef = nullptr;
|
||||
}
|
||||
|
||||
CrossProcessCompositorParent::~CrossProcessCompositorParent()
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsSize.h" // for nsIntSize
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
|
||||
class CancelableTask;
|
||||
class MessageLoop;
|
||||
@ -68,7 +69,7 @@ class CompositorThreadHolder;
|
||||
class CompositorParent : public PCompositorParent,
|
||||
public ShadowLayersManager
|
||||
{
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
|
||||
|
||||
public:
|
||||
CompositorParent(nsIWidget* aWidget,
|
||||
@ -244,6 +245,8 @@ protected:
|
||||
// Protected destructor, to discourage deletion outside of Release():
|
||||
virtual ~CompositorParent();
|
||||
|
||||
void DeferredDestroy();
|
||||
|
||||
virtual PLayerTransactionParent*
|
||||
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
|
||||
const uint64_t& aId,
|
||||
@ -314,8 +317,6 @@ protected:
|
||||
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
|
||||
|
||||
friend void DeferredDeleteCompositorParentOnMainThread(CompositorParent* aNowReadyToDie);
|
||||
};
|
||||
|
||||
} // layers
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "mozilla/layers/PImageBridgeChild.h"
|
||||
#include "nsDebug.h" // for NS_RUNTIMEABORT
|
||||
#include "nsRegion.h" // for nsIntRegion
|
||||
|
||||
class MessageLoop;
|
||||
struct nsIntPoint;
|
||||
struct nsIntRect;
|
||||
|
@ -0,0 +1,83 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef THREADSAFEREFCOUNTINGWITHMAINTHREADDESTRUCTION_H_
|
||||
#define THREADSAFEREFCOUNTINGWITHMAINTHREADDESTRUCTION_H_
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
inline MessageLoop* GetMainLoopAssertingMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return MessageLoop::current();
|
||||
}
|
||||
|
||||
inline MessageLoop* GetMainLoop()
|
||||
{
|
||||
static MessageLoop* sMainLoop = GetMainLoopAssertingMainThread();
|
||||
return sMainLoop;
|
||||
}
|
||||
|
||||
struct HelperForMainThreadDestruction
|
||||
{
|
||||
HelperForMainThreadDestruction()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetMainLoop();
|
||||
}
|
||||
|
||||
~HelperForMainThreadDestruction()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(_class) \
|
||||
public: \
|
||||
NS_METHOD_(MozExternalRefCountType) AddRef(void) { \
|
||||
MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(_class) \
|
||||
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
|
||||
nsrefcnt count = ++mRefCnt; \
|
||||
NS_LOG_ADDREF(this, count, #_class, sizeof(*this)); \
|
||||
return (nsrefcnt) count; \
|
||||
} \
|
||||
static void DestroyToBeCalledOnMainThread(_class* ptr) { \
|
||||
MOZ_ASSERT(NS_IsMainThread()); \
|
||||
NS_LOG_RELEASE(ptr, 0, #_class); \
|
||||
delete ptr; \
|
||||
} \
|
||||
NS_METHOD_(MozExternalRefCountType) Release(void) { \
|
||||
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release"); \
|
||||
nsrefcnt count = --mRefCnt; \
|
||||
if (count == 0) { \
|
||||
if (NS_IsMainThread()) { \
|
||||
NS_LOG_RELEASE(this, 0, #_class); \
|
||||
delete this; \
|
||||
} else { \
|
||||
/* no NS_LOG_RELEASE here, will be in the runnable */ \
|
||||
MessageLoop *l = ::mozilla::layers::GetMainLoop(); \
|
||||
l->PostTask(FROM_HERE, \
|
||||
NewRunnableFunction(&DestroyToBeCalledOnMainThread, \
|
||||
this)); \
|
||||
} \
|
||||
} else { \
|
||||
NS_LOG_RELEASE(this, count, #_class); \
|
||||
} \
|
||||
return count; \
|
||||
} \
|
||||
protected: \
|
||||
::mozilla::ThreadSafeAutoRefCnt mRefCnt; \
|
||||
private: \
|
||||
::mozilla::layers::HelperForMainThreadDestruction mHelperForMainThreadDestruction; \
|
||||
public:
|
||||
|
||||
#endif
|
@ -27,6 +27,7 @@ EXPORTS += [
|
||||
'ipc/CompositorChild.h',
|
||||
'ipc/CompositorParent.h',
|
||||
'ipc/ShadowLayersManager.h',
|
||||
'ipc/ThreadSafeRefcountingWithMainThreadDestruction.h',
|
||||
'Layers.h',
|
||||
'LayerScope.h',
|
||||
'LayersLogging.h',
|
||||
|
Loading…
Reference in New Issue
Block a user