back out bug 774388 and bug 1028383 for intermittent e10s mochitest-2 crashes

This commit is contained in:
Benoit Jacob 2014-07-04 21:24:32 -04:00
parent d138da640f
commit 6f52581979
13 changed files with 162 additions and 318 deletions

View File

@ -8,10 +8,6 @@
#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 {
@ -22,21 +18,10 @@ 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);
@ -58,17 +43,7 @@ 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));
}
}
delete derived;
} else if (1 == currCount && recycleCallback) {
T* derived = static_cast<T*>(this);
recycleCallback(derived, mClosure);
@ -96,7 +71,6 @@ private:
RecycleCallback mRecycleCallback;
void *mClosure;
Atomic<int> mRefCount;
MessageLoop *mMessageLoopToPostDestructionTo;
};
}

View File

@ -17,7 +17,6 @@
#include "nsCOMPtr.h" // for nsCOMPtr
#include "nsHashKeys.h" // for nsUint64HashKey
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
class nsIObserver;
@ -30,8 +29,7 @@ struct FrameMetrics;
class CompositorChild MOZ_FINAL : public PCompositorChild
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorChild)
NS_INLINE_DECL_REFCOUNTING(CompositorChild)
public:
CompositorChild(ClientLayerManager *aLayerManager);

View File

