summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-06-30 09:21:56 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-06-30 09:21:56 (GMT)
commit197df24edfe095a10e2bf65116796e027fea44e2 (patch)
tree4ffb08f614b550298663f90297c9e559ecb47a3c /src/3rdparty/webkit/JavaScriptCore/wtf/ThreadingPthreads.cpp
parent1e84894225e31adf80a7a33da7f655fb5c38ea0e (diff)
parente3c1039d4d10aa383a1f681e7dd9c1129d22d8ca (diff)
downloadQt-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.cpp194
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(&currentTime, 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)