]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - wtf/Threading.h
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / wtf / Threading.h
index 5e5f020b81293c6fcc6fd0385fb1027a5133fcb0..b12f41fa771c92f98f6ef141698098f894d8272a 100644 (file)
@@ -59,9 +59,7 @@
 #ifndef Threading_h
 #define Threading_h
 
-#include <wtf/Platform.h>
-
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE)
 #include <windows.h>
 #endif
 
@@ -69,7 +67,7 @@
 #include <wtf/Locker.h>
 #include <wtf/Noncopyable.h>
 
-#if PLATFORM(WIN_OS) && !PLATFORM(WIN_CE)
+#if PLATFORM(WIN_OS) && !PLATFORM(WINCE)
 #include <windows.h>
 #elif PLATFORM(DARWIN)
 #include <libkern/OSAtomic.h>
@@ -89,14 +87,6 @@ typedef struct _GMutex GMutex;
 typedef struct _GCond GCond;
 #endif
 
-#if USE(PTHREADS) && (PLATFORM(MAC) || PLATFORM(IPHONE))
-#ifdef __OBJC__
-@class NSThread;
-#else
-class NSThread;
-#endif
-#endif
-
 #if PLATFORM(QT)
 #include <qglobal.h>
 QT_BEGIN_NAMESPACE
@@ -118,10 +108,17 @@ namespace WTF {
 typedef uint32_t ThreadIdentifier;
 typedef void* (*ThreadFunction)(void* argument);
 
-// Returns 0 if thread creation failed
+// 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**);
@@ -129,18 +126,22 @@ void detachThread(ThreadIdentifier);
 
 #if USE(PTHREADS)
 typedef pthread_mutex_t PlatformMutex;
+typedef pthread_rwlock_t PlatformReadWriteLock;
 typedef pthread_cond_t PlatformCondition;
 #elif PLATFORM(GTK)
 typedef GOwnPtr<GMutex> PlatformMutex;
+typedef void* PlatformReadWriteLock; // FIXME: Implement.
 typedef GOwnPtr<GCond> PlatformCondition;
 #elif PLATFORM(QT)
 typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;
+typedef void* PlatformReadWriteLock; // FIXME: Implement.
 typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;
 #elif PLATFORM(WIN_OS)
 struct PlatformMutex {
     CRITICAL_SECTION m_internalMutex;
     size_t m_recursionCount;
 };
+typedef void* PlatformReadWriteLock; // FIXME: Implement.
 struct PlatformCondition {
     size_t m_waitersGone;
     size_t m_waitersBlocked;
@@ -154,6 +155,7 @@ struct PlatformCondition {
 };
 #else
 typedef void* PlatformMutex;
+typedef void* PlatformReadWriteLock;
 typedef void* PlatformCondition;
 #endif
     
@@ -174,6 +176,23 @@ private:
 
 typedef Locker<Mutex> MutexLocker;
 
+class ReadWriteLock : Noncopyable {
+public:
+    ReadWriteLock();
+    ~ReadWriteLock();
+
+    void readLock();
+    bool tryReadLock();
+
+    void writeLock();
+    bool tryWriteLock();
+    
+    void unlock();
+
+private:
+    PlatformReadWriteLock m_readWriteLock;
+};
+
 class ThreadCondition : Noncopyable {
 public:
     ThreadCondition();
@@ -193,7 +212,7 @@ private:
 #if PLATFORM(WIN_OS)
 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1
 
-#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WIN_CE)
+#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WINCE)
 inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast<long*>(addend)); }
 inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
 #else
@@ -215,9 +234,9 @@ inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_
 
 #endif
 
-template<class T> class ThreadSafeShared : Noncopyable {
+class ThreadSafeSharedBase : Noncopyable {
 public:
-    ThreadSafeShared(int initialRefCount = 1)
+    ThreadSafeSharedBase(int initialRefCount = 1)
         : m_refCount(initialRefCount)
     {
     }
@@ -232,20 +251,6 @@ public:
 #endif
     }
 
-    void deref()
-    {
-#if USE(LOCKFREE_THREADSAFESHARED)
-        if (atomicDecrement(&m_refCount) <= 0)
-#else
-        {
-            MutexLocker locker(m_mutex);
-            --m_refCount;
-        }
-        if (m_refCount <= 0)
-#endif
-            delete static_cast<T*>(this);
-    }
-
     bool hasOneRef()
     {
         return refCount() == 1;
@@ -259,22 +264,54 @@ public:
         return static_cast<int const volatile &>(m_refCount);
     }
 
+protected:
+    // Returns whether the pointer should be freed or not.
+    bool derefBase()
+    {
+#if USE(LOCKFREE_THREADSAFESHARED)
+        if (atomicDecrement(&m_refCount) <= 0)
+            return true;
+#else
+        int refCount;
+        {
+            MutexLocker locker(m_mutex);
+            --m_refCount;
+            refCount = m_refCount;
+        }
+        if (refCount <= 0)
+            return true;
+#endif
+        return false;
+    }
+
 private:
+    template<class T>
+    friend class CrossThreadRefCounted;
+
     int m_refCount;
 #if !USE(LOCKFREE_THREADSAFESHARED)
     mutable Mutex m_mutex;
 #endif
 };
 
+template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {
+public:
+    ThreadSafeShared(int initialRefCount = 1)
+        : ThreadSafeSharedBase(initialRefCount)
+    {
+    }
+
+    void deref()
+    {
+        if (derefBase())
+            delete static_cast<T*>(this);
+    }
+};
+
 // This function must be called from the main thread. It is safe to call it repeatedly.
 // Darwin is an exception to this rule: it is OK to call it from any thread, the only requirement is that the calls are not reentrant.
 void initializeThreading();
 
-#if USE(PTHREADS) && (PLATFORM(MAC) || PLATFORM(IPHONE))
-void initializeMainNSThread();
-NSThread *mainNSThread();
-#endif
-    
 void lockAtomicallyInitializedStaticMutex();
 void unlockAtomicallyInitializedStaticMutex();