diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index cbc47ad3d8eff25a4416a937b190bfb617e79718..d0e490ea7dc4401965e879720a9c7478715ef738 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,24 @@ +2009-06-12 Dave Hyatt + + Reviewed by Anders Carlsson. + + https://bugs.webkit.org/show_bug.cgi?id=26373 + + Add a new class to Threading in wtf called ReadWriteLock that handles single writer/multiple reader locking. + Provide a pthreads-only implementation of the lock for now, as this class is only going to be used + on Snow Leopard at first. + + * wtf/Threading.h: + (WTF::ReadWriteLock::impl): + * wtf/ThreadingPthreads.cpp: + (WTF::ReadWriteLock::ReadWriteLock): + (WTF::ReadWriteLock::~ReadWriteLock): + (WTF::ReadWriteLock::readLock): + (WTF::ReadWriteLock::tryReadLock): + (WTF::ReadWriteLock::writeLock): + (WTF::ReadWriteLock::tryWriteLock): + (WTF::ReadWriteLock::unlock): + 2009-06-12 Oliver Hunt Reviewed by Geoff Garen. diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h index 02fa3a4cd70794f932052b613f6dca921a1bd498..d244768a88b2ad29c73506c9ae59291350a3a8b6 100644 --- a/JavaScriptCore/wtf/Threading.h +++ b/JavaScriptCore/wtf/Threading.h @@ -126,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 PlatformMutex; +typedef void* PlatformReadWriteLock; // FIXME: Implement. typedef GOwnPtr 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; @@ -151,6 +155,7 @@ struct PlatformCondition { }; #else typedef void* PlatformMutex; +typedef void* PlatformReadWriteLock; typedef void* PlatformCondition; #endif @@ -171,6 +176,23 @@ private: typedef Locker 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(); diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp index f54dd3f8322b54a38327204d7d860c87f0cdd2fd..d0e6df8fb7bc7d8a203e22a94356883003f07fce 100644 --- a/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -267,6 +267,61 @@ void Mutex::unlock() 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() { pthread_cond_init(&m_condition, NULL);