Commit 4b43290e authored by dimich@chromium.org's avatar dimich@chromium.org
Browse files

JavaScriptCore:

2009-05-07  Dmitry Titov  <dimich@chromium.org>

        Reviewed by Alexey Proskuryakov and Adam Roben.

        https://bugs.webkit.org/show_bug.cgi?id=25348
        Change WTF::ThreadIdentifier to be an actual (but wrapped) thread id, remove ThreadMap.

        * wtf/Threading.h:
        (WTF::ThreadIdentifier::ThreadIdentifier):
        (WTF::ThreadIdentifier::isValid):
        (WTF::ThreadIdentifier::invalidate):
        (WTF::ThreadIdentifier::platformId):
        ThreadIdentifier is now a class, containing a PlatformThreadIdentifier and
        methods that are used across the code on thread ids: construction, comparisons,
        check for 'valid' state etc. '0' is used as invalid id, which happens to just work
        with all platform-specific thread id implementations.

        All the following files repeatedly reflect the new ThreadIdentifier for each platform.
        We remove ThreadMap and threadMapMutex from all of them, remove the functions that
        populated/searched/cleared the map and add platform-specific comparison operators
        for ThreadIdentifier.

        * wtf/gtk/ThreadingGtk.cpp:
        (WTF::ThreadIdentifier::operator==):
        (WTF::ThreadIdentifier::operator!=):
        (WTF::initializeThreading):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::currentThread):

        * wtf/ThreadingNone.cpp:
        (WTF::ThreadIdentifier::operator==):
        (WTF::ThreadIdentifier::operator!=):

        * wtf/ThreadingPthreads.cpp:
        (WTF::ThreadIdentifier::operator==):
        (WTF::ThreadIdentifier::operator!=):
        (WTF::initializeThreading):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::detachThread):
        (WTF::currentThread):

        * wtf/qt/ThreadingQt.cpp:
        (WTF::ThreadIdentifier::operator==):
        (WTF::ThreadIdentifier::operator!=):
        (WTF::initializeThreading):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::currentThread):

        * wtf/ThreadingWin.cpp:
        (WTF::ThreadIdentifier::operator==):
        (WTF::ThreadIdentifier::operator!=):
        (WTF::initializeThreading):
        (WTF::createThreadInternal): All the platforms (except Windows) used a sequential
        counter as a thread ID and mapped it into platform ID. Windows was using native thread
        id and mapped it into thread handle. Since we can always obtain a thread handle
        by thread id, createThread now closes the handle.
        (WTF::waitForThreadCompletion): obtains another one using OpenThread(id) API. If can not obtain a handle,
        it means the thread already exited.
        (WTF::detachThread):
        (WTF::currentThread):
        (WTF::detachThreadDeprecated): old function, renamed (for Win Safari 4 beta which uses it for now).
        (WTF::waitForThreadCompletionDeprecated): same.
        (WTF::currentThreadDeprecated): same.
        (WTF::createThreadDeprecated): same.

        * bytecode/SamplingTool.h:
        * bytecode/SamplingTool.cpp: Use DEFINE_STATIC_LOCAL for a static ThreadIdentifier variable, to avoid static constructor.

        * JavaScriptCore.exp: export lists - updated the WTF threading functions decorated names
        since they now take a different type as a parameter.
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: ditto for Windows, plus added "deprecated" functions
        that take old parameter type - turns out public beta of Safari 4 uses those, so they need to be kept along for a while.
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: ditto.

WebCore:

