From 6f52581979e57b0f01c1f8fb58bb4ed06e5a1816 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 4 Jul 2014 21:24:32 -0400 Subject: [PATCH] back out bug 774388 and bug 1028383 for intermittent e10s mochitest-2 crashes --- gfx/layers/AtomicRefCountedWithFinalize.h | 28 +-- gfx/layers/ipc/CompositorChild.h | 4 +- gfx/layers/ipc/CompositorParent.cpp | 238 +++++++----------- gfx/layers/ipc/CompositorParent.h | 44 +++- gfx/layers/ipc/ImageBridgeChild.cpp | 11 +- gfx/layers/ipc/ImageBridgeChild.h | 1 - gfx/layers/ipc/ImageBridgeParent.cpp | 53 ++-- gfx/layers/ipc/ImageBridgeParent.h | 2 - ...SafeRefcountingWithMainThreadDestruction.h | 83 ------ gfx/layers/moz.build | 1 - ipc/glue/ProtocolUtils.cpp | 3 - ipc/glue/ProtocolUtils.h | 4 - xpcom/build/nsXPComInit.cpp | 8 +- 13 files changed, 162 insertions(+), 318 deletions(-) delete mode 100644 gfx/layers/ipc/ThreadSafeRefcountingWithMainThreadDestruction.h diff --git a/gfx/layers/AtomicRefCountedWithFinalize.h b/gfx/layers/AtomicRefCountedWithFinalize.h index 27795694808..2e77833c783 100644 --- a/gfx/layers/AtomicRefCountedWithFinalize.h +++ b/gfx/layers/AtomicRefCountedWithFinalize.h @@ -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(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(this); recycleCallback(derived, mClosure); @@ -96,7 +71,6 @@ private: RecycleCallback mRecycleCallback; void *mClosure; Atomic mRefCount; - MessageLoop *mMessageLoopToPostDestructionTo; }; } diff --git a/gfx/layers/ipc/CompositorChild.h b/gfx/layers/ipc/CompositorChild.h index 50af4d4f071..f59e21a316c 100644 --- a/gfx/layers/ipc/CompositorChild.h +++ b/gfx/layers/ipc/CompositorChild.h @@ -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); diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index eaf960d03af..11b8435c406 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -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 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 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 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 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 mCompositorThreadHolder; }; void @@ -1220,8 +1176,6 @@ OpenCompositor(CrossProcessCompositorParent* aCompositor, /*static*/ PCompositorParent* CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess) { - gfxPlatform::InitLayersIPC(); - nsRefPtr 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 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(mTransport)); } diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 728cc242387..de41299ef88 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -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& 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 mApzcTreeManager; - nsRefPtr mCompositorThreadHolder; - DISALLOW_EVIL_CONSTRUCTORS(CompositorParent); }; diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index f8cbe127d11..c8abcff401a 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -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; } diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index 214bd19dfa0..124c9f773c4 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -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; diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index 37d0f8cfc64..40920d559c2 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -44,8 +44,6 @@ using namespace mozilla::gfx; std::map 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(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 runnable = new ReleaseRunnable(self); + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable))); } ImageBridgeParent* diff --git a/gfx/layers/ipc/ImageBridgeParent.h b/gfx/layers/ipc/ImageBridgeParent.h index bcd513e44ff..a356d9096cb 100644 --- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -151,8 +151,6 @@ private: * Map of all living ImageBridgeParent instances */ static std::map sImageBridges; - - static MessageLoop* sMainLoop; }; } // layers diff --git a/gfx/layers/ipc/ThreadSafeRefcountingWithMainThreadDestruction.h b/gfx/layers/ipc/ThreadSafeRefcountingWithMainThreadDestruction.h deleted file mode 100644 index 0d5f39235d2..00000000000 --- a/gfx/layers/ipc/ThreadSafeRefcountingWithMainThreadDestruction.h +++ /dev/null @@ -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 \ No newline at end of file diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index 8d021197ad2..eb7123dea67 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -27,7 +27,6 @@ EXPORTS += [ 'ipc/CompositorChild.h', 'ipc/CompositorParent.h', 'ipc/ShadowLayersManager.h', - 'ipc/ThreadSafeRefcountingWithMainThreadDestruction.h', 'Layers.h', 'LayerScope.h', 'LayersLogging.h', diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index 70374428394..ff059ae84fb 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -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; diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index 1d37a2cb59e..48c2b75c545 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -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 @@ -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(); } diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index c53bb94a749..efab931019f 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -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);