#include "wtf/ThreadIdentifierDataPthreads.h"
#include "wtf/ThreadSpecific.h"
#include "wtf/ThreadingPrimitives.h"
-#include "wtf/UnusedParam.h"
#include "wtf/WTFThreadData.h"
#include "wtf/dtoa.h"
#include "wtf/dtoa/cached-powers.h"
OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(new ThreadFunctionInvocation(entryPoint, data));
pthread_t threadHandle;
if (pthread_create(&threadHandle, 0, wtfThreadEntryPoint, invocation.get())) {
- LOG_ERROR("Failed to create pthread at entry point %p with data %p", wtfThreadEntryPoint, invocation.get());
+ WTF_LOG_ERROR("Failed to create pthread at entry point %p with data %p", wtfThreadEntryPoint, invocation.get());
return 0;
}
// Balanced by adoptPtr() in wtfThreadEntryPoint.
- ThreadFunctionInvocation* leakedInvocation = invocation.leakPtr();
- UNUSED_PARAM(leakedInvocation);
+ ThreadFunctionInvocation* leakedInvocation ALLOW_UNUSED = invocation.leakPtr();
return establishIdentifierForPthreadHandle(threadHandle);
}
void initializeCurrentThreadInternal(const char* threadName)
{
-#if HAVE(PTHREAD_SETNAME_NP)
+#if OS(MACOSX)
pthread_setname_np(threadName);
-#else
- UNUSED_PARAM(threadName);
-#endif
-#if OS(MACOSX)
// All threads that potentially use APIs above the BSD layer must be registered with the Objective-C
// garbage collector in case API implementations use garbage-collected memory.
objc_registerThreadWithCollector();
int joinResult = pthread_join(pthreadHandle, 0);
if (joinResult == EDEADLK)
- LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
+ WTF_LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
else if (joinResult)
- LOG_ERROR("ThreadIdentifier %u was unable to be joined.\n", threadID);
+ WTF_LOG_ERROR("ThreadIdentifier %u was unable to be joined.\n", threadID);
MutexLocker locker(threadMapMutex());
PthreadState* state = threadMap().get(threadID);
int detachResult = pthread_detach(pthreadHandle);
if (detachResult)
- LOG_ERROR("ThreadIdentifier %u was unable to be detached\n", threadID);
+ WTF_LOG_ERROR("ThreadIdentifier %u was unable to be detached\n", threadID);
PthreadState* state = threadMap().get(threadID);
ASSERT(state);
return id;
}
-Mutex::Mutex()
+MutexBase::MutexBase(bool recursive)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
+ pthread_mutexattr_settype(&attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL);
- int result = pthread_mutex_init(&m_mutex, &attr);
+ int result = pthread_mutex_init(&m_mutex.m_internalMutex, &attr);
ASSERT_UNUSED(result, !result);
+#if ENABLE(ASSERT)
+ m_mutex.m_recursionCount = 0;
+#endif
pthread_mutexattr_destroy(&attr);
}
-Mutex::~Mutex()
+MutexBase::~MutexBase()
{
- int result = pthread_mutex_destroy(&m_mutex);
+ int result = pthread_mutex_destroy(&m_mutex.m_internalMutex);
ASSERT_UNUSED(result, !result);
}
-void Mutex::lock()
+void MutexBase::lock()
{
- int result = pthread_mutex_lock(&m_mutex);
+ int result = pthread_mutex_lock(&m_mutex.m_internalMutex);
ASSERT_UNUSED(result, !result);
+#if ENABLE(ASSERT)
+ ++m_mutex.m_recursionCount;
+#endif
}
-bool Mutex::tryLock()
+void MutexBase::unlock()
{
- int result = pthread_mutex_trylock(&m_mutex);
+#if ENABLE(ASSERT)
+ ASSERT(m_mutex.m_recursionCount);
+ --m_mutex.m_recursionCount;
+#endif
+ int result = pthread_mutex_unlock(&m_mutex.m_internalMutex);
+ ASSERT_UNUSED(result, !result);
+}
- if (result == 0)
+// There is a separate tryLock implementation for the Mutex and the
+// RecursiveMutex since on Windows we need to manually check if tryLock should
+// succeed or not for the non-recursive mutex. On Linux the two implementations
+// are equal except we can assert the recursion count is always zero for the
+// non-recursive mutex.
+bool Mutex::tryLock()
+{
+ int result = pthread_mutex_trylock(&m_mutex.m_internalMutex);
+ if (result == 0) {
+#if ENABLE(ASSERT)
+ // The Mutex class is not recursive, so the recursionCount should be
+ // zero after getting the lock.
+ ASSERT(!m_mutex.m_recursionCount);
+ ++m_mutex.m_recursionCount;
+#endif
return true;
+ }
if (result == EBUSY)
return false;
return false;
}
-void Mutex::unlock()
+bool RecursiveMutex::tryLock()
{
- int result = pthread_mutex_unlock(&m_mutex);
- ASSERT_UNUSED(result, !result);
+ int result = pthread_mutex_trylock(&m_mutex.m_internalMutex);
+ if (result == 0) {
+#if ENABLE(ASSERT)
+ ++m_mutex.m_recursionCount;
+#endif
+ return true;
+ }
+ if (result == EBUSY)
+ return false;
+
+ ASSERT_NOT_REACHED();
+ return false;
}
ThreadCondition::ThreadCondition()
pthread_cond_destroy(&m_condition);
}
-void ThreadCondition::wait(Mutex& mutex)
+void ThreadCondition::wait(MutexBase& mutex)
{
- int result = pthread_cond_wait(&m_condition, &mutex.impl());
+ PlatformMutex& platformMutex = mutex.impl();
+ int result = pthread_cond_wait(&m_condition, &platformMutex.m_internalMutex);
ASSERT_UNUSED(result, !result);
+#if ENABLE(ASSERT)
+ ++platformMutex.m_recursionCount;
+#endif
}
-bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
+bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime)
{
if (absoluteTime < currentTime())
return false;
targetTime.tv_sec = timeSeconds;
targetTime.tv_nsec = timeNanoseconds;
- return pthread_cond_timedwait(&m_condition, &mutex.impl(), &targetTime) == 0;
+ PlatformMutex& platformMutex = mutex.impl();
+ int result = pthread_cond_timedwait(&m_condition, &platformMutex.m_internalMutex, &targetTime);
+#if ENABLE(ASSERT)
+ ++platformMutex.m_recursionCount;
+#endif
+ return result == 0;
}
void ThreadCondition::signal()