Backed out 10 changesets (bug 1033358, bug 774388, bug 1028383) for causing frequent shutdown crashes on a CLOSED TREE.

Backed out changeset a54b05c9e4a1 (bug 1028383)
Backed out changeset 37985f79e0c2 (bug 774388)
Backed out changeset d07521729077 (bug 774388)
Backed out changeset 9f14b17f358c (bug 774388)
Backed out changeset 2d347d6aa9bc (bug 774388)
Backed out changeset 99581dfb5ec4 (bug 774388)
Backed out changeset 2532e22d6135 (bug 774388)
Backed out changeset 719844108f1a (bug 774388)
Backed out changeset 7829c78348a4 (bug 1033358)
Backed out changeset c571df9a85de (bug 1033358)
This commit is contained in:
Ryan VanderMeulen 2014-07-03 20:37:05 -04:00
parent ab939fdfed
commit 133741f11d
17 changed files with 199 additions and 308 deletions

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,25 +51,18 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
, mTransport(aTransport)
, mChildProcessId(aChildProcessId)
{
MOZ_ASSERT(NS_IsMainThread());
// 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()
{
MOZ_ASSERT(NS_IsMainThread());
if (mTransport) {
MOZ_ASSERT(XRE_GetIOMessageLoop());
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(mTransport));
}
sImageBridges.erase(mChildProcessId);
}
@ -274,11 +265,23 @@ MessageLoop * ImageBridgeParent::GetMessageLoop() const {
return mMessageLoop;
}
static void
DeferredReleaseImageBridgeParentOnMainThread(ImageBridgeParent* aDyingImageBridgeParent)
class ReleaseRunnable : public nsRunnable
{
aDyingImageBridgeParent->Release();
}
public:
ReleaseRunnable(ImageBridgeParent* aRef)
: mRef(aRef)
{
}
NS_IMETHOD Run()
{
mRef->Release();
return NS_OK;
}
private:
ImageBridgeParent* mRef;
};
void
ImageBridgeParent::DeferredDestroy()
@ -286,9 +289,8 @@ ImageBridgeParent::DeferredDestroy()
ImageBridgeParent* self;
mSelfRef.forget(&self);
sMainLoop->PostTask(
FROM_HERE,
NewRunnableFunction(&DeferredReleaseImageBridgeParentOnMainThread, this));
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

@ -18,7 +18,6 @@
#include "nsStackWalkPrivate.h"
#include "nsStackWalk.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#ifdef XP_WIN
@ -920,8 +919,6 @@ nsTraceRefcnt::DemangleSymbol(const char* aSymbol,
EXPORT_XPCOM_API(void)
NS_LogInit()
{
NS_SetMainThread();
// FIXME: This is called multiple times, we should probably not allow that.
#ifdef STACKWALKING_AVAILABLE
StackWalkInitCriticalAddress();

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);

View File

@ -28,8 +28,21 @@ extern NS_COM_GLUE NS_METHOD NS_GetMainThread(nsIThread** aResult);
extern NS_COM_GLUE nsIThread* NS_GetCurrentThread();
#endif
#ifdef MOZILLA_INTERNAL_API
#if defined(MOZILLA_INTERNAL_API) && defined(XP_WIN)
bool NS_IsMainThread();
#elif defined(MOZILLA_INTERNAL_API) && defined(NS_TLS)
// This is defined in nsThreadManager.cpp and initialized to `Main` for the
// main thread by nsThreadManager::Init.
extern NS_TLS mozilla::threads::ID gTLSThreadID;
#ifdef MOZ_ASAN
// Temporary workaround, see bug 895845
MOZ_ASAN_BLACKLIST bool NS_IsMainThread();
#else
inline bool NS_IsMainThread()
{
return gTLSThreadID == mozilla::threads::Main;
}
#endif
#else
/**
* Test to see if the current thread is the main thread.

View File

@ -125,7 +125,34 @@ NS_GetMainThread(nsIThread** aResult)
#endif
}
#ifndef MOZILLA_INTERNAL_API
#if defined(MOZILLA_INTERNAL_API) && defined(XP_WIN)
extern DWORD gTLSThreadIDIndex;
bool
NS_IsMainThread()
{
return TlsGetValue(gTLSThreadIDIndex) == (void*)mozilla::threads::Main;
}
#elif defined(MOZILLA_INTERNAL_API) && defined(NS_TLS)
#ifdef MOZ_ASAN
// Temporary workaround, see bug 895845
bool
NS_IsMainThread()
{
return gTLSThreadID == mozilla::threads::Main;
}
#else
// NS_IsMainThread() is defined inline in MainThreadUtils.h
#endif
#else
#ifdef MOZILLA_INTERNAL_API
bool
NS_IsMainThread()
{
bool result = false;
nsThreadManager::get()->nsThreadManager::GetIsMainThread(&result);
return bool(result);
}
#else
bool
NS_IsMainThread()
{
@ -138,6 +165,7 @@ NS_IsMainThread()
return bool(result);
}
#endif
#endif
NS_METHOD
NS_DispatchToCurrentThread(nsIRunnable* aEvent)
@ -328,9 +356,7 @@ nsThreadPoolNaming::SetThreadPoolName(const nsACString& aPoolName,
NS_SetThreadName(aThread, name);
} else {
// Set on the current thread
#ifndef XPCOM_GLUE_AVOID_NSPR
PR_SetCurrentThreadName(name.BeginReading());
#endif
}
}

View File

@ -565,7 +565,6 @@ private:
#endif
};
void
NS_SetMainThread();
#endif // nsThreadUtils_h__

View File

@ -10,7 +10,6 @@
#include "nsIClassInfoImpl.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "mozilla/ThreadLocal.h"
#ifdef MOZ_CANARY
#include <fcntl.h>
#include <unistd.h>
@ -25,26 +24,6 @@ DWORD gTLSThreadIDIndex = TlsAlloc();
NS_TLS mozilla::threads::ID gTLSThreadID = mozilla::threads::Generic;
#endif
static mozilla::ThreadLocal<bool> sTLSIsMainThread;
bool
NS_IsMainThread()
{
return sTLSIsMainThread.get();
}
void
NS_SetMainThread()
{
if (!sTLSIsMainThread.initialized()) {
if (!sTLSIsMainThread.init()) {
MOZ_CRASH();
}
sTLSIsMainThread.set(true);
}
MOZ_ASSERT(NS_IsMainThread());
}
typedef nsTArray<nsRefPtr<nsThread>> nsThreadArray;
//-----------------------------------------------------------------------------