mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
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:
parent
3f9e56aab8
commit
6d9424856d
@ -17,7 +17,6 @@
|
|||||||
#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;
|
||||||
|
|
||||||
@ -30,8 +29,7 @@ struct FrameMetrics;
|
|||||||
|
|
||||||
class CompositorChild MOZ_FINAL : public PCompositorChild
|
class CompositorChild MOZ_FINAL : public PCompositorChild
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorChild)
|
NS_INLINE_DECL_REFCOUNTING(CompositorChild)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompositorChild(ClientLayerManager *aLayerManager);
|
CompositorChild(ClientLayerManager *aLayerManager);
|
||||||
|
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "mozilla/Hal.h"
|
#include "mozilla/Hal.h"
|
||||||
#include "mozilla/HalTypes.h"
|
#include "mozilla/HalTypes.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
@ -74,78 +73,64 @@ CompositorParent::LayerTreeState::LayerTreeState()
|
|||||||
typedef map<uint64_t, CompositorParent::LayerTreeState> LayerTreeMap;
|
typedef map<uint64_t, CompositorParent::LayerTreeState> LayerTreeMap;
|
||||||
static LayerTreeMap sIndirectLayerTrees;
|
static LayerTreeMap sIndirectLayerTrees;
|
||||||
|
|
||||||
/**
|
// FIXME/bug 774386: we're assuming that there's only one
|
||||||
* A global map referencing each compositor by ID.
|
// CompositorParent, but that's not always true. This assumption only
|
||||||
*
|
// affects CrossProcessCompositorParent below.
|
||||||
* This map is used by the ImageBridge protocol to trigger
|
static Thread* sCompositorThread = nullptr;
|
||||||
* compositions without having to keep references to the
|
// manual reference count of the compositor thread.
|
||||||
* compositor
|
static int sCompositorThreadRefCount = 0;
|
||||||
*/
|
static MessageLoop* sMainLoop = nullptr;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See ImageBridgeChild.cpp
|
// See ImageBridgeChild.cpp
|
||||||
void ReleaseImageBridgeParentSingleton();
|
void ReleaseImageBridgeParentSingleton();
|
||||||
|
|
||||||
class CompositorThreadHolder MOZ_FINAL
|
static void DeferredDeleteCompositorParent(CompositorParent* aNowReadyToDie)
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorThreadHolder)
|
aNowReadyToDie->Release();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
static void DeleteCompositorThread()
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
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;
|
Thread::Options options;
|
||||||
/* Timeout values are powers-of-two to enable us get better data.
|
/* 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). */
|
than the default hang timeout on major platforms (about 5 seconds). */
|
||||||
options.permanent_hang_timeout = 8192; // milliseconds
|
options.permanent_hang_timeout = 8192; // milliseconds
|
||||||
|
|
||||||
if (!compositorThread->StartWithOptions(options)) {
|
if (!sCompositorThread->StartWithOptions(options)) {
|
||||||
delete compositorThread;
|
delete sCompositorThread;
|
||||||
return nullptr;
|
sCompositorThread = nullptr;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateCompositorMap();
|
return true;
|
||||||
|
|
||||||
return compositorThread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void
|
void CompositorParent::DestroyThread()
|
||||||
CompositorThreadHolder::DestroyCompositorThread(Thread* aCompositorThread)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
|
||||||
|
ReleaseCompositorThread();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageLoop* CompositorParent::CompositorLoop()
|
MessageLoop* CompositorParent::CompositorLoop()
|
||||||
{
|
{
|
||||||
return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
|
return sCompositorThread ? sCompositorThread->message_loop() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositorParent::CompositorParent(nsIWidget* aWidget,
|
CompositorParent::CompositorParent(nsIWidget* aWidget,
|
||||||
@ -229,11 +175,9 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
|
|||||||
, mResumeCompositionMonitor("ResumeCompositionMonitor")
|
, mResumeCompositionMonitor("ResumeCompositionMonitor")
|
||||||
, mOverrideComposeReadiness(false)
|
, mOverrideComposeReadiness(false)
|
||||||
, mForceCompositionTask(nullptr)
|
, mForceCompositionTask(nullptr)
|
||||||
, mCompositorThreadHolder(sCompositorThreadHolder)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(sCompositorThread != nullptr,
|
||||||
MOZ_ASSERT(CompositorThread(),
|
"The compositor thread must be Initialized before instanciating a CmpositorParent.");
|
||||||
"The compositor thread must be Initialized before instanciating a CompositorParent.");
|
|
||||||
MOZ_COUNT_CTOR(CompositorParent);
|
MOZ_COUNT_CTOR(CompositorParent);
|
||||||
mCompositorID = 0;
|
mCompositorID = 0;
|
||||||
// FIXME: This holds on the the fact that right now the only thing that
|
// 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;
|
sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
|
||||||
|
|
||||||
mApzcTreeManager = new APZCTreeManager();
|
mApzcTreeManager = new APZCTreeManager();
|
||||||
|
++sCompositorThreadRefCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CompositorParent::IsInCompositorThread()
|
CompositorParent::IsInCompositorThread()
|
||||||
{
|
{
|
||||||
return CompositorThread() && CompositorThread()->thread_id() == PlatformThread::CurrentId();
|
return sCompositorThread && sCompositorThread->thread_id() == PlatformThread::CurrentId();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
@ -264,8 +209,9 @@ CompositorParent::RootLayerTreeId()
|
|||||||
|
|
||||||
CompositorParent::~CompositorParent()
|
CompositorParent::~CompositorParent()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_COUNT_DTOR(CompositorParent);
|
MOZ_COUNT_DTOR(CompositorParent);
|
||||||
|
|
||||||
|
ReleaseCompositorThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -318,13 +264,6 @@ CompositorParent::RecvWillStop()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompositorParent::DeferredDestroy()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
|
||||||
mCompositorThreadHolder = nullptr;
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CompositorParent::RecvStop()
|
CompositorParent::RecvStop()
|
||||||
{
|
{
|
||||||
@ -334,9 +273,10 @@ 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 DeferredDestroy's Release
|
this->AddRef(); // Corresponds to DeferredDeleteCompositorParent's Release
|
||||||
MessageLoop::current()->PostTask(FROM_HERE,
|
CompositorLoop()->PostTask(FROM_HERE,
|
||||||
NewRunnableMethod(this,&CompositorParent::DeferredDestroy));
|
NewRunnableFunction(&DeferredDeleteCompositorParent,
|
||||||
|
this));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -981,6 +921,27 @@ CompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
|
|||||||
return true;
|
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)
|
CompositorParent* CompositorParent::GetCompositor(uint64_t id)
|
||||||
{
|
{
|
||||||
CompositorMap::iterator it = sCompositorMap->find(id);
|
CompositorMap::iterator it = sCompositorMap->find(id);
|
||||||
@ -1116,15 +1077,12 @@ class CrossProcessCompositorParent MOZ_FINAL : public PCompositorParent,
|
|||||||
{
|
{
|
||||||
friend class CompositorParent;
|
friend class CompositorParent;
|
||||||
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CrossProcessCompositorParent)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CrossProcessCompositorParent)
|
||||||
public:
|
public:
|
||||||
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
|
CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
|
||||||
: mTransport(aTransport)
|
: mTransport(aTransport)
|
||||||
, mChildProcessId(aOtherProcess)
|
, mChildProcessId(aOtherProcess)
|
||||||
, mCompositorThreadHolder(sCompositorThreadHolder)
|
{}
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
}
|
|
||||||
|
|
||||||
// IToplevelProtocol::CloneToplevel()
|
// IToplevelProtocol::CloneToplevel()
|
||||||
virtual IToplevelProtocol*
|
virtual IToplevelProtocol*
|
||||||
@ -1187,8 +1145,6 @@ private:
|
|||||||
Transport* mTransport;
|
Transport* mTransport;
|
||||||
// Child side's process Id.
|
// Child side's process Id.
|
||||||
base::ProcessId mChildProcessId;
|
base::ProcessId mChildProcessId;
|
||||||
|
|
||||||
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1220,8 +1176,6 @@ OpenCompositor(CrossProcessCompositorParent* aCompositor,
|
|||||||
/*static*/ PCompositorParent*
|
/*static*/ PCompositorParent*
|
||||||
CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
|
CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
|
||||||
{
|
{
|
||||||
gfxPlatform::InitLayersIPC();
|
|
||||||
|
|
||||||
nsRefPtr<CrossProcessCompositorParent> cpcp =
|
nsRefPtr<CrossProcessCompositorParent> cpcp =
|
||||||
new CrossProcessCompositorParent(aTransport, aOtherProcess);
|
new CrossProcessCompositorParent(aTransport, aOtherProcess);
|
||||||
ProcessHandle handle;
|
ProcessHandle handle;
|
||||||
@ -1450,14 +1404,16 @@ CrossProcessCompositorParent::GetCompositionManager(LayerTransactionParent* aLay
|
|||||||
void
|
void
|
||||||
CrossProcessCompositorParent::DeferredDestroy()
|
CrossProcessCompositorParent::DeferredDestroy()
|
||||||
{
|
{
|
||||||
mCompositorThreadHolder = nullptr;
|
CrossProcessCompositorParent* self;
|
||||||
mSelfRef = nullptr;
|
mSelfRef.forget(&self);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIRunnable> runnable =
|
||||||
|
NS_NewNonOwningRunnableMethod(self, &CrossProcessCompositorParent::Release);
|
||||||
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CrossProcessCompositorParent::~CrossProcessCompositorParent()
|
CrossProcessCompositorParent::~CrossProcessCompositorParent()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(XRE_GetIOMessageLoop());
|
|
||||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||||
new DeleteTask<Transport>(mTransport));
|
new DeleteTask<Transport>(mTransport));
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#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;
|
||||||
@ -64,12 +63,10 @@ private:
|
|||||||
uint64_t mLayersId;
|
uint64_t mLayersId;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CompositorThreadHolder;
|
|
||||||
|
|
||||||
class CompositorParent : public PCompositorParent,
|
class CompositorParent : public PCompositorParent,
|
||||||
public ShadowLayersManager
|
public ShadowLayersManager
|
||||||
{
|
{
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompositorParent(nsIWidget* aWidget,
|
CompositorParent(nsIWidget* aWidget,
|
||||||
@ -169,10 +166,7 @@ public:
|
|||||||
static void StartUp();
|
static void StartUp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for all [CrossProcess]CompositorParent's to be gone,
|
* Destroys the compositor thread and the global compositor map.
|
||||||
* and destroys the compositor thread and global compositor map.
|
|
||||||
*
|
|
||||||
* Does not return until all of that has completed.
|
|
||||||
*/
|
*/
|
||||||
static void ShutDown();
|
static void ShutDown();
|
||||||
|
|
||||||
@ -245,8 +239,6 @@ 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,
|
||||||
@ -267,6 +259,36 @@ protected:
|
|||||||
void ForceComposition();
|
void ForceComposition();
|
||||||
void CancelCurrentCompositeTask();
|
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.
|
* Add a compositor to the global compositor map.
|
||||||
*/
|
*/
|
||||||
@ -314,8 +336,6 @@ protected:
|
|||||||
|
|
||||||
nsRefPtr<APZCTreeManager> mApzcTreeManager;
|
nsRefPtr<APZCTreeManager> mApzcTreeManager;
|
||||||
|
|
||||||
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
|
|
||||||
|
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
|
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,6 +221,7 @@ static void ImageBridgeShutdownStep2(ReentrantMonitor *aBarrier, bool *aDone)
|
|||||||
|
|
||||||
sImageBridgeChildSingleton->SendStop();
|
sImageBridgeChildSingleton->SendStop();
|
||||||
|
|
||||||
|
sImageBridgeChildSingleton = nullptr;
|
||||||
*aDone = true;
|
*aDone = true;
|
||||||
aBarrier->NotifyAll();
|
aBarrier->NotifyAll();
|
||||||
}
|
}
|
||||||
@ -247,14 +248,10 @@ static void ConnectImageBridge(ImageBridgeChild * child, ImageBridgeParent * par
|
|||||||
ImageBridgeChild::ImageBridgeChild()
|
ImageBridgeChild::ImageBridgeChild()
|
||||||
: mShuttingDown(false)
|
: mShuttingDown(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
mTxn = new CompositableTransaction();
|
mTxn = new CompositableTransaction();
|
||||||
}
|
}
|
||||||
ImageBridgeChild::~ImageBridgeChild()
|
ImageBridgeChild::~ImageBridgeChild()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
delete mTxn;
|
delete mTxn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +547,7 @@ PImageBridgeChild*
|
|||||||
ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
|
ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
|
||||||
ProcessId aOtherProcess)
|
ProcessId aOtherProcess)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
|
||||||
|
|
||||||
gfxPlatform::GetPlatform();
|
gfxPlatform::GetPlatform();
|
||||||
|
|
||||||
@ -575,7 +572,7 @@ ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
|
|||||||
|
|
||||||
void ImageBridgeChild::ShutDown()
|
void ImageBridgeChild::ShutDown()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
|
||||||
if (ImageBridgeChild::IsCreated()) {
|
if (ImageBridgeChild::IsCreated()) {
|
||||||
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
|
MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
|
||||||
|
|
||||||
@ -603,8 +600,6 @@ void ImageBridgeChild::ShutDown()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sImageBridgeChildSingleton = nullptr;
|
|
||||||
|
|
||||||
delete sImageBridgeChildThread;
|
delete sImageBridgeChildThread;
|
||||||
sImageBridgeChildThread = nullptr;
|
sImageBridgeChildThread = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#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;
|
||||||
|
@ -44,8 +44,6 @@ using namespace mozilla::gfx;
|
|||||||
|
|
||||||
std::map<base::ProcessId, ImageBridgeParent*> ImageBridgeParent::sImageBridges;
|
std::map<base::ProcessId, ImageBridgeParent*> ImageBridgeParent::sImageBridges;
|
||||||
|
|
||||||
MessageLoop* ImageBridgeParent::sMainLoop = nullptr;
|
|
||||||
|
|
||||||
ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
|
ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
|
||||||
Transport* aTransport,
|
Transport* aTransport,
|
||||||
ProcessId aChildProcessId)
|
ProcessId aChildProcessId)
|
||||||
@ -53,25 +51,18 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
|
|||||||
, mTransport(aTransport)
|
, mTransport(aTransport)
|
||||||
, mChildProcessId(aChildProcessId)
|
, mChildProcessId(aChildProcessId)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
// creates the map only if it has not been created already, so it is safe
|
// creates the map only if it has not been created already, so it is safe
|
||||||
// with several bridges
|
// with several bridges
|
||||||
CompositableMap::Create();
|
CompositableMap::Create();
|
||||||
sImageBridges[aChildProcessId] = this;
|
sImageBridges[aChildProcessId] = this;
|
||||||
sMainLoop = MessageLoop::current();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageBridgeParent::~ImageBridgeParent()
|
ImageBridgeParent::~ImageBridgeParent()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
if (mTransport) {
|
if (mTransport) {
|
||||||
MOZ_ASSERT(XRE_GetIOMessageLoop());
|
|
||||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||||
new DeleteTask<Transport>(mTransport));
|
new DeleteTask<Transport>(mTransport));
|
||||||
}
|
}
|
||||||
|
|
||||||
sImageBridges.erase(mChildProcessId);
|
sImageBridges.erase(mChildProcessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,11 +265,23 @@ MessageLoop * ImageBridgeParent::GetMessageLoop() const {
|
|||||||
return mMessageLoop;
|
return mMessageLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
class ReleaseRunnable : public nsRunnable
|
||||||
DeferredReleaseImageBridgeParentOnMainThread(ImageBridgeParent* aDyingImageBridgeParent)
|
|
||||||
{
|
{
|
||||||
aDyingImageBridgeParent->Release();
|
public:
|
||||||
}
|
ReleaseRunnable(ImageBridgeParent* aRef)
|
||||||
|
: mRef(aRef)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHOD Run()
|
||||||
|
{
|
||||||
|
mRef->Release();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageBridgeParent* mRef;
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
ImageBridgeParent::DeferredDestroy()
|
ImageBridgeParent::DeferredDestroy()
|
||||||
@ -286,9 +289,8 @@ ImageBridgeParent::DeferredDestroy()
|
|||||||
ImageBridgeParent* self;
|
ImageBridgeParent* self;
|
||||||
mSelfRef.forget(&self);
|
mSelfRef.forget(&self);
|
||||||
|
|
||||||
sMainLoop->PostTask(
|
nsCOMPtr<nsIRunnable> runnable = new ReleaseRunnable(self);
|
||||||
FROM_HERE,
|
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));
|
||||||
NewRunnableFunction(&DeferredReleaseImageBridgeParentOnMainThread, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageBridgeParent*
|
ImageBridgeParent*
|
||||||
|
@ -151,8 +151,6 @@ private:
|
|||||||
* Map of all living ImageBridgeParent instances
|
* Map of all living ImageBridgeParent instances
|
||||||
*/
|
*/
|
||||||
static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
|
static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
|
||||||
|
|
||||||
static MessageLoop* sMainLoop;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // layers
|
} // layers
|
||||||
|
@ -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
|
|
@ -27,7 +27,6 @@ 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',
|
||||||
|
@ -19,14 +19,11 @@ namespace ipc {
|
|||||||
|
|
||||||
IToplevelProtocol::~IToplevelProtocol()
|
IToplevelProtocol::~IToplevelProtocol()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
mOpenActors.clear();
|
mOpenActors.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor)
|
void IToplevelProtocol::AddOpenedActor(IToplevelProtocol* aActor)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
for (const IToplevelProtocol* actor = mOpenActors.getFirst();
|
for (const IToplevelProtocol* actor = mOpenActors.getFirst();
|
||||||
actor;
|
actor;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include "mozilla/ipc/Transport.h"
|
#include "mozilla/ipc/Transport.h"
|
||||||
#include "mozilla/ipc/MessageLink.h"
|
#include "mozilla/ipc/MessageLink.h"
|
||||||
#include "mozilla/LinkedList.h"
|
#include "mozilla/LinkedList.h"
|
||||||
#include "MainThreadUtils.h"
|
|
||||||
|
|
||||||
#if defined(ANDROID) && defined(DEBUG)
|
#if defined(ANDROID) && defined(DEBUG)
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
@ -188,7 +187,6 @@ protected:
|
|||||||
: mProtocolId(aProtoId)
|
: mProtocolId(aProtoId)
|
||||||
, mTrans(nullptr)
|
, mTrans(nullptr)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~IToplevelProtocol();
|
~IToplevelProtocol();
|
||||||
@ -214,12 +212,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
IToplevelProtocol* GetFirstOpenedActors()
|
IToplevelProtocol* GetFirstOpenedActors()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
return mOpenActors.getFirst();
|
return mOpenActors.getFirst();
|
||||||
}
|
}
|
||||||
const IToplevelProtocol* GetFirstOpenedActors() const
|
const IToplevelProtocol* GetFirstOpenedActors() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
return mOpenActors.getFirst();
|
return mOpenActors.getFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "nsStackWalkPrivate.h"
|
#include "nsStackWalkPrivate.h"
|
||||||
#include "nsStackWalk.h"
|
#include "nsStackWalk.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
|
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
@ -920,8 +919,6 @@ nsTraceRefcnt::DemangleSymbol(const char* aSymbol,
|
|||||||
EXPORT_XPCOM_API(void)
|
EXPORT_XPCOM_API(void)
|
||||||
NS_LogInit()
|
NS_LogInit()
|
||||||
{
|
{
|
||||||
NS_SetMainThread();
|
|
||||||
|
|
||||||
// FIXME: This is called multiple times, we should probably not allow that.
|
// FIXME: This is called multiple times, we should probably not allow that.
|
||||||
#ifdef STACKWALKING_AVAILABLE
|
#ifdef STACKWALKING_AVAILABLE
|
||||||
StackWalkInitCriticalAddress();
|
StackWalkInitCriticalAddress();
|
||||||
|
@ -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);
|
NS_ProcessPendingEvents(thread);
|
||||||
gfxPlatform::ShutdownLayersIPC();
|
|
||||||
|
|
||||||
mozilla::scache::StartupCache::DeleteSingleton();
|
mozilla::scache::StartupCache::DeleteSingleton();
|
||||||
if (observerService)
|
if (observerService)
|
||||||
(void) observerService->
|
(void) observerService->
|
||||||
NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
|
NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
|
||||||
nullptr);
|
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;
|
gXPCOMThreadsShutDown = true;
|
||||||
NS_ProcessPendingEvents(thread);
|
NS_ProcessPendingEvents(thread);
|
||||||
|
|
||||||
|
@ -28,8 +28,21 @@ extern NS_COM_GLUE NS_METHOD NS_GetMainThread(nsIThread** aResult);
|
|||||||
extern NS_COM_GLUE nsIThread* NS_GetCurrentThread();
|
extern NS_COM_GLUE nsIThread* NS_GetCurrentThread();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZILLA_INTERNAL_API
|
#if defined(MOZILLA_INTERNAL_API) && defined(XP_WIN)
|
||||||
bool NS_IsMainThread();
|
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
|
#else
|
||||||
/**
|
/**
|
||||||
* Test to see if the current thread is the main thread.
|
* Test to see if the current thread is the main thread.
|
||||||
|
@ -125,7 +125,34 @@ NS_GetMainThread(nsIThread** aResult)
|
|||||||
#endif
|
#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
|
bool
|
||||||
NS_IsMainThread()
|
NS_IsMainThread()
|
||||||
{
|
{
|
||||||
@ -138,6 +165,7 @@ NS_IsMainThread()
|
|||||||
return bool(result);
|
return bool(result);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_METHOD
|
NS_METHOD
|
||||||
NS_DispatchToCurrentThread(nsIRunnable* aEvent)
|
NS_DispatchToCurrentThread(nsIRunnable* aEvent)
|
||||||
@ -328,9 +356,7 @@ nsThreadPoolNaming::SetThreadPoolName(const nsACString& aPoolName,
|
|||||||
NS_SetThreadName(aThread, name);
|
NS_SetThreadName(aThread, name);
|
||||||
} else {
|
} else {
|
||||||
// Set on the current thread
|
// Set on the current thread
|
||||||
#ifndef XPCOM_GLUE_AVOID_NSPR
|
|
||||||
PR_SetCurrentThreadName(name.BeginReading());
|
PR_SetCurrentThreadName(name.BeginReading());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +565,6 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
|
||||||
NS_SetMainThread();
|
|
||||||
|
|
||||||
#endif // nsThreadUtils_h__
|
#endif // nsThreadUtils_h__
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "nsIClassInfoImpl.h"
|
#include "nsIClassInfoImpl.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "mozilla/ThreadLocal.h"
|
|
||||||
#ifdef MOZ_CANARY
|
#ifdef MOZ_CANARY
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -25,26 +24,6 @@ DWORD gTLSThreadIDIndex = TlsAlloc();
|
|||||||
NS_TLS mozilla::threads::ID gTLSThreadID = mozilla::threads::Generic;
|
NS_TLS mozilla::threads::ID gTLSThreadID = mozilla::threads::Generic;
|
||||||
#endif
|
#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;
|
typedef nsTArray<nsRefPtr<nsThread>> nsThreadArray;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user