Bug 1033358 - Make NS_IsMainThread use its own TLS so it's always correct, from early init to exit time - r=bsmedberg

This commit is contained in:
Benoit Jacob 2014-07-03 14:53:24 -04:00
parent 6e4aca3cdf
commit 0e68107d00
5 changed files with 28 additions and 44 deletions

View File

@ -18,6 +18,7 @@
#include "nsStackWalkPrivate.h"
#include "nsStackWalk.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
#ifdef XP_WIN
@ -919,6 +920,8 @@ 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

@ -28,21 +28,8 @@ extern NS_COM_GLUE NS_METHOD NS_GetMainThread(nsIThread** aResult);
extern NS_COM_GLUE nsIThread* NS_GetCurrentThread();
#endif
#if defined(MOZILLA_INTERNAL_API) && defined(XP_WIN)
#ifdef MOZILLA_INTERNAL_API
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,34 +125,7 @@ NS_GetMainThread(nsIThread** aResult)
#endif
}
#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
#ifndef MOZILLA_INTERNAL_API
bool
NS_IsMainThread()
{
@ -165,7 +138,6 @@ NS_IsMainThread()
return bool(result);
}
#endif
#endif
NS_METHOD
NS_DispatchToCurrentThread(nsIRunnable* aEvent)

View File

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

View File

@ -10,6 +10,7 @@
#include "nsIClassInfoImpl.h"
#include "nsTArray.h"
#include "nsAutoPtr.h"
#include "mozilla/ThreadLocal.h"
#ifdef MOZ_CANARY
#include <fcntl.h>
#include <unistd.h>
@ -24,6 +25,26 @@ 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;
//-----------------------------------------------------------------------------