@ -53,7 +53,6 @@
#include "mozilla/unused.h"
#include "mozilla/Hal.h"
#include "mozilla/HalTypes.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
namespace layers {
@ -74,78 +73,64 @@ CompositorParent::LayerTreeState::LayerTreeState()
typedef map<uint64_t, CompositorParent::LayerTreeState> LayerTreeMap;
static LayerTreeMap sIndirectLayerTrees;
/**
* A global map referencing each compositor by ID.
*
* This map is used by the ImageBridge protocol to trigger
* compositions without having to keep references to the
* compositor
*/
typedef map<uint64_t,CompositorParent*> CompositorMap;
static CompositorMap* sCompositorMap;
static void CreateCompositorMap()
{
MOZ_ASSERT(!sCompositorMap);
sCompositorMap = new CompositorMap;
}
static void DestroyCompositorMap()
{
MOZ_ASSERT(sCompositorMap);
MOZ_ASSERT(sCompositorMap->empty());
delete sCompositorMap;
sCompositorMap = nullptr;
}
// FIXME/bug 774386: we're assuming that there's only one
// CompositorParent, but that's not always true. This assumption only
// affects CrossProcessCompositorParent below.
static Thread* sCompositorThread = nullptr;
// manual reference count of the compositor thread.
static int sCompositorThreadRefCount = 0;
static MessageLoop* sMainLoop = nullptr;
// See ImageBridgeChild.cpp
void ReleaseImageBridgeParentSingleton();
class CompositorThreadHolder MOZ_FINAL
static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie)
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorThreadHolder)
aNowReadyToDie->Release();
}
public:
CompositorThreadHolder()
: mCompositorThread(CreateCompositorThread())
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_CTOR(CompositorThreadHolder);
}
Thread* GetCompositorThread() const {
return mCompositorThread;
}
private:
~CompositorThreadHolder()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_DTOR(CompositorThreadHolder);
DestroyCompositorThread(mCompositorThread);
}
Thread* const mCompositorThread;
static Thread* CreateCompositorThread();
static void DestroyCompositorThread(Thread* aCompositorThread);
friend class CompositorParent;
};
static StaticRefPtr<CompositorThreadHolder> sCompositorThreadHolder;
static bool sFinishedCompositorShutDown = false;
/* static */ Thread*
CompositorThreadHolder::CreateCompositorThread()
static void DeleteCompositorThread()
{
MOZ_ASSERT(NS_IsMainThread());
if (NS_IsMainThread()){
ReleaseImageBridgeParentSingleton();
delete sCompositorThread;
sCompositorThread = nullptr;
} else {
sMainLoop->PostTask(FROM_HERE, NewRunnableFunction(&DeleteCompositorThread));
}
}
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
static void ReleaseCompositorThread()
{
if(--sCompositorThreadRefCount == 0) {
DeleteCompositorThread();
}
}
Thread* compositorThread = new Thread("Compositor");
static void SetThreadPriority()
{
hal::SetCurrentThreadPriority(hal::THREAD_PRIORITY_COMPOSITOR);
}
void CompositorParent::StartUp()
{
CreateCompositorMap();
CreateThread();
sMainLoop = MessageLoop::current();
}
void CompositorParent::ShutDown()
{
DestroyThread();
DestroyCompositorMap();
}
bool CompositorParent::CreateThread()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
MOZ_ASSERT(!sCompositorThread);
sCompositorThreadRefCount = 1;
sCompositorThread = new Thread("Compositor");
Thread::Options options;
/* Timeout values are powers-of-two to enable us get better data.
@ -156,63 +141,24 @@ CompositorThreadHolder::CreateCompositorThread()
than the default hang timeout on major platforms (about 5 seconds). */
options.permanent_hang_timeout = 8192; // milliseconds
if (!compositorThread->StartWithOptions(options)) {
delete compositorThread;
return nullptr;
if (!sCompositorThread->StartWithOptions(options)) {
delete sCompositorThread;
sCompositorThread = nullptr;
return false;
}
CreateCompositorMap();
return compositorThread;
return true;
}
/* static */ void
CompositorThreadHolder::DestroyCompositorThread(Thread* aCompositorThread)
void CompositorParent::DestroyThread()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sCompositorThreadHolder, "We shouldn't be destroying the compositor thread yet.");
DestroyCompositorMap();
ReleaseImageBridgeParentSingleton();
delete aCompositorThread;
sFinishedCompositorShutDown = true;
}
static Thread* CompositorThread() {
return sCompositorThreadHolder ? sCompositorThreadHolder->GetCompositorThread() : nullptr;
}
static void SetThreadPriority()
{
hal::SetCurrentThreadPriority(hal::THREAD_PRIORITY_COMPOSITOR);
}
void CompositorParent::StartUp()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
MOZ_ASSERT(!sCompositorThreadHolder, "The compositor thread has already been started!");
sCompositorThreadHolder = new CompositorThreadHolder();
}
void CompositorParent::ShutDown()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
MOZ_ASSERT(sCompositorThreadHolder, "The compositor thread has already been shut down!");
sCompositorThreadHolder = nullptr;
// No locking is needed around sFinishedCompositorShutDown because it is only
// ever accessed on the main thread.
while (!sFinishedCompositorShutDown) {
NS_ProcessNextEvent(nullptr, true);
}
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
ReleaseCompositorThread();
}
MessageLoop* CompositorParent::CompositorLoop()
{
return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
return sCompositorThread ? sCompositorThread->message_loop() : nullptr;
}
CompositorParent::CompositorParent(nsIWidget* aWidget,
@ -229,11 +175,9 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
, mResumeCompositionMonitor("ResumeCompositionMonitor")
, mOverrideComposeReadiness(false)
, mForceCompositionTask(nullptr)
, mCompositorThreadHolder(sCompositorThreadHolder)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(CompositorThread(),
"The compositor thread must be Initialized before instanciating a CompositorParent.");
MOZ_ASSERT(sCompositorThread != nullptr,
"The compositor thread must be Initialized before instanciating a CmpositorParent.");
MOZ_COUNT_CTOR(CompositorParent);
mCompositorID = 0;
// FIXME: This holds on the the fact that right now the only thing that
@ -248,12 +192,13 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
mApzcTreeManager = new APZCTreeManager();
++sCompositorThreadRefCount;
}
bool
CompositorParent::IsInCompositorThread()
{
return CompositorThread() && CompositorThread()->thread_id() == PlatformThread::CurrentId();
return sCompositorThread && sCompositorThread->thread_id() == PlatformThread::CurrentId();
}
uint64_t
@ -264,8 +209,9 @@ CompositorParent::RootLayerTreeId()
CompositorParent::~CompositorParent()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_DTOR(CompositorParent);
ReleaseCompositorThread();
}
void
@ -318,13 +264,6 @@ CompositorParent::RecvWillStop()
return true;
}
void CompositorParent::DeferredDestroy()
{
MOZ_ASSERT(!NS_IsMainThread());
mCompositorThreadHolder = nullptr;
Release();
}
bool
CompositorParent::RecvStop()
{
@ -334,9 +273,10 @@ 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 DeferredDestroy's Release
MessageLoop::current()->PostTask(FROM_HERE,
NewRunnableMethod(this,&CompositorParent::DeferredDestroy));
this->AddRef(); // Corresponds to DeferredDeleteCompositorParent's Release
CompositorLoop()->PostTask(FROM_HERE,
NewRunnableFunction(&DeferredDeleteCompositorParent,
this));
return true;
}
@ -981,6 +921,27 @@ CompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
return true;
}
typedef map<uint64_t,CompositorParent*> CompositorMap;
static CompositorMap* sCompositorMap;
void CompositorParent::CreateCompositorMap()
{
if (sCompositorMap == nullptr) {
sCompositorMap = new CompositorMap;
}
}
void CompositorParent::DestroyCompositorMap()
{
if (sCompositorMap != nullptr) {
NS_ASSERTION(sCompositorMap->empty(),
"The Compositor map should be empty when destroyed>");
delete sCompositorMap;
sCompositorMap = nullptr;
}
}
CompositorParent* CompositorParent::GetCompositor(uint64_t id)
{
CompositorMap::iterator it = sCompositorMap->find(id);
@ -1116,15 +1077,12 @@ class CrossProcessCompositorParent MOZ_FINAL : public PCompositorParent,
{
friend class CompositorParent;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CrossProcessCompositorParent)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrossProcessCompositorParent)
public:
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
: mTransport(aTransport)
, mChildProcessId(aOtherProcess)
, mCompositorThreadHolder(sCompositorThreadHolder)
{
MOZ_ASSERT(NS_IsMainThread());
}
{}
// IToplevelProtocol::CloneToplevel()
virtual IToplevelProtocol*
@ -1187,8 +1145,6 @@ private:
Transport* mTransport;
// Child side's process Id.
base::ProcessId mChildProcessId;
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
};
void
@ -1220,8 +1176,6 @@ OpenCompositor(CrossProcessCompositorParent* aCompositor,
/*static*/ PCompositorParent*
CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
{
gfxPlatform::InitLayersIPC();
nsRefPtr<CrossProcessCompositorParent> cpcp =
new CrossProcessCompositorParent(aTransport, aOtherProcess);
ProcessHandle handle;
@ -1450,14 +1404,16 @@ CrossProcessCompositorParent::GetCompositionManager(LayerTransactionParent* aLay
void
CrossProcessCompositorParent::DeferredDestroy()
{
mCompositorThreadHolder = nullptr;
mSelfRef = nullptr;
CrossProcessCompositorParent* self;
mSelfRef.forget(&self);
nsCOMPtr<nsIRunnable> runnable =
NS_NewNonOwningRunnableMethod(self, &CrossProcessCompositorParent::Release);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
}
CrossProcessCompositorParent::~CrossProcessCompositorParent()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(XRE_GetIOMessageLoop());
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(mTransport));
}

View File

@ -33,7 +33,6 @@
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsISupportsImpl.h"
#include "nsSize.h" // for nsIntSize
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
class CancelableTask;
class MessageLoop;
@ -64,12 +63,10 @@ private:
uint64_t mLayersId;
};
class CompositorThreadHolder;
class CompositorParent : public PCompositorParent,
public ShadowLayersManager
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
public:
CompositorParent(nsIWidget* aWidget,
@ -169,10 +166,7 @@ public:
static void StartUp();
/**
* Waits for all [CrossProcess]CompositorParent's to be gone,
* and destroys the compositor thread and global compositor map.
*
* Does not return until all of that has completed.
* Destroys the compositor thread and the global compositor map.
*/
static void ShutDown();
@ -245,8 +239,6 @@ protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~CompositorParent();
void DeferredDestroy();
virtual PLayerTransactionParent*
AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aBackendHints,
const uint64_t& aId,
@ -267,6 +259,36 @@ protected:
void ForceComposition();
void CancelCurrentCompositeTask();
/**
* Creates a global map referencing each compositor by ID.
*
* This map is used by the ImageBridge protocol to trigger
* compositions without having to keep references to the
* compositor
*/
static void CreateCompositorMap();
static void DestroyCompositorMap();
/**
* Creates the compositor thread.
*
* All compositors live on the same thread.
* The thread is not lazily created on first access to avoid dealing with
* thread safety. Therefore it's best to create and destroy the thread when
* we know we areb't using it (So creating/destroying along with gfxPlatform
* looks like a good place).
*/
static bool CreateThread();
/**
* Destroys the compositor thread.
*
* It is safe to call this fucntion more than once, although the second call
* will have no effect.
* This function is not thread-safe.
*/
static void DestroyThread();
/**
* Add a compositor to the global compositor map.
*/
@ -314,8 +336,6 @@ protected:
nsRefPtr<APZCTreeManager> mApzcTreeManager;
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};

