Enable use of pthread's recursive mutexes

Signed-off-by: Bobby Bingham <koorogi@koorogi.info>
pull/72/head
Bobby Bingham 11 months ago committed by Michele Calgaro
parent b6e9b6c6c4
commit 0b3c8dfbc9
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -44,29 +44,12 @@
typedef pthread_mutex_t Q_MUTEX_T;
// POSIX threads mutex types
#if (defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) && \
!defined(Q_OS_UNIXWARE) && !defined(Q_OS_SOLARIS) && \
!defined(Q_OS_MAC)
// POSIX 1003.1c-1995 - We love this OS
# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b))
# if defined(QT_CHECK_RANGE)
# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK
# else
# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
# endif
# define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE
#elif defined(MUTEX_NONRECURSIVE_NP) && defined(MUTEX_RECURSIVE_NP)
// POSIX 1003.4a pthreads draft extensions
# define Q_MUTEX_SET_TYPE(a, b) pthread_mutexattr_setkind_np((a), (b));
# define Q_NORMAL_MUTEX_TYPE MUTEX_NONRECURSIVE_NP
# define Q_RECURSIVE_MUTEX_TYPE MUTEX_RECURSIVE_NP
#if defined(QT_CHECK_RANGE)
# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK
#else
// Unknown mutex types - skip them
# define Q_MUTEX_SET_TYPE(a, b)
# undef Q_NORMAL_MUTEX_TYPE
# undef Q_RECURSIVE_MUTEX_TYPE
# define Q_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
#endif
#define Q_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE
#include "ntqmutex.h"
#include "qmutex_p.h"
@ -91,27 +74,6 @@ public:
int count;
};
#ifndef Q_RECURSIVE_MUTEX_TYPE
class TQRecursiveMutexPrivate : public TQMutexPrivate
{
public:
TQRecursiveMutexPrivate();
~TQRecursiveMutexPrivate();
void lock();
void unlock();
bool locked();
bool trylock();
int type() const;
int level();
int count;
pthread_t owner;
bool is_owned;
pthread_mutex_t handle2;
};
#endif // !Q_RECURSIVE_MUTEX_TYPE
// Private class implementation
@ -128,12 +90,11 @@ TQMutexPrivate::~TQMutexPrivate()
// real mutex class
TQRealMutexPrivate::TQRealMutexPrivate(bool recurs)
: count(0), recursive(recurs)
: recursive(recurs), count(0)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
Q_MUTEX_SET_TYPE(&attr, recursive ? Q_RECURSIVE_MUTEX_TYPE : Q_NORMAL_MUTEX_TYPE);
Q_UNUSED(recursive);
pthread_mutexattr_settype(&attr, recursive ? Q_RECURSIVE_MUTEX_TYPE : Q_NORMAL_MUTEX_TYPE);
int ret = pthread_mutex_init(&handle, &attr);
pthread_mutexattr_destroy(&attr);
@ -201,146 +162,6 @@ int TQRealMutexPrivate::level()
}
#ifndef Q_RECURSIVE_MUTEX_TYPE
TQRecursiveMutexPrivate::TQRecursiveMutexPrivate()
: count(0), is_owned(false)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
Q_MUTEX_SET_TYPE(&attr, Q_NORMAL_MUTEX_TYPE);
int ret = pthread_mutex_init(&handle, &attr);
pthread_mutexattr_destroy(&attr);
# ifdef QT_CHECK_RANGE
if (ret)
tqWarning( "Mutex init failure: %s", strerror(ret) );
# endif
pthread_mutexattr_init(&attr);
ret = pthread_mutex_init( &handle2, &attr );
pthread_mutexattr_destroy(&attr);
# ifdef QT_CHECK_RANGE
if (ret)
tqWarning( "Mutex init failure: %s", strerror(ret) );
# endif
}
TQRecursiveMutexPrivate::~TQRecursiveMutexPrivate()
{
int ret = pthread_mutex_destroy(&handle2);
# ifdef QT_CHECK_RANGE
if (ret)
tqWarning( "Mutex destroy failure: %s", strerror(ret) );
# endif
}
void TQRecursiveMutexPrivate::lock()
{
pthread_mutex_lock(&handle2);
if (count > 0 && pthread_equal(owner, pthread_self()) ) {
count++;
} else {
pthread_mutex_unlock(&handle2);
pthread_mutex_lock(&handle);
pthread_mutex_lock(&handle2);
count = 1;
owner = pthread_self();
is_owned = true;
}
pthread_mutex_unlock(&handle2);
}
void TQRecursiveMutexPrivate::unlock()
{
pthread_mutex_lock(&handle2);
if ( is_owned && pthread_equal(owner, pthread_self()) ) {
// do nothing if the count is already 0... to reflect the behaviour described
// in the docs
if (count && (--count) < 1) {
count = 0;
pthread_mutex_unlock(&handle);
}
} else {
#ifdef QT_CHECK_RANGE
tqWarning("TQMutex::unlock: unlock from different thread than locker");
#endif
}
pthread_mutex_unlock(&handle2);
}
bool TQRecursiveMutexPrivate::locked()
{
pthread_mutex_lock(&handle2);
bool ret;
int code = pthread_mutex_trylock(&handle);
if (code == EBUSY) {
ret = TRUE;
} else {
#ifdef QT_CHECK_RANGE
if (code)
tqWarning("Mutex trylock failure: %s", strerror(code));
#endif
pthread_mutex_unlock(&handle);
ret = FALSE;
}
pthread_mutex_unlock(&handle2);
return ret;
}
bool TQRecursiveMutexPrivate::trylock()
{
bool ret = TRUE;
pthread_mutex_lock(&handle2);
if ( count > 0 && pthread_equal(owner, pthread_self()) ) {
count++;
} else {
int code = pthread_mutex_trylock(&handle);
if (code == EBUSY) {
ret = FALSE;
} else if (code) {
#ifdef QT_CHECK_RANGE
tqWarning("Mutex trylock failure: %s", strerror(code));
#endif
ret = FALSE;
} else {
count = 1;
owner = pthread_self();
is_owned = true;
}
}
pthread_mutex_unlock(&handle2);
return ret;
}
int TQRecursiveMutexPrivate::type() const
{
return Q_MUTEX_RECURSIVE;
}
int TQRecursiveMutexPrivate::level()
{
return count;
}
#endif // !Q_RECURSIVE_MUTEX_TYPE
/*!
\class TQMutex ntqmutex.h
\threadsafe
@ -445,11 +266,6 @@ int TQRecursiveMutexPrivate::level()
*/
TQMutex::TQMutex(bool recursive)
{
#ifndef Q_RECURSIVE_MUTEX_TYPE
if ( recursive )
d = new TQRecursiveMutexPrivate();
else
#endif // !Q_RECURSIVE_MUTEX_TYPE
d = new TQRealMutexPrivate(recursive);
}

Loading…
Cancel
Save