2009-05-07  Dmitry Titov  <dimich@chromium.org>

        Reviewed by Alexey Proskuryakov and Adam Roben.

        https://bugs.webkit.org/show_bug.cgi?id=25348
        Change WTF::ThreadIdentifier to be an actual (but wrapped) thread id, remove ThreadMap.

        Most of the change is in WTF.
        Unless noted, all the following files changed to use the new ThreadIdentifier::isValid()
        method instead of just doing 'if(m_threadID)' kind of checks, since ThreadIdentifier
        is now a class rather then an integer.
        Also, there is no need to initialize threadID in constructors to 0 now.

        * dom/XMLTokenizerLibxml2.cpp:
        (WebCore::libxmlLoaderThread): use DEFINE_STATIC_LOCAL and accessor function for static thread id,
        since now ThreadIdentifier needs construction and we avoid having global initializers.
        (WebCore::matchFunc): use the new accessor function.
        (WebCore::openFunc): ditto.
        (WebCore::createStringParser): ditto.
        (WebCore::createMemoryParser): ditto.
        * loader/icon/IconDatabase.cpp:
        (WebCore::IconDatabase::open):
        * platform/sql/SQLiteDatabase.cpp:
        (WebCore::SQLiteDatabase::SQLiteDatabase):
        (WebCore::SQLiteDatabase::close):
        * storage/DatabaseThread.cpp:
        (WebCore::DatabaseThread::start):
        (WebCore::DatabaseThread::databaseThread): remove m_threadID from debug output.
        * storage/LocalStorageThread.cpp:
        (WebCore::LocalStorageThread::start):
        (WebCore::LocalStorageThread::scheduleImport):
        (WebCore::LocalStorageThread::scheduleSync):
        (WebCore::LocalStorageThread::terminate):
        * workers/WorkerThread.cpp:
        (WebCore::WorkerThread::start):
        (WebCore::WorkerThread::WorkerThread):
        (WebCore::WorkerThread::start):

WebKit/win:

2009-05-07  Dmitry Titov  <dimich@chromium.org>

        Reviewed by Alexey Proskuryakov and Adam Roben.

        https://bugs.webkit.org/show_bug.cgi?id=25348
        Change WTF::ThreadIdentifier to be an actual (but wrapped) thread id, remove ThreadMap.

        Most of the change is in WTF and WebCore.

        * WebKit.vcproj/WebKit.def: replaced decorated names of WTF threading functions with new ones.
        Also, aliased the old implementations so the public Safari 4 beta can load the old WTF functions
        which it uses. Next time Safari 4 builds, it will pick up new functions and the deprecated ones
        can be removed.
        * WebKit.vcproj/WebKit_debug.def: same.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@43366 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 10438435
2009-05-07 Dmitry Titov <dimich@chromium.org>
Reviewed by Alexey Proskuryakov and Adam Roben.
https://bugs.webkit.org/show_bug.cgi?id=25348
Change WTF::ThreadIdentifier to be an actual (but wrapped) thread id, remove ThreadMap.
* wtf/Threading.h:
(WTF::ThreadIdentifier::ThreadIdentifier):
(WTF::ThreadIdentifier::isValid):
(WTF::ThreadIdentifier::invalidate):
(WTF::ThreadIdentifier::platformId):
ThreadIdentifier is now a class, containing a PlatformThreadIdentifier and
methods that are used across the code on thread ids: construction, comparisons,
check for 'valid' state etc. '0' is used as invalid id, which happens to just work
with all platform-specific thread id implementations.
All the following files repeatedly reflect the new ThreadIdentifier for each platform.
We remove ThreadMap and threadMapMutex from all of them, remove the functions that
populated/searched/cleared the map and add platform-specific comparison operators
for ThreadIdentifier.
* wtf/gtk/ThreadingGtk.cpp:
(WTF::ThreadIdentifier::operator==):
(WTF::ThreadIdentifier::operator!=):
(WTF::initializeThreading):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::currentThread):
* wtf/ThreadingNone.cpp:
(WTF::ThreadIdentifier::operator==):
(WTF::ThreadIdentifier::operator!=):
* wtf/ThreadingPthreads.cpp:
(WTF::ThreadIdentifier::operator==):
(WTF::ThreadIdentifier::operator!=):
(WTF::initializeThreading):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::detachThread):
(WTF::currentThread):
* wtf/qt/ThreadingQt.cpp:
(WTF::ThreadIdentifier::operator==):
(WTF::ThreadIdentifier::operator!=):
(WTF::initializeThreading):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::currentThread):
* wtf/ThreadingWin.cpp:
(WTF::ThreadIdentifier::operator==):
(WTF::ThreadIdentifier::operator!=):
(WTF::initializeThreading):
(WTF::createThreadInternal): All the platforms (except Windows) used a sequential
counter as a thread ID and mapped it into platform ID. Windows was using native thread
id and mapped it into thread handle. Since we can always obtain a thread handle
by thread id, createThread now closes the handle.
(WTF::waitForThreadCompletion): obtains another one using OpenThread(id) API. If can not obtain a handle,
it means the thread already exited.
(WTF::detachThread):
(WTF::currentThread):
(WTF::detachThreadDeprecated): old function, renamed (for Win Safari 4 beta which uses it for now).
(WTF::waitForThreadCompletionDeprecated): same.
(WTF::currentThreadDeprecated): same.
(WTF::createThreadDeprecated): same.
* bytecode/SamplingTool.h:
* bytecode/SamplingTool.cpp: Use DEFINE_STATIC_LOCAL for a static ThreadIdentifier variable, to avoid static constructor.
* JavaScriptCore.exp: export lists - updated the WTF threading functions decorated names
since they now take a different type as a parameter.
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: ditto for Windows, plus added "deprecated" functions
that take old parameter type - turns out public beta of Safari 4 uses those, so they need to be kept along for a while.
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def: ditto.
2009-05-07 Maciej Stachowiak <mjs@apple.com>
 
Reviewed by Sam Weinig.
......@@ -279,7 +279,7 @@ __ZN3WTF11currentTimeEv
__ZN3WTF11fastReallocEPvm
__ZN3WTF12createThreadEPFPvS0_ES0_
__ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12detachThreadENS_16ThreadIdentifierE
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
__ZN3WTF13currentThreadEv
......@@ -300,7 +300,7 @@ __ZN3WTF21RefCountedLeakCounter9decrementEv
__ZN3WTF21RefCountedLeakCounter9incrementEv
__ZN3WTF21RefCountedLeakCounterC1EPKc
__ZN3WTF21RefCountedLeakCounterD1Ev
__ZN3WTF23waitForThreadCompletionEjPPv
__ZN3WTF23waitForThreadCompletionENS_16ThreadIdentifierEPPv
__ZN3WTF27releaseFastMallocFreeMemoryEv
__ZN3WTF28setMainThreadCallbacksPausedEb
__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
......@@ -362,6 +362,8 @@ __ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3JSC9HashTable11deleteTableEv
__ZNK3WTF8Collator7collateEPKtmS2_m
__ZNK3WTF16ThreadIdentifiereqERKS0_
__ZNK3WTF16ThreadIdentifierneERKS0_
__ZTVN3JSC12StringObjectE
__ZTVN3JSC14JSGlobalObjectE
__ZTVN3JSC15JSWrapperObjectE
......
......@@ -29,6 +29,7 @@ EXPORTS
??2JSGlobalObject@JSC@@SAPAXIPAVJSGlobalData@1@@Z
??4UString@JSC@@QAEAAV01@PBD@Z
??8JSC@@YA_NABVUString@0@0@Z
??8ThreadIdentifier@WTF@@QBE_NABV01@@Z
?UTF8String@UString@JSC@@QBE?AVCString@2@_N@Z
?add@Identifier@JSC@@SA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVExecState@2@PBD@Z
?add@PropertyNameArray@JSC@@QAEXPAURep@UString@2@@Z
......@@ -71,9 +72,8 @@ EXPORTS
?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ
?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@VJSValue@2@@Z
?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z
?createThread@WTF@@YAIP6APAXPAX@Z0@Z
?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YAIXZ
?createThread@WTF@@YA?AVThreadIdentifier@1@P6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YA?AVThreadIdentifier@1@XZ
?currentTime@WTF@@YANXZ
?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
......@@ -93,7 +93,7 @@ EXPORTS
?destroy@Heap@JSC@@QAEXXZ
?destroy@Rep@UString@JSC@@QAEXXZ
?detach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXI@Z
?detachThread@WTF@@YAXVThreadIdentifier@1@@Z
?equal@Identifier@JSC@@SA_NPBURep@UString@2@PBD@Z
?equal@JSC@@YA_NPBURep@UString@1@0@Z
?evaluate@DebuggerCallFrame@JSC@@QBE?AVJSValue@2@ABVUString@2@AAV32@@Z
......@@ -251,7 +251,7 @@ EXPORTS
?unprotect@Heap@JSC@@QAEXVJSValue@2@@Z
?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ
?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
?waitForThreadCompletion@WTF@@YAHVThreadIdentifier@1@PAPAX@Z
WTFLog
WTFLogVerbose
WTFReportArgumentAssertionFailure
......@@ -263,3 +263,7 @@ EXPORTS
?substr@UString@JSC@@QBE?AV12@HH@Z
?setDumpsGeneratedCode@BytecodeGenerator@JSC@@SAX_N@Z
?putDirectFunction@JSObject@JSC@@QAEXPAVExecState@2@PAVInternalFunction@2@I@Z
?createThreadDeprecated@WTF@@YAIP6APAXPAX@Z0PBD@Z
?currentThreadDeprecated@WTF@@YAIXZ
?detachThreadDeprecated@WTF@@YAXI@Z
?waitForThreadCompletionDeprecated@WTF@@YAHIPAPAX@Z
......@@ -29,6 +29,7 @@ EXPORTS
??2JSGlobalObject@JSC@@SAPAXIPAVJSGlobalData@1@@Z
??4UString@JSC@@QAEAAV01@PBD@Z
??8JSC@@YA_NABVUString@0@0@Z
??8ThreadIdentifier@WTF@@QBE_NABV01@@Z
?UTF8String@UString@JSC@@QBE?AVCString@2@_N@Z
?add@Identifier@JSC@@SA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVExecState@2@PBD@Z
?add@PropertyNameArray@JSC@@QAEXPAURep@UString@2@@Z
......@@ -71,9 +72,8 @@ EXPORTS
?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ
?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@VJSValue@2@@Z
?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z
?createThread@WTF@@YAIP6APAXPAX@Z0@Z
?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YAIXZ
?createThread@WTF@@YA?AVThreadIdentifier@1@P6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YA?AVThreadIdentifier@1@XZ
?currentTime@WTF@@YANXZ
?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
......@@ -93,7 +93,7 @@ EXPORTS
?destroy@Heap@JSC@@QAEXXZ
?destroy@Rep@UString@JSC@@QAEXXZ
?detach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXI@Z
?detachThread@WTF@@YAXVThreadIdentifier@1@@Z
?equal@Identifier@JSC@@SA_NPBURep@UString@2@PBD@Z
?equal@JSC@@YA_NPBURep@UString@1@0@Z
?evaluate@DebuggerCallFrame@JSC@@QBE?AVJSValue@2@ABVUString@2@AAV32@@Z
......@@ -251,7 +251,7 @@ EXPORTS
?unprotect@Heap@JSC@@QAEXVJSValue@2@@Z
?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ
?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
?waitForThreadCompletion@WTF@@YAHVThreadIdentifier@1@PAPAX@Z
WTFLog
WTFLogVerbose
WTFReportArgumentAssertionFailure
......@@ -263,3 +263,7 @@ EXPORTS
?substr@UString@JSC@@QBE?AV12@HH@Z
?setDumpsGeneratedCode@BytecodeGenerator@JSC@@SAX_N@Z
?putDirectFunction@JSObject@JSC@@QAEXPAVExecState@2@PAVInternalFunction@2@I@Z
?createThreadDeprecated@WTF@@YAIP6APAXPAX@Z0PBD@Z
?currentThreadDeprecated@WTF@@YAIXZ
?detachThreadDeprecated@WTF@@YAXI@Z
?waitForThreadCompletionDeprecated@WTF@@YAHIPAPAX@Z
......@@ -121,7 +121,11 @@ SamplingTool* SamplingTool::s_samplingTool = 0;
bool SamplingThread::s_running = false;
unsigned SamplingThread::s_hertz = 10000;
ThreadIdentifier SamplingThread::s_samplingThread;
ThreadIdentifier& SamplingThread::samplingThread() {
DEFINE_STATIC_LOCAL(ThreadIdentifier, staticSamplingThread, ());
return staticSamplingThread;
}
void* SamplingThread::threadStartFunc(void*)
{
......@@ -146,14 +150,14 @@ void SamplingThread::start(unsigned hertz)
s_running = true;
s_hertz = hertz;
s_samplingThread = createThread(threadStartFunc, 0, "JavaScriptCore::Sampler");
samplingThread() = createThread(threadStartFunc, 0, "JavaScriptCore::Sampler");
}
void SamplingThread::stop()
{
ASSERT(s_running);
s_running = false;
waitForThreadCompletion(s_samplingThread, 0);
waitForThreadCompletion(samplingThread(), 0);
}
......
......@@ -125,7 +125,8 @@ namespace JSC {
// Sampling thread state.
static bool s_running;
static unsigned s_hertz;
static ThreadIdentifier s_samplingThread;
static ThreadIdentifier& samplingThread();
static void start(unsigned hertz=10000);
static void stop();
......
......@@ -74,9 +74,6 @@ namespace WTF {
CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
: m_threadSafeRefCounter(threadedCounter)
, m_data(data)
#ifndef NDEBUG
, m_threadId(0)
#endif
{
}
......@@ -99,7 +96,7 @@ namespace WTF {
template<class T>
void CrossThreadRefCounted<T>::ref()
{
ASSERT(!m_threadId || m_threadId == currentThread());
ASSERT(!m_threadId.isValid() || m_threadId == currentThread());
m_refCounter.ref();
#ifndef NDEBUG
// Store the threadId as soon as the ref count gets to 2.
......@@ -107,7 +104,7 @@ namespace WTF {
// to another thread where to ref count get increased. This
// is a heuristic but it seems to always work and has helped
// find some bugs.
if (!m_threadId && m_refCounter.refCount() == 2)
if (!m_threadId.isValid() && m_refCounter.refCount() == 2)
m_threadId = currentThread();
#endif
}
......@@ -115,7 +112,7 @@ namespace WTF {
template<class T>
void CrossThreadRefCounted<T>::deref()
{
ASSERT(!m_threadId || m_threadId == currentThread());
ASSERT(!m_threadId.isValid() || m_threadId == currentThread());
if (m_refCounter.derefBase()) {
threadSafeDeref();
delete this;
......@@ -124,7 +121,7 @@ namespace WTF {
// Clear the threadId when the ref goes to 1 because it
// is safe to be passed to another thread at this point.
if (m_threadId && m_refCounter.refCount() == 1)
m_threadId = 0;
m_threadId.invalidate();
#endif
}
}
......
......@@ -85,12 +85,14 @@
#include <wtf/GOwnPtr.h>
typedef struct _GMutex GMutex;
typedef struct _GCond GCond;
typedef struct _GThread GThread;
#endif
#if PLATFORM(QT)
#include <qglobal.h>
QT_BEGIN_NAMESPACE
class QMutex;
class QThread;
class QWaitCondition;
QT_END_NAMESPACE
#endif
......@@ -105,34 +107,18 @@ QT_END_NAMESPACE
namespace WTF {
typedef uint32_t ThreadIdentifier;
typedef void* (*ThreadFunction)(void* argument);
// Returns 0 if thread creation failed.
// The thread name must be a literal since on some platforms it's passed in to the thread.
ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
// Internal platform-specific createThread implementation.
ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
// Called in the thread during initialization.
// Helpful for platforms where the thread name must be set from within the thread.
void setThreadNameInternal(const char* threadName);
ThreadIdentifier currentThread();
bool isMainThread();
int waitForThreadCompletion(ThreadIdentifier, void**);
void detachThread(ThreadIdentifier);
#if USE(PTHREADS)
typedef pthread_mutex_t PlatformMutex;
typedef pthread_cond_t PlatformCondition;
typedef pthread_t PlatformThreadIdentifier;
#elif PLATFORM(GTK)
typedef GOwnPtr<GMutex> PlatformMutex;
typedef GOwnPtr<GCond> PlatformCondition;
typedef GThread* PlatformThreadIdentifier;
#elif PLATFORM(QT)
typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;
typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;
typedef QT_PREPEND_NAMESPACE(QThread)* PlatformThreadIdentifier;
#elif PLATFORM(WIN_OS)
struct PlatformMutex {
CRITICAL_SECTION m_internalMutex;
......@@ -149,11 +135,61 @@ struct PlatformCondition {
bool timedWait(PlatformMutex&, DWORD durationMilliseconds);
void signal(bool unblockAll);
};
typedef unsigned PlatformThreadIdentifier;
#else
typedef void* PlatformMutex;
typedef void* PlatformCondition;
#endif
// Platform-independent wrapper for thread id. Assignable and copyable.
// The only way to obtain a valid ThreadIdentifier is from createThread(...) or currentThread() functions.
// ThreadIdentifier remains valid for as long as its thread is alive and is not automatically invalidated
// when thread terminates. Since platform-dependent thread ids can be recycled, stale ThreadIdentifier
// may reference a completely unrelated thread after its original thread terminates.
class ThreadIdentifier {
public:
ThreadIdentifier()
: m_platformId(0)
{
ASSERT(!isValid());
}
explicit ThreadIdentifier(PlatformThreadIdentifier platformId)
: m_platformId(platformId)
{
ASSERT(isValid());
}
bool isValid() const { return m_platformId; }
void invalidate() { m_platformId = 0; }
bool operator==(const ThreadIdentifier&) const;
bool operator!=(const ThreadIdentifier&) const;
PlatformThreadIdentifier platformId() const { return m_platformId; }
private:
PlatformThreadIdentifier m_platformId;
};
typedef void* (*ThreadFunction)(void* argument);
// Returns invalid identifier if thread creation failed.
// The thread name must be a literal since on some platforms it's passed in to the thread.
ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
// Internal platform-specific createThread implementation.
ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
// Called in the thread during initialization.
// Helpful for platforms where the thread name must be set from within the thread.
void setThreadNameInternal(const char* threadName);
ThreadIdentifier currentThread();
bool isMainThread();
int waitForThreadCompletion(ThreadIdentifier, void**);
void detachThread(ThreadIdentifier);
class Mutex : Noncopyable {
public:
Mutex();
......
......@@ -32,6 +32,9 @@
namespace WTF {
bool ThreadIdentifier::operator==(const ThreadIdentifier&) const { return true; }
bool ThreadIdentifier::operator!=(const ThreadIdentifier&) const { return false; }
void initializeThreading() { }
ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return 0; }
void setThreadNameInternal(const char*) { }
......
......@@ -48,7 +48,15 @@
namespace WTF {
typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
bool ThreadIdentifier::operator==(const ThreadIdentifier& another) const
{
return pthread_equal(m_platformId, another.m_platformId);
}
bool ThreadIdentifier::operator!=(const ThreadIdentifier& another) const
{
return !pthread_equal(m_platformId, another.m_platformId);
}
static Mutex* atomicallyInitializedStaticMutex;
......@@ -56,17 +64,10 @@ static Mutex* atomicallyInitializedStaticMutex;
static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread.
#endif
static Mutex& threadMapMutex()
{
DEFINE_STATIC_LOCAL(Mutex, mutex, ());
return mutex;
}
void initializeThreading()
{
if (!atomicallyInitializedStaticMutex) {
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
initializeRandomNumberGenerator();
#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM)
mainThreadIdentifier = currentThread();
......@@ -86,54 +87,6 @@ void unlockAtomicallyInitializedStaticMutex()
atomicallyInitializedStaticMutex->unlock();
}
static ThreadMap& threadMap()
{
DEFINE_STATIC_LOCAL(ThreadMap, map, ());
return map;
}
static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle)
{
MutexLocker locker(threadMapMutex());
ThreadMap::iterator i = threadMap().begin();
for (; i != threadMap().end(); ++i) {
if (pthread_equal(i->second, pthreadHandle))
return i->first;
}
return 0;
}
static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
{
ASSERT(!identifierByPthreadHandle(pthreadHandle));
MutexLocker locker(threadMapMutex());
static ThreadIdentifier identifierCount = 1;
threadMap().add(identifierCount, pthreadHandle);
return identifierCount++;
}
static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
{
MutexLocker locker(threadMapMutex());
return threadMap().get(id);
}
static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
{
MutexLocker locker(threadMapMutex());
ASSERT(threadMap().contains(id));
threadMap().remove(id);
}
#if PLATFORM(ANDROID)
// On the Android platform, threads must be registered with the VM before they run.
struct ThreadData {
......@@ -164,9 +117,9 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) {
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
return 0;
return ThreadIdentifier();
}
return establishIdentifierForPthreadHandle(threadHandle);
return ThreadIdentifier(threadHandle);
}
#else
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
......@@ -174,10 +127,10 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
pthread_t threadHandle;
if (pthread_create(&threadHandle, 0, entryPoint, data)) {
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
return 0;
return ThreadIdentifier();
}
return establishIdentifierForPthreadHandle(threadHandle);
return ThreadIdentifier(threadHandle);
}
#endif
......@@ -192,35 +145,29 @@ void setThreadNameInternal(const char* threadName)
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID);
ASSERT(threadID.isValid());
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
pthread_t pthreadHandle = threadID.platformId();
int joinResult = pthread_join(pthreadHandle, result);
if (joinResult == EDEADLK)
LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
LOG_ERROR("ThreadIdentifier %p was found to be deadlocked trying to quit", pthreadHandle);
clearPthreadHandleForIdentifier(threadID);
return joinResult;
}
void detachThread(ThreadIdentifier threadID)
{
ASSERT(threadID);
ASSERT(threadID.isValid());
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
pthread_t pthreadHandle = threadID.platformId();
pthread_detach(pthreadHandle);
clearPthreadHandleForIdentifier(threadID);
}
ThreadIdentifier currentThread()
{
pthread_t currentThread = pthread_self();
if (ThreadIdentifier id = identifierByPthreadHandle(currentThread))
return id;
return establishIdentifierForPthreadHandle(currentThread);
return ThreadIdentifier(pthread_self());
}
bool isMainThread()
......
......@@ -98,6 +98,16 @@
namespace WTF {
bool ThreadIdentifier::operator==(const ThreadIdentifier& another) const
{
return m_platformId == another.m_platformId;
}
bool ThreadIdentifier::operator!=(const ThreadIdentifier& another) const
{
return m_platformId != another.m_platformId;
}
// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
static const DWORD MS_VC_EXCEPTION = 0x406D1388;
......@@ -139,17 +149,10 @@ void unlockAtomicallyInitializedStaticMutex()
static ThreadIdentifier mainThreadIdentifier;
static Mutex& threadMapMutex()
{
static Mutex mutex;
return mutex;
}
void initializeThreading()
{
if (!atomicallyInitializedStaticMutex) {
atomicallyInitializedStaticMutex = new Mutex;
threadMapMutex();
initializeRandomNumberGenerator();
initializeMainThread();
mainThreadIdentifier = currentThread();
......@@ -157,32 +160,6 @@ void initializeThreading()
}
}
static HashMap<DWORD, HANDLE>& threadMap()
{
static HashMap<DWORD, HANDLE> map;
return map;
}
static void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle)
{
MutexLocker locker(threadMapMutex());
ASSERT(!threadMap().contains(threadID));
threadMap().add(threadID, threadHandle);
}
static HANDLE threadHandleForIdentifier(ThreadIdentifier id)
{