]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - wtf/ThreadingPthreads.cpp
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / wtf / ThreadingPthreads.cpp
index 3cc2f8a73ff2cf52f81016246718fad5c7b55742..0c6db2d1ec60c794b4f6a5264a55c9b612d30187 100644 (file)
@@ -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
  * (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;
@@ -63,7 +67,6 @@ void initializeThreading()
         threadMapMutex();
         initializeRandomNumberGenerator();
         mainThreadIdentifier = currentThread();
-        initializeMainNSThread();
         initializeMainThread();
     }
 }
@@ -107,14 +110,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);
 }
 
@@ -123,31 +126,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 HAVE(PTHREAD_SETNAME_NP)
+    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;
 }
@@ -155,11 +203,11 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
 void detachThread(ThreadIdentifier threadID)
 {
     ASSERT(threadID);
-    
+
     pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
-    
+
     pthread_detach(pthreadHandle);
-    
+
     clearPthreadHandleForIdentifier(threadID);
 }
 
@@ -188,27 +236,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()
@@ -223,8 +326,8 @@ 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 absoluteTime)
@@ -249,16 +352,16 @@ bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
 
 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)