Bug 1475899: Part 1 - Track live nsThreads and add a method of enumerating them. r=erahm

This will allow us to enumerate active threads in order to report their
memory.

MozReview-Commit-ID: IExELSkFdwB

--HG--
extra : source : 2916b5e05b6d100e91448f21cb4082e41a86e87c
This commit is contained in:
Kris Maglione 2018-07-14 02:19:59 -07:00
Родитель e8ffb68819
Коммит 9b7d0838b7
2 изменённых файлов: 60 добавлений и 0 удалений

Просмотреть файл

@ -376,6 +376,26 @@ struct ThreadInitData {
} }
/* static */ mozilla::OffTheBooksMutex&
nsThread::ThreadListMutex()
{
static OffTheBooksMutex sMutex("nsThread::ThreadListMutex");
return sMutex;
}
/* static */ LinkedList<nsThread>&
nsThread::ThreadList()
{
static LinkedList<nsThread> sList;
return sList;
}
/* static */ nsThreadEnumerator
nsThread::Enumerate()
{
return {};
}
/*static*/ void /*static*/ void
nsThread::ThreadFunc(void* aArg) nsThread::ThreadFunc(void* aArg)
{ {
@ -568,6 +588,7 @@ nsThread::~nsThread()
{ {
NS_ASSERTION(mRequestedShutdownContexts.IsEmpty(), NS_ASSERTION(mRequestedShutdownContexts.IsEmpty(),
"shouldn't be waiting on other threads to shutdown"); "shouldn't be waiting on other threads to shutdown");
MOZ_ASSERT(!isInList());
#ifdef DEBUG #ifdef DEBUG
// We deliberately leak these so they can be tracked by the leak checker. // We deliberately leak these so they can be tracked by the leak checker.
// If you're having nsThreadShutdownContext leaks, you can set: // If you're having nsThreadShutdownContext leaks, you can set:
@ -601,6 +622,11 @@ nsThread::Init(const nsACString& aName)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
{
OffTheBooksMutexAutoLock mal(ThreadListMutex());
ThreadList().insertBack(this);
}
// ThreadFunc will wait for this event to be run before it tries to access // ThreadFunc will wait for this event to be run before it tries to access
// mThread. By delaying insertion of this event into the queue, we ensure // mThread. By delaying insertion of this event into the queue, we ensure
// that mThread is set properly. // that mThread is set properly.
@ -715,6 +741,13 @@ nsThread::ShutdownInternal(bool aSync)
return nullptr; return nullptr;
} }
{
OffTheBooksMutexAutoLock mal(ThreadListMutex());
if (isInList()) {
removeFrom(ThreadList());
}
}
NotNull<nsThread*> currentThread = NotNull<nsThread*> currentThread =
WrapNotNull(nsThreadManager::get().GetCurrentThread()); WrapNotNull(nsThreadManager::get().GetCurrentThread());

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsString.h" #include "nsString.h"
#include "nsTObserverArray.h" #include "nsTObserverArray.h"
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "mozilla/SynchronizedEventQueue.h" #include "mozilla/SynchronizedEventQueue.h"
#include "mozilla/NotNull.h" #include "mozilla/NotNull.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
@ -31,11 +32,16 @@ class ThreadEventTarget;
using mozilla::NotNull; using mozilla::NotNull;
class nsThreadEnumerator;
// A native thread // A native thread
class nsThread class nsThread
: public nsIThreadInternal : public nsIThreadInternal
, public nsISupportsPriority , public nsISupportsPriority
, private mozilla::LinkedListElement<nsThread>
{ {
friend mozilla::LinkedList<nsThread>;
friend mozilla::LinkedListElement<nsThread>;
public: public:
NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIEVENTTARGET_FULL NS_DECL_NSIEVENTTARGET_FULL
@ -132,12 +138,16 @@ public:
virtual mozilla::PerformanceCounter* GetPerformanceCounter(nsIRunnable* aEvent); virtual mozilla::PerformanceCounter* GetPerformanceCounter(nsIRunnable* aEvent);
static nsThreadEnumerator Enumerate();
private: private:
void DoMainThreadSpecificProcessing(bool aReallyWait); void DoMainThreadSpecificProcessing(bool aReallyWait);
protected: protected:
friend class nsThreadShutdownEvent; friend class nsThreadShutdownEvent;
friend class nsThreadEnumerator;
virtual ~nsThread(); virtual ~nsThread();
static void ThreadFunc(void* aArg); static void ThreadFunc(void* aArg);
@ -152,6 +162,9 @@ protected:
struct nsThreadShutdownContext* ShutdownInternal(bool aSync); struct nsThreadShutdownContext* ShutdownInternal(bool aSync);
static mozilla::OffTheBooksMutex& ThreadListMutex();
static mozilla::LinkedList<nsThread>& ThreadList();
RefPtr<mozilla::SynchronizedEventQueue> mEvents; RefPtr<mozilla::SynchronizedEventQueue> mEvents;
RefPtr<mozilla::ThreadEventTarget> mEventTarget; RefPtr<mozilla::ThreadEventTarget> mEventTarget;
@ -184,6 +197,20 @@ protected:
RefPtr<mozilla::PerformanceCounter> mCurrentPerformanceCounter; RefPtr<mozilla::PerformanceCounter> mCurrentPerformanceCounter;
}; };
class MOZ_STACK_CLASS nsThreadEnumerator final
{
public:
nsThreadEnumerator()
: mMal(nsThread::ThreadListMutex())
{}
auto begin() { return nsThread::ThreadList().begin(); }
auto end() { return nsThread::ThreadList().end(); }
private:
mozilla::OffTheBooksMutexAutoLock mMal;
};
#if defined(XP_UNIX) && !defined(ANDROID) && !defined(DEBUG) && HAVE_UALARM \ #if defined(XP_UNIX) && !defined(ANDROID) && !defined(DEBUG) && HAVE_UALARM \
&& defined(_GNU_SOURCE) && defined(_GNU_SOURCE)
# define MOZ_CANARY # define MOZ_CANARY