View File

@ -221,6 +221,7 @@ static void ImageBridgeShutdownStep2(ReentrantMonitor *aBarrier, bool *aDone)
sImageBridgeChildSingleton->SendStop();
sImageBridgeChildSingleton = nullptr;
*aDone = true;
aBarrier->NotifyAll();
}
@ -247,14 +248,10 @@ static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * par
ImageBridgeChild::ImageBridgeChild()
: mShuttingDown(false)
{
MOZ_ASSERT(NS_IsMainThread());
mTxn = new CompositableTransaction();
}
ImageBridgeChild::~ImageBridgeChild()
{
MOZ_ASSERT(NS_IsMainThread());
delete mTxn;
}
@ -550,7 +547,7 @@ PImageBridgeChild*
ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
ProcessId aOtherProcess)
{
MOZ_ASSERT(NS_IsMainThread());
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
gfxPlatform::GetPlatform();
@ -575,7 +572,7 @@ ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
void ImageBridgeChild::ShutDown()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
if (ImageBridgeChild::IsCreated()) {
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
@ -603,8 +600,6 @@ void ImageBridgeChild::ShutDown()
}
}
sImageBridgeChildSingleton = nullptr;
delete sImageBridgeChildThread;
sImageBridgeChildThread = nullptr;
}

View File

