diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-06-30 09:21:56 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-06-30 09:21:56 (GMT) |
commit | 197df24edfe095a10e2bf65116796e027fea44e2 (patch) | |
tree | 4ffb08f614b550298663f90297c9e559ecb47a3c /src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp | |
parent | 1e84894225e31adf80a7a33da7f655fb5c38ea0e (diff) | |
parent | e3c1039d4d10aa383a1f681e7dd9c1129d22d8ca (diff) | |
download | Qt-197df24edfe095a10e2bf65116796e027fea44e2.zip Qt-197df24edfe095a10e2bf65116796e027fea44e2.tar.gz Qt-197df24edfe095a10e2bf65116796e027fea44e2.tar.bz2 |
Merge commit 'qt/master-stable' into 4.6-merged
Conflicts:
.gitignore
configure.exe
src/corelib/concurrent/qtconcurrentthreadengine.h
src/corelib/global/qnamespace.h
src/gui/graphicsview/qgraphicssceneevent.h
src/gui/kernel/qapplication.cpp
src/gui/kernel/qapplication.h
src/gui/kernel/qapplication_p.h
src/gui/kernel/qapplication_qws.cpp
src/gui/kernel/qwidget.h
src/gui/painting/qpaintengine_raster.cpp
src/gui/text/qfontdatabase.cpp
src/network/access/qnetworkaccesshttpbackend.cpp
tests/auto/network-settings.h
tests/auto/qscriptjstestsuite/qscriptjstestsuite.pro
tests/auto/qvariant/tst_qvariant.cpp
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp')
-rw-r--r-- | src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp | 194 |
1 files changed, 147 insertions, 47 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp b/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp index f111fcf..d0e6df8 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) * * Redistribution and use in source and binary forms, with or without @@ -26,27 +26,33 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #include "config.h" #include "Threading.h" -#include "StdLibExtras.h" - #if USE(PTHREADS) +#include "CurrentTime.h" #include "HashMap.h" #include "MainThread.h" #include "RandomNumberSeed.h" - +#include "StdLibExtras.h" +#include "UnusedParam.h" #include <errno.h> +#include <limits.h> #include <sys/time.h> +#if PLATFORM(ANDROID) +#include "jni_utility.h" +#endif + namespace WTF { typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap; static Mutex* atomicallyInitializedStaticMutex; -#if !PLATFORM(DARWIN) +#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM) static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread. #endif @@ -62,7 +68,7 @@ void initializeThreading() atomicallyInitializedStaticMutex = new Mutex; threadMapMutex(); initializeRandomNumberGenerator(); -#if !PLATFORM(DARWIN) +#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM) mainThreadIdentifier = currentThread(); #endif initializeMainThread(); @@ -108,14 +114,14 @@ static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHa static ThreadIdentifier identifierCount = 1; threadMap().add(identifierCount, pthreadHandle); - + return identifierCount++; } static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id) { MutexLocker locker(threadMapMutex()); - + return threadMap().get(id); } @@ -124,31 +130,76 @@ 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 { + ThreadFunction entryPoint; + void* arg; +}; + +static void* runThreadWithRegistration(void* arg) +{ + ThreadData* data = static_cast<ThreadData*>(arg); + JavaVM* vm = JSC::Bindings::getJavaVM(); + JNIEnv* env; + void* ret = 0; + if (vm->AttachCurrentThread(&env, 0) == JNI_OK) { + ret = data->entryPoint(data->arg); + vm->DetachCurrentThread(); + } + delete data; + return ret; +} + +ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) +{ + pthread_t threadHandle; + ThreadData* threadData = new ThreadData(); + threadData->entryPoint = entryPoint; + threadData->arg = data; + + 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 establishIdentifierForPthreadHandle(threadHandle); +} +#else ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) { pthread_t threadHandle; - if (pthread_create(&threadHandle, NULL, entryPoint, data)) { + 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 establishIdentifierForPthreadHandle(threadHandle); } +#endif + +void setThreadNameInternal(const char* threadName) +{ +#if PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) + pthread_setname_np(threadName); +#else + UNUSED_PARAM(threadName); +#endif +} int waitForThreadCompletion(ThreadIdentifier threadID, void** result) { ASSERT(threadID); - + pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); - + int joinResult = pthread_join(pthreadHandle, result); if (joinResult == EDEADLK) LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); - + clearPthreadHandleForIdentifier(threadID); return joinResult; } @@ -156,11 +207,11 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result) void detachThread(ThreadIdentifier threadID) { ASSERT(threadID); - + pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); - + pthread_detach(pthreadHandle); - + clearPthreadHandleForIdentifier(threadID); } @@ -174,7 +225,7 @@ ThreadIdentifier currentThread() bool isMainThread() { -#if PLATFORM(DARWIN) +#if PLATFORM(DARWIN) && !PLATFORM(CHROMIUM) return pthread_main_np(); #else return currentThread() == mainThreadIdentifier; @@ -193,27 +244,82 @@ Mutex::~Mutex() void Mutex::lock() { - if (pthread_mutex_lock(&m_mutex) != 0) - ASSERT(false); + 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; - else if (result == EBUSY) + if (result == EBUSY) return false; - ASSERT(false); + ASSERT_NOT_REACHED(); return false; } void Mutex::unlock() { - if (pthread_mutex_unlock(&m_mutex) != 0) - ASSERT(false); + int result = pthread_mutex_unlock(&m_mutex); + ASSERT_UNUSED(result, !result); +} + + +ReadWriteLock::ReadWriteLock() +{ + pthread_rwlock_init(&m_readWriteLock, NULL); +} + +ReadWriteLock::~ReadWriteLock() +{ + pthread_rwlock_destroy(&m_readWriteLock); +} + +void ReadWriteLock::readLock() +{ + int result = pthread_rwlock_rdlock(&m_readWriteLock); + ASSERT_UNUSED(result, !result); +} + +bool ReadWriteLock::tryReadLock() +{ + int result = pthread_rwlock_tryrdlock(&m_readWriteLock); + + if (result == 0) + return true; + if (result == EBUSY || result == EAGAIN) + return false; + + ASSERT_NOT_REACHED(); + return false; +} + +void ReadWriteLock::writeLock() +{ + int result = pthread_rwlock_wrlock(&m_readWriteLock); + ASSERT_UNUSED(result, !result); +} + +bool ReadWriteLock::tryWriteLock() +{ + int result = pthread_rwlock_trywrlock(&m_readWriteLock); + + if (result == 0) + return true; + if (result == EBUSY || result == EAGAIN) + return false; + + ASSERT_NOT_REACHED(); + return false; +} + +void ReadWriteLock::unlock() +{ + int result = pthread_rwlock_unlock(&m_readWriteLock); + ASSERT_UNUSED(result, !result); } ThreadCondition::ThreadCondition() @@ -228,48 +334,42 @@ ThreadCondition::~ThreadCondition() void ThreadCondition::wait(Mutex& mutex) { - if (pthread_cond_wait(&m_condition, &mutex.impl()) != 0) - ASSERT(false); + int result = pthread_cond_wait(&m_condition, &mutex.impl()); + ASSERT_UNUSED(result, !result); } -bool ThreadCondition::timedWait(Mutex& mutex, double secondsToWait) +bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) { - if (secondsToWait < 0.0) { + if (absoluteTime < currentTime()) + return false; + + if (absoluteTime > INT_MAX) { wait(mutex); return true; } - int intervalSeconds = static_cast<int>(secondsToWait); - int intervalMicroseconds = static_cast<int>((secondsToWait - intervalSeconds) * 1000000.0); - - // Current time comes in sec/microsec - timeval currentTime; - gettimeofday(¤tTime, NULL); + int timeSeconds = static_cast<int>(absoluteTime); + int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9); - // Target time comes in sec/nanosec timespec targetTime; - targetTime.tv_sec = currentTime.tv_sec + intervalSeconds; - targetTime.tv_nsec = (currentTime.tv_usec + intervalMicroseconds) * 1000; - if (targetTime.tv_nsec > 1000000000) { - targetTime.tv_nsec -= 1000000000; - targetTime.tv_sec++; - } + targetTime.tv_sec = timeSeconds; + targetTime.tv_nsec = timeNanoseconds; return pthread_cond_timedwait(&m_condition, &mutex.impl(), &targetTime) == 0; } void ThreadCondition::signal() { - if (pthread_cond_signal(&m_condition) != 0) - ASSERT(false); + int result = pthread_cond_signal(&m_condition); + ASSERT_UNUSED(result, !result); } void ThreadCondition::broadcast() { - if (pthread_cond_broadcast(&m_condition) != 0) - ASSERT(false); + int result = pthread_cond_broadcast(&m_condition); + ASSERT_UNUSED(result, !result); } - + } // namespace WTF #endif // USE(PTHREADS) |