Commit c85b91df authored by dimich@chromium.org's avatar dimich@chromium.org

JavaScriptCore:

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

        Rubber-stamped by Mark Rowe.

        https://bugs.webkit.org/show_bug.cgi?id=25746
        Revert http://trac.webkit.org/changeset/43507 which caused crash in PPC nightlies with Safari 4.

        * JavaScriptCore.exp:
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
        * bytecode/SamplingTool.cpp:
        (JSC::SamplingThread::start):
        (JSC::SamplingThread::stop):
        * bytecode/SamplingTool.h:
        * wtf/CrossThreadRefCounted.h:
        (WTF::CrossThreadRefCounted::CrossThreadRefCounted):
        (WTF::::ref):
        (WTF::::deref):
        * wtf/Threading.h:
        * wtf/ThreadingNone.cpp:
        * wtf/ThreadingPthreads.cpp:
        (WTF::threadMapMutex):
        (WTF::initializeThreading):
        (WTF::threadMap):
        (WTF::identifierByPthreadHandle):
        (WTF::establishIdentifierForPthreadHandle):
        (WTF::pthreadHandleForIdentifier):
        (WTF::clearPthreadHandleForIdentifier):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::detachThread):
        (WTF::currentThread):
        * wtf/ThreadingWin.cpp:
        (WTF::threadMapMutex):
        (WTF::initializeThreading):
        (WTF::threadMap):
        (WTF::storeThreadHandleByIdentifier):
        (WTF::threadHandleForIdentifier):
        (WTF::clearThreadHandleForIdentifier):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::detachThread):
        (WTF::currentThread):
        * wtf/gtk/ThreadingGtk.cpp:
        (WTF::threadMapMutex):
        (WTF::initializeThreading):
        (WTF::threadMap):
        (WTF::identifierByGthreadHandle):
        (WTF::establishIdentifierForThread):
        (WTF::threadForIdentifier):
        (WTF::clearThreadForIdentifier):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::currentThread):
        * wtf/qt/ThreadingQt.cpp:
        (WTF::threadMapMutex):
        (WTF::threadMap):
        (WTF::identifierByQthreadHandle):
        (WTF::establishIdentifierForThread):
        (WTF::clearThreadForIdentifier):
        (WTF::threadForIdentifier):
        (WTF::initializeThreading):
        (WTF::createThreadInternal):
        (WTF::waitForThreadCompletion):
        (WTF::currentThread):

WebCore:

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

        Rubber-stamped by Mark Rowe.

        https://bugs.webkit.org/show_bug.cgi?id=25746
        Revert http://trac.webkit.org/changeset/43507 which caused crash in PPC nightlies with Safari 4.

        * dom/XMLTokenizerLibxml2.cpp:
        (WebCore::matchFunc):
        (WebCore::openFunc):
        (WebCore::createStringParser):
        (WebCore::createMemoryParser):
        * loader/icon/IconDatabase.cpp:
        (WebCore::IconDatabase::open):
        * platform/sql/SQLiteDatabase.cpp:
        (WebCore::SQLiteDatabase::SQLiteDatabase):
        (WebCore::SQLiteDatabase::close):
        * storage/DatabaseThread.cpp:
        (WebCore::DatabaseThread::DatabaseThread):
        (WebCore::DatabaseThread::start):
        (WebCore::DatabaseThread::databaseThread):
        * storage/LocalStorageThread.cpp:
        (WebCore::LocalStorageThread::LocalStorageThread):
        (WebCore::LocalStorageThread::start):
        (WebCore::LocalStorageThread::localStorageThread):
        (WebCore::LocalStorageThread::scheduleImport):
        (WebCore::LocalStorageThread::scheduleSync):
        (WebCore::LocalStorageThread::terminate):
        * workers/WorkerThread.cpp:
        (WebCore::WorkerThread::WorkerThread):
        (WebCore::WorkerThread::start):

WebKit/win:

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

        Rubber-stamped by Mark Rowe.

        https://bugs.webkit.org/show_bug.cgi?id=25746
        Revert http://trac.webkit.org/changeset/43507 which caused crash in PPC nightlies with Safari 4.

        * WebKit.vcproj/WebKit.def:
        * WebKit.vcproj/WebKit_debug.def:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@43663 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e378141a
2009-05-13 Dmitry Titov <dimich@chromium.org>
Rubber-stamped by Mark Rowe.
https://bugs.webkit.org/show_bug.cgi?id=25746
Revert http://trac.webkit.org/changeset/43507 which caused crash in PPC nightlies with Safari 4.
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore_debug.def:
* bytecode/SamplingTool.cpp:
(JSC::SamplingThread::start):
(JSC::SamplingThread::stop):
* bytecode/SamplingTool.h:
* wtf/CrossThreadRefCounted.h:
(WTF::CrossThreadRefCounted::CrossThreadRefCounted):
(WTF::::ref):
(WTF::::deref):
* wtf/Threading.h:
* wtf/ThreadingNone.cpp:
* wtf/ThreadingPthreads.cpp:
(WTF::threadMapMutex):
(WTF::initializeThreading):
(WTF::threadMap):
(WTF::identifierByPthreadHandle):
(WTF::establishIdentifierForPthreadHandle):
(WTF::pthreadHandleForIdentifier):
(WTF::clearPthreadHandleForIdentifier):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::detachThread):
(WTF::currentThread):
* wtf/ThreadingWin.cpp:
(WTF::threadMapMutex):
(WTF::initializeThreading):
(WTF::threadMap):
(WTF::storeThreadHandleByIdentifier):
(WTF::threadHandleForIdentifier):
(WTF::clearThreadHandleForIdentifier):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::detachThread):
(WTF::currentThread):
* wtf/gtk/ThreadingGtk.cpp:
(WTF::threadMapMutex):
(WTF::initializeThreading):
(WTF::threadMap):
(WTF::identifierByGthreadHandle):
(WTF::establishIdentifierForThread):
(WTF::threadForIdentifier):
(WTF::clearThreadForIdentifier):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::currentThread):
* wtf/qt/ThreadingQt.cpp:
(WTF::threadMapMutex):
(WTF::threadMap):
(WTF::identifierByQthreadHandle):
(WTF::establishIdentifierForThread):
(WTF::clearThreadForIdentifier):
(WTF::threadForIdentifier):
(WTF::initializeThreading):
(WTF::createThreadInternal):
(WTF::waitForThreadCompletion):
(WTF::currentThread):
2009-05-13 Darin Adler <darin@apple.com>
Revert the parser arena change. It was a slowdown, not a speedup.
......@@ -280,7 +280,7 @@ __ZN3WTF11currentTimeEv
__ZN3WTF11fastReallocEPvm
__ZN3WTF12createThreadEPFPvS0_ES0_
__ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadENS_16ThreadIdentifierE
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
__ZN3WTF13currentThreadEv
......@@ -301,7 +301,7 @@ __ZN3WTF21RefCountedLeakCounter9decrementEv
__ZN3WTF21RefCountedLeakCounter9incrementEv
__ZN3WTF21RefCountedLeakCounterC1EPKc
__ZN3WTF21RefCountedLeakCounterD1Ev
__ZN3WTF23waitForThreadCompletionENS_16ThreadIdentifierEPPv
__ZN3WTF23waitForThreadCompletionEjPPv
__ZN3WTF27releaseFastMallocFreeMemoryEv
__ZN3WTF28setMainThreadCallbacksPausedEb
__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
......@@ -363,8 +363,6 @@ __ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3JSC9HashTable11deleteTableEv
__ZNK3WTF8Collator7collateEPKtmS2_m
__ZNK3WTF16ThreadIdentifiereqERKS0_
__ZNK3WTF16ThreadIdentifierneERKS0_
__ZTVN3JSC12StringObjectE
__ZTVN3JSC14JSGlobalObjectE
__ZTVN3JSC15JSWrapperObjectE
......
......@@ -32,7 +32,6 @@ 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
......@@ -75,8 +74,9 @@ 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@@YA?AVThreadIdentifier@1@P6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YA?AVThreadIdentifier@1@XZ
?createThread@WTF@@YAIP6APAXPAX@Z0@Z
?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YAIXZ
?currentTime@WTF@@YANXZ
?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
......@@ -96,7 +96,7 @@ EXPORTS
?destroy@Heap@JSC@@QAEXXZ
?destroy@Rep@UString@JSC@@QAEXXZ
?detach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXVThreadIdentifier@1@@Z
?detachThread@WTF@@YAXI@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
......@@ -254,7 +254,7 @@ EXPORTS
?unprotect@Heap@JSC@@QAEXVJSValue@2@@Z
?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ
?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
?waitForThreadCompletion@WTF@@YAHVThreadIdentifier@1@PAPAX@Z
?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
WTFLog
WTFLogVerbose
WTFReportArgumentAssertionFailure
......@@ -265,7 +265,3 @@ 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
......@@ -32,7 +32,6 @@ 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
......@@ -75,8 +74,9 @@ 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@@YA?AVThreadIdentifier@1@P6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YA?AVThreadIdentifier@1@XZ
?createThread@WTF@@YAIP6APAXPAX@Z0@Z
?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z
?currentThread@WTF@@YAIXZ
?currentTime@WTF@@YANXZ
?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
......@@ -96,7 +96,7 @@ EXPORTS
?destroy@Heap@JSC@@QAEXXZ
?destroy@Rep@UString@JSC@@QAEXXZ
?detach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXVThreadIdentifier@1@@Z
?detachThread@WTF@@YAXI@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
......@@ -254,7 +254,7 @@ EXPORTS
?unprotect@Heap@JSC@@QAEXVJSValue@2@@Z
?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ
?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
?waitForThreadCompletion@WTF@@YAHVThreadIdentifier@1@PAPAX@Z
?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
WTFLog
WTFLogVerbose
WTFReportArgumentAssertionFailure
......@@ -265,7 +265,3 @@ 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,11 +121,7 @@ SamplingTool* SamplingTool::s_samplingTool = 0;
bool SamplingThread::s_running = false;
unsigned SamplingThread::s_hertz = 10000;
ThreadIdentifier& SamplingThread::samplingThread() {
DEFINE_STATIC_LOCAL(ThreadIdentifier, staticSamplingThread, ());
return staticSamplingThread;
}
ThreadIdentifier SamplingThread::s_samplingThread;
void* SamplingThread::threadStartFunc(void*)
{
......@@ -150,14 +146,14 @@ void SamplingThread::start(unsigned hertz)
s_running = true;
s_hertz = hertz;
samplingThread() = createThread(threadStartFunc, 0, "JavaScriptCore::Sampler");
s_samplingThread = createThread(threadStartFunc, 0, "JavaScriptCore::Sampler");
}
void SamplingThread::stop()
{
ASSERT(s_running);
s_running = false;
waitForThreadCompletion(samplingThread(), 0);
waitForThreadCompletion(s_samplingThread, 0);
}
......
......@@ -126,8 +126,7 @@ namespace JSC {
// Sampling thread state.
static bool s_running;
static unsigned s_hertz;
static ThreadIdentifier& samplingThread();
static ThreadIdentifier s_samplingThread;
static void start(unsigned hertz=10000);
static void stop();
......
......@@ -74,6 +74,9 @@ namespace WTF {
CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
: m_threadSafeRefCounter(threadedCounter)
, m_data(data)
#ifndef NDEBUG
, m_threadId(0)
#endif
{
}
......@@ -96,7 +99,7 @@ namespace WTF {
template<class T>
void CrossThreadRefCounted<T>::ref()
{
ASSERT(!m_threadId.isValid() || m_threadId == currentThread());
ASSERT(!m_threadId || m_threadId == currentThread());
m_refCounter.ref();
#ifndef NDEBUG
// Store the threadId as soon as the ref count gets to 2.
......@@ -104,7 +107,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.isValid() && m_refCounter.refCount() == 2)
if (!m_threadId && m_refCounter.refCount() == 2)
m_threadId = currentThread();
#endif
}
......@@ -112,7 +115,7 @@ namespace WTF {
template<class T>
void CrossThreadRefCounted<T>::deref()
{
ASSERT(!m_threadId.isValid() || m_threadId == currentThread());
ASSERT(!m_threadId || m_threadId == currentThread());
if (m_refCounter.derefBase()) {
threadSafeDeref();
delete this;
......@@ -121,7 +124,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.invalidate();
m_threadId = 0;
#endif
}
}
......
......@@ -85,14 +85,12 @@
#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
......@@ -107,18 +105,34 @@ 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;
......@@ -135,61 +149,11 @@ 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.
// A valid ThreadIdentifier is usually returned 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,9 +32,6 @@
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 ThreadIdentifier(); }
void setThreadNameInternal(const char*) { }
......
......@@ -48,15 +48,7 @@
namespace WTF {
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);
}
typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
static Mutex* atomicallyInitializedStaticMutex;
......@@ -64,10 +56,17 @@ 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();
......@@ -87,6 +86,54 @@ 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 {
......@@ -117,9 +164,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 ThreadIdentifier();
return 0;
}
return ThreadIdentifier(threadHandle);
return establishIdentifierForPthreadHandle(threadHandle);
}
#else
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
......@@ -127,10 +174,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 ThreadIdentifier();
return 0;
}
return ThreadIdentifier(threadHandle);
return establishIdentifierForPthreadHandle(threadHandle);
}
#endif
......@@ -145,29 +192,35 @@ void setThreadNameInternal(const char* threadName)
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
{
ASSERT(threadID.isValid());
pthread_t pthreadHandle = threadID.platformId();
ASSERT(threadID);
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
int joinResult = pthread_join(pthreadHandle, result);
if (joinResult == EDEADLK)
LOG_ERROR("ThreadIdentifier %p was found to be deadlocked trying to quit", pthreadHandle);
LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
clearPthreadHandleForIdentifier(threadID);
return joinResult;
}
void detachThread(ThreadIdentifier threadID)
{
ASSERT(threadID.isValid());
pthread_t pthreadHandle = threadID.platformId();
ASSERT(threadID);
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
pthread_detach(pthreadHandle);
clearPthreadHandleForIdentifier(threadID);
}
ThreadIdentifier currentThread()
{
return ThreadIdentifier(pthread_self());
pthread_t currentThread = pthread_self();
if (ThreadIdentifier id = identifierByPthreadHandle(currentThread))
return id;
return establishIdentifierForPthreadHandle(currentThread);
}
bool isMainThread()
......@@ -194,11 +247,11 @@ void Mutex::lock()
int result = pthread_mutex_lock(&m_mutex);
ASSERT_UNUSED(result, !result);
}
bool Mutex::tryLock()
{
int result = pthread_mutex_trylock(&m_mutex);
if (result == 0)
return true;
if (result == EBUSY)
......@@ -262,26 +315,6 @@ void ThreadCondition::broadcast()
ASSERT_UNUSED(result, !result);
}
#if PLATFORM(DARWIN)
// Derecated function. Safari 4 beta, until recompiled next time, uses ThreadIdentifier as uint32_t.
// pthread_t is a pointer. So they get a pointer casted into uint32_t from CurrentThread()
// and then pass it here. We cast it back to pointer. This is an ugly hack which is very temporary
// and will be removed once next public build of Safari 4 is released.
// Some versions of GCC require a prototype before a function with external linkage, so we have to
// add a declaration here before defining the function.
int waitForThreadCompletion(uint32_t, void**);
int waitForThreadCompletion(uint32_t threadID, void** result)
{
pthread_t pthreadHandle = reinterpret_cast<pthread_t>(threadID);
int joinResult = pthread_join(pthreadHandle, result);
if (joinResult == EDEADLK)
LOG_ERROR("ThreadIdentifier %p was found to be deadlocked trying to quit", pthreadHandle);
return joinResult;
}
#endif
} // namespace WTF
#endif // USE(PTHREADS)
......@@ -98,16 +98,6 @@
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;
......@@ -149,10 +139,17 @@ 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();
......@@ -160,6 +157,32 @@ void initializeThreading()
}
}
static HashMap<DWORD, HANDLE>& threadMap()
{
static HashMap<DWORD, HANDLE> map;
return map;
}