@ -17,7 +17,6 @@
#include "mozilla/layers/PImageBridgeChild.h"
#include "nsDebug.h" // for NS_RUNTIMEABORT
#include "nsRegion.h" // for nsIntRegion
class MessageLoop;
struct nsIntPoint;
struct nsIntRect;

View File

@ -44,8 +44,6 @@ using namespace mozilla::gfx;
std::map<base::ProcessId, ImageBridgeParent*> ImageBridgeParent::sImageBridges;
MessageLoop* ImageBridgeParent::sMainLoop = nullptr;
ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
Transport* aTransport,
ProcessId aChildProcessId)
@ -53,12 +51,6 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
, mTransport(aTransport)
, 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();
@ -67,14 +59,10 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
ImageBridgeParent::~ImageBridgeParent()
{
MOZ_ASSERT(NS_IsMainThread());
if (mTransport) {
MOZ_ASSERT(XRE_GetIOMessageLoop());
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(mTransport));
}
sImageBridges.erase(mChildProcessId);
}
@ -172,25 +160,10 @@ bool ImageBridgeParent::RecvWillStop()
return true;
}
static void
ReleaseImageBridgeParent(ImageBridgeParent* aImageBridgeParent)
{
aImageBridgeParent->Release();
}
bool ImageBridgeParent::RecvStop()
{
// This message just serves as synchronization between the
// Nothing to do. This message just serves as synchronization between the
// child and parent threads during shutdown.
// There is one thing that we need to do here: temporarily addref, so that
// the handling of this sync message can't race with the destruction of
// the ImageBridgeParent, which would trigger the dreaded "mismatched CxxStackFrames"
// assertion of MessageChannel.
AddRef();
MessageLoop::current()->PostTask(
FROM_HERE,
NewRunnableFunction(&ReleaseImageBridgeParent, this));
return true;
}
@ -292,10 +265,32 @@ MessageLoop * ImageBridgeParent::GetMessageLoop() const {
return mMessageLoop;
}
class ReleaseRunnable : public nsRunnable
{
public:
ReleaseRunnable(ImageBridgeParent* aRef)
: mRef(aRef)
{
}
NS_IMETHOD Run()
{
mRef->Release();
return NS_OK;
}
private:
ImageBridgeParent* mRef;
};
void
ImageBridgeParent::DeferredDestroy()
{
mSelfRef = nullptr;
ImageBridgeParent* self;
mSelfRef.forget(&self);
nsCOMPtr<nsIRunnable> runnable = new ReleaseRunnable(self);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
}
ImageBridgeParent*

View File

@ -151,8 +151,6 @@ private:
* Map of all living ImageBridgeParent instances
*/
static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
static MessageLoop* sMainLoop;
};
} // layers

View File

@ -1,83 +0,0 @@
/* 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

View File

@ -27,7 +27,6 @@ EXPORTS += [
'ipc/CompositorChild.h',
'ipc/CompositorParent.h',
'ipc/ShadowLayersManager.h',
'ipc/ThreadSafeRefcountingWithMainThreadDestruction.h',
'Layers.h',
'LayerScope.h',
'LayersLogging.h',

View File

@ -19,14 +19,11 @@ namespace ipc {
IToplevelProtocol::~IToplevelProtocol()
{
MOZ_ASSERT(NS_IsMainThread());
mOpenActors.clear();
}
void IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor)
{
MOZ_ASSERT(NS_IsMainThread());
#ifdef DEBUG
for (const IToplevelProtocol* actor = mOpenActors.getFirst();
actor;

View File

@ -21,7 +21,6 @@
#include "mozilla/ipc/Transport.h"
#include "mozilla/ipc/MessageLink.h"
#include "mozilla/LinkedList.h"
#include "MainThreadUtils.h"
#if defined(ANDROID) && defined(DEBUG)
#include <android/log.h>
@ -188,7 +187,6 @@ protected:
: mProtocolId(aProtoId)
, mTrans(nullptr)
{
MOZ_ASSERT(NS_IsMainThread());
}
~IToplevelProtocol();
@ -214,12 +212,10 @@ public:
*/
IToplevelProtocol* GetFirstOpenedActors()
{
MOZ_ASSERT(NS_IsMainThread());
return mOpenActors.getFirst();
}
const IToplevelProtocol* GetFirstOpenedActors() const
{
MOZ_ASSERT(NS_IsMainThread());
return mOpenActors.getFirst();
}

View File

@ -811,17 +811,17 @@ ShutdownXPCOM(nsIServiceManager* servMgr)
}
}
// This must happen after the shutdown of media and widgets, which
// are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
NS_ProcessPendingEvents(thread);
gfxPlatform::ShutdownLayersIPC();
mozilla::scache::StartupCache::DeleteSingleton();
if (observerService)
(void) observerService->
NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
nullptr);
// This must happen after the shutdown of media and widgets, which
// are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
gfxPlatform::ShutdownLayersIPC();
gXPCOMThreadsShutDown = true;
NS_ProcessPendingEvents(thread);