зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1323100 - Add nsThreadManager::NewNamedThread API. r=froydnj
The point of this exercise is to make the thread name available in the thread func of the thread, so that we can register the thread with the profiler from the very start of its lifetime, and so that registration and unregistration can be inside the same function. MozReview-Commit-ID: DiiMKUQVr55 --HG-- extra : rebase_source : 24b15d56315ad49e72b3e9b76db7fb634f3bfe01
This commit is contained in:
Родитель
45941e71bc
Коммит
8924022f9d
|
@ -35,6 +35,20 @@ interface nsIThreadManager : nsISupports
|
|||
*/
|
||||
nsIThread newThread(in unsigned long creationFlags, [optional] in unsigned long stackSize);
|
||||
|
||||
/**
|
||||
* Create a new thread (a global, user PRThread) with the specified name.
|
||||
*
|
||||
* @param name
|
||||
* The name of the thread. Passing an empty name is equivalent to
|
||||
* calling newThread(0, stackSize), i.e. the thread will not be named.
|
||||
* @param stackSize
|
||||
* Number of bytes to reserve for the thread's stack.
|
||||
*
|
||||
* @returns
|
||||
* The newly created nsIThread object.
|
||||
*/
|
||||
[noscript] nsIThread newNamedThread(in ACString name, [optional] in unsigned long stackSize);
|
||||
|
||||
/**
|
||||
* Get the nsIThread object (if any) corresponding to the given PRThread.
|
||||
* This method returns null if there is no corresponding nsIThread.
|
||||
|
|
|
@ -432,15 +432,30 @@ SetupCurrentThreadForChaosMode()
|
|||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct ThreadInitData {
|
||||
nsThread* thread;
|
||||
const nsACString& name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
nsThread::ThreadFunc(void* aArg)
|
||||
{
|
||||
using mozilla::ipc::BackgroundChild;
|
||||
|
||||
nsThread* self = static_cast<nsThread*>(aArg); // strong reference
|
||||
ThreadInitData* initData = static_cast<ThreadInitData*>(aArg);
|
||||
nsThread* self = initData->thread; // strong reference
|
||||
|
||||
self->mThread = PR_GetCurrentThread();
|
||||
SetupCurrentThreadForChaosMode();
|
||||
|
||||
if (initData->name.Length() > 0) {
|
||||
PR_SetCurrentThreadName(initData->name.BeginReading());
|
||||
}
|
||||
|
||||
// Inform the ThreadManager
|
||||
nsThreadManager::get().RegisterCurrentThread(*self);
|
||||
|
||||
|
@ -455,6 +470,9 @@ nsThread::ThreadFunc(void* aArg)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
initData = nullptr; // clear before unblocking nsThread::Init
|
||||
|
||||
event->Run(); // unblocks nsThread::Init
|
||||
event = nullptr;
|
||||
|
||||
|
@ -628,7 +646,7 @@ nsThread::~nsThread()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsThread::Init()
|
||||
nsThread::Init(const nsACString& aName)
|
||||
{
|
||||
// spawn thread and wait until it is fully setup
|
||||
RefPtr<nsThreadStartupEvent> startup = new nsThreadStartupEvent();
|
||||
|
@ -639,8 +657,10 @@ nsThread::Init()
|
|||
|
||||
mShutdownRequired = true;
|
||||
|
||||
ThreadInitData initData = { this, aName };
|
||||
|
||||
// ThreadFunc is responsible for setting mThread
|
||||
if (!PR_CreateThread(PR_USER_THREAD, ThreadFunc, this,
|
||||
if (!PR_CreateThread(PR_USER_THREAD, ThreadFunc, &initData,
|
||||
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
||||
PR_JOINABLE_THREAD, mStackSize)) {
|
||||
NS_RELEASE_THIS();
|
||||
|
|
|
@ -48,8 +48,8 @@ public:
|
|||
|
||||
nsThread(MainThreadFlag aMainThread, uint32_t aStackSize);
|
||||
|
||||
// Initialize this as a wrapper for a new PRThread.
|
||||
nsresult Init();
|
||||
// Initialize this as a wrapper for a new PRThread, and optionally give it a name.
|
||||
nsresult Init(const nsACString& aName = NS_LITERAL_CSTRING(""));
|
||||
|
||||
// Initialize this as a wrapper for the current PRThread.
|
||||
nsresult InitCurrentThread();
|
||||
|
|
|
@ -248,6 +248,14 @@ NS_IMETHODIMP
|
|||
nsThreadManager::NewThread(uint32_t aCreationFlags,
|
||||
uint32_t aStackSize,
|
||||
nsIThread** aResult)
|
||||
{
|
||||
return NewNamedThread(NS_LITERAL_CSTRING(""), aStackSize, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThreadManager::NewNamedThread(const nsACString& aName,
|
||||
uint32_t aStackSize,
|
||||
nsIThread** aResult)
|
||||
{
|
||||
// Note: can be called from arbitrary threads
|
||||
|
||||
|
@ -257,7 +265,7 @@ nsThreadManager::NewThread(uint32_t aCreationFlags,
|
|||
}
|
||||
|
||||
RefPtr<nsThread> thr = new nsThread(nsThread::NOT_MAIN_THREAD, aStackSize);
|
||||
nsresult rv = thr->Init(); // Note: blocks until the new thread has been set up
|
||||
nsresult rv = thr->Init(aName); // Note: blocks until the new thread has been set up
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче