X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/ba379fdc102753d6be2c4d937058fe40257329fe..14957cd040308e3eeec43d26bae5d76da13fcd85:/wtf/ThreadingWin.cpp?ds=inline diff --git a/wtf/ThreadingWin.cpp b/wtf/ThreadingWin.cpp index ea18656..c452205 100644 --- a/wtf/ThreadingWin.cpp +++ b/wtf/ThreadingWin.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -86,16 +87,27 @@ #include "Threading.h" #include "MainThread.h" -#if !USE(PTHREADS) && PLATFORM(WIN_OS) -#include "ThreadSpecific.h" -#endif -#include +#include "ThreadFunctionInvocation.h" #include #include #include #include +#include +#include #include +#if !USE(PTHREADS) && OS(WINDOWS) +#include "ThreadSpecific.h" +#endif + +#if !OS(WINCE) +#include +#endif + +#if HAVE(ERRNO_H) +#include +#endif + namespace WTF { // MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from . @@ -110,7 +122,7 @@ typedef struct tagTHREADNAME_INFO { } THREADNAME_INFO; #pragma pack(pop) -void setThreadNameInternal(const char* szThreadName) +void initializeCurrentThreadInternal(const char* szThreadName) { THREADNAME_INFO info; info.dwType = 0x1000; @@ -137,8 +149,6 @@ void unlockAtomicallyInitializedStaticMutex() atomicallyInitializedStaticMutex->unlock(); } -static ThreadIdentifier mainThreadIdentifier; - static Mutex& threadMapMutex() { static Mutex mutex; @@ -147,14 +157,12 @@ static Mutex& threadMapMutex() void initializeThreading() { - if (!atomicallyInitializedStaticMutex) { - atomicallyInitializedStaticMutex = new Mutex; - threadMapMutex(); - initializeRandomNumberGenerator(); - initializeMainThread(); - mainThreadIdentifier = currentThread(); - setThreadNameInternal("Main Thread"); - } + if (atomicallyInitializedStaticMutex) + return; + + atomicallyInitializedStaticMutex = new Mutex; + threadMapMutex(); + initializeRandomNumberGenerator(); } static HashMap& threadMap() @@ -183,21 +191,12 @@ static void clearThreadHandleForIdentifier(ThreadIdentifier id) threadMap().remove(id); } -struct ThreadFunctionInvocation { - ThreadFunctionInvocation(ThreadFunction function, void* data) : function(function), data(data) {} - - ThreadFunction function; - void* data; -}; - static unsigned __stdcall wtfThreadEntryPoint(void* param) { - ThreadFunctionInvocation invocation = *static_cast(param); - delete static_cast(param); - - void* result = invocation.function(invocation.data); + OwnPtr invocation = adoptPtr(static_cast(param)); + void* result = invocation->function(invocation->data); -#if !USE(PTHREADS) && PLATFORM(WIN_OS) +#if !USE(PTHREADS) && OS(WINDOWS) // Do the TLS cleanup. ThreadSpecificThreadExit(); #endif @@ -209,13 +208,28 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con { unsigned threadIdentifier = 0; ThreadIdentifier threadID = 0; - ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data); - HANDLE threadHandle = reinterpret_cast(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier)); + OwnPtr invocation = adoptPtr(new ThreadFunctionInvocation(entryPoint, data)); +#if OS(WINCE) + // This is safe on WINCE, since CRT is in the core and innately multithreaded. + // On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions + HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation.get(), 0, (LPDWORD)&threadIdentifier); +#else + HANDLE threadHandle = reinterpret_cast(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation.get(), 0, &threadIdentifier)); +#endif if (!threadHandle) { +#if OS(WINCE) + LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError()); +#elif !HAVE(ERRNO_H) + LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data); +#else LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, errno); +#endif return 0; } + // The thread will take ownership of invocation. + invocation.leakPtr(); + threadID = static_cast(threadIdentifier); storeThreadHandleByIdentifier(threadIdentifier, threadHandle); @@ -250,14 +264,14 @@ void detachThread(ThreadIdentifier threadID) clearThreadHandleForIdentifier(threadID); } -ThreadIdentifier currentThread() +void yield() { - return static_cast(GetCurrentThreadId()); + ::Sleep(1); } -bool isMainThread() +ThreadIdentifier currentThread() { - return currentThread() == mainThreadIdentifier; + return static_cast(GetCurrentThreadId()); } Mutex::Mutex() @@ -318,6 +332,7 @@ bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMillisecon res = ReleaseSemaphore(m_blockLock, 1, 0); ASSERT(res); + --mutex.m_recursionCount; LeaveCriticalSection(&mutex.m_internalMutex); // Main wait - use timeout. @@ -351,6 +366,7 @@ bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMillisecon } EnterCriticalSection (&mutex.m_internalMutex); + ++mutex.m_recursionCount; return !timedOut; } @@ -444,20 +460,15 @@ void ThreadCondition::wait(Mutex& mutex) bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) { - double currentTime = WTF::currentTime(); + DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); - // Time is in the past - return immediately. - if (absoluteTime < currentTime) + if (!interval) { + // Consider the wait to have timed out, even if our condition has already been signaled, to + // match the pthreads implementation. return false; - - // Time is too far in the future (and would overflow unsigned long) - wait forever. - if (absoluteTime - currentTime > static_cast(INT_MAX) / 1000.0) { - wait(mutex); - return true; } - double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0; - return m_condition.timedWait(mutex.impl(), static_cast(intervalMilliseconds)); + return m_condition.timedWait(mutex.impl(), interval); } void ThreadCondition::signal() @@ -470,4 +481,19 @@ void ThreadCondition::broadcast() m_condition.signal(true); // Unblock all threads. } +DWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime) +{ + double currentTime = WTF::currentTime(); + + // Time is in the past - return immediately. + if (absoluteTime < currentTime) + return 0; + + // Time is too far in the future (and would overflow unsigned long) - wait forever. + if (absoluteTime - currentTime > static_cast(INT_MAX) / 1000.0) + return INFINITE; + + return static_cast((absoluteTime - currentTime) * 1000.0); +} + } // namespace WTF