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
a88b8b44ad
commit
9a085aa41f
@ -17,6 +17,7 @@
|
|||||||
#include "nsCOMPtr.h" // for nsCOMPtr
|
#include "nsCOMPtr.h" // for nsCOMPtr
|
||||||
#include "nsHashKeys.h" // for nsUint64HashKey
|
#include "nsHashKeys.h" // for nsUint64HashKey
|
||||||
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
|
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
|
||||||
|
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||||
|
|
||||||
class nsIObserver;
|
class nsIObserver;
|
||||||
|
|
||||||
@ -29,7 +30,8 @@ struct FrameMetrics;
|
|||||||
|
|
||||||
class CompositorChild MOZ_FINAL : public PCompositorChild
|
class CompositorChild MOZ_FINAL : public PCompositorChild
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_REFCOUNTING(CompositorChild)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorChild)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompositorChild(ClientLayerManager *aLayerManager);
|
CompositorChild(ClientLayerManager *aLayerManager);
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ void ReleaseImageBridgeParentSingleton();
|
|||||||
|
|
||||||
class CompositorThreadHolder MOZ_FINAL
|
class CompositorThreadHolder MOZ_FINAL
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorThreadHolder)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorThreadHolder)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompositorThreadHolder()
|
CompositorThreadHolder()
|
||||||
@ -138,13 +138,10 @@ private:
|
|||||||
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
|
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
|
||||||
static bool sFinishedCompositorShutDown = false;
|
static bool sFinishedCompositorShutDown = false;
|
||||||
|
|
||||||
static MessageLoop* sMainLoop = nullptr;
|
|
||||||
|
|
||||||
/* static */ Thread*
|
/* static */ Thread*
|
||||||
CompositorThreadHolder::CreateCompositorThread()
|
CompositorThreadHolder::CreateCompositorThread()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
sMainLoop = MessageLoop::current();
|
|
||||||
|
|
||||||
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
|
||||||
|
|
||||||
@ -321,20 +318,11 @@ CompositorParent::RecvWillStop()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeferredDeleteCompositorParentOnMainThread(CompositorParent* aNowReadyToDie)
|
void CompositorParent::DeferredDestroy()
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
aNowReadyToDie->mCompositorThreadHolder = nullptr;
|
|
||||||
aNowReadyToDie->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DeferredDeleteCompositorParentOnIOThread(CompositorParent* aToBeDeletedOnMainThread)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
MOZ_ASSERT(sMainLoop);
|
mCompositorThreadHolder = nullptr;
|
||||||
sMainLoop->PostTask(FROM_HERE,
|
Release();
|
||||||
NewRunnableFunction(&DeferredDeleteCompositorParentOnMainThread,
|
|
||||||
aToBeDeletedOnMainThread));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -346,10 +334,9 @@ CompositorParent::RecvStop()
|
|||||||
// this thread.
|
// this thread.
|
||||||
// We must keep the compositor parent alive untill the code handling message
|
// We must keep the compositor parent alive untill the code handling message
|
||||||
// reception is finished on this thread.
|
// 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,
|
MessageLoop::current()->PostTask(FROM_HERE,
|
||||||
NewRunnableFunction(&DeferredDeleteCompositorParentOnIOThread,
|
NewRunnableMethod(this,&CompositorParent::DeferredDestroy));
|
||||||
this));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1129,7 +1116,7 @@ class CrossProcessCompositorParent MOZ_FINAL : public PCompositorParent,
|
|||||||
{
|
{
|
||||||
friend class CompositorParent;
|
friend class CompositorParent;
|
||||||
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrossProcessCompositorParent)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CrossProcessCompositorParent)
|
||||||
public:
|
public:
|
||||||
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
|
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
|
||||||
: mTransport(aTransport)
|
: mTransport(aTransport)
|
||||||
@ -1201,7 +1188,7 @@ private:
|
|||||||
// Child side's process Id.
|
// Child side's process Id.
|
||||||
base::ProcessId mChildProcessId;
|
base::ProcessId mChildProcessId;
|
||||||
|
|
||||||
const nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1463,12 +1450,8 @@ CrossProcessCompositorParent::GetCompositionManager(LayerTransactionParent* aLay
|
|||||||
void
|
void
|
||||||
CrossProcessCompositorParent::DeferredDestroy()
|
CrossProcessCompositorParent::DeferredDestroy()
|
||||||
{
|
{
|
||||||
CrossProcessCompositorParent* self;
|
mCompositorThreadHolder = nullptr;
|
||||||
mSelfRef.forget(&self);
|
mSelfRef = nullptr;
|
||||||
|
|
||||||
MOZ_ASSERT(sMainLoop);
|
|
||||||
sMainLoop->PostTask(FROM_HERE,
|
|
||||||
NewRunnableMethod(self, &CrossProcessCompositorParent::Release));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CrossProcessCompositorParent::~CrossProcessCompositorParent()
|
CrossProcessCompositorParent::~CrossProcessCompositorParent()
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "nsAutoPtr.h" // for nsRefPtr
|
#include "nsAutoPtr.h" // for nsRefPtr
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
#include "nsSize.h" // for nsIntSize
|
#include "nsSize.h" // for nsIntSize
|
||||||
|
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||||
|
|
||||||
class CancelableTask;
|
class CancelableTask;
|
||||||
class MessageLoop;
|
class MessageLoop;
|
||||||
@ -68,7 +69,7 @@ class CompositorThreadHolder;
|
|||||||
class CompositorParent : public PCompositorParent,
|
class CompositorParent : public PCompositorParent,
|
||||||
public ShadowLayersManager
|
public ShadowLayersManager
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompositorParent(nsIWidget* aWidget,
|
CompositorParent(nsIWidget* aWidget,
|
||||||
@ -244,6 +245,8 @@ protected:
|
|||||||
// Protected destructor, to discourage deletion outside of Release():
|
// Protected destructor, to discourage deletion outside of Release():
|
||||||
virtual ~CompositorParent();
|
virtual ~CompositorParent();
|
||||||
|
|
||||||
|
void DeferredDestroy();
|
||||||
|
|
||||||
virtual PLayerTransactionParent*
|
virtual PLayerTransactionParent*
|
||||||
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
|
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
|
||||||
const uint64_t& aId,
|
const uint64_t& aId,
|
||||||
@ -314,8 +317,6 @@ protected:
|
|||||||
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
||||||
|
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
|
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
|
||||||
|
|
||||||
friend void DeferredDeleteCompositorParentOnMainThread(CompositorParent* aNowReadyToDie);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // layers
|
} // layers
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "mozilla/layers/PImageBridgeChild.h"
|
#include "mozilla/layers/PImageBridgeChild.h"
|
||||||
#include "nsDebug.h" // for NS_RUNTIMEABORT
|
#include "nsDebug.h" // for NS_RUNTIMEABORT
|
||||||
#include "nsRegion.h" // for nsIntRegion
|
#include "nsRegion.h" // for nsIntRegion
|
||||||
|
|
||||||
class MessageLoop;
|
class MessageLoop;
|
||||||
struct nsIntPoint;
|
struct nsIntPoint;
|
||||||
struct nsIntRect;
|
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/CompositorChild.h',
|
||||||
'ipc/CompositorParent.h',
|
'ipc/CompositorParent.h',
|
||||||
'ipc/ShadowLayersManager.h',
|
'ipc/ShadowLayersManager.h',
|
||||||
|
'ipc/ThreadSafeRefcountingWithMainThreadDestruction.h',
|
||||||
'Layers.h',
|
'Layers.h',
|
||||||
'LayerScope.h',
|
'LayerScope.h',
|
||||||
'LayersLogging.h',
|
'LayersLogging.h',
|
||||||
|
Loading…
Reference in New Issue
Block a user