summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBobby Bingham <koorogi@koorogi.info>2023-03-27 22:07:16 -0500
committerMichele Calgaro <michele.calgaro@yahoo.it>2023-05-23 12:24:21 +0900
commit999cebcb5df0269d24d65db579a7c78a94053c2e (patch)
treedf7b916f6be7c3c5f6044a70a3cb6b572a0c1744
parent4ff2cb8b3ccf77ba3e111ac37b3fe0ebb15199eb (diff)
downloadtqt3-999cebcb5df0269d24d65db579a7c78a94053c2e.tar.gz
tqt3-999cebcb5df0269d24d65db579a7c78a94053c2e.zip
Fix level when using pthreads recursive mutex
When using the pthreads recursive mutex, the level method was only able to return either zero or one, but a recursive mutex can be locked more than once. Additionally, the way this detected if the mutex was already locked was to test whether it can be locked again. If testing from the thread that is currently holding the lock, this locking attempt always succeeds, and therefore determines that the lock is _not_ held at all. This is especially bad, as this operation only makes sense to perform from the thread that holds the lock -- if any thread not holding the lock queries the number of times the lock is held, that answer can change before the thread can used it. Signed-off-by: Bobby Bingham <koorogi@koorogi.info>
-rw-r--r--src/tools/qmutex_unix.cpp28
1 files changed, 12 insertions, 16 deletions
diff --git a/src/tools/qmutex_unix.cpp b/src/tools/qmutex_unix.cpp
index dae1533c4..5cb037a18 100644
--- a/src/tools/qmutex_unix.cpp
+++ b/src/tools/qmutex_unix.cpp
@@ -88,6 +88,7 @@ public:
int level();
bool recursive;
+ int count;
};
#ifndef Q_RECURSIVE_MUTEX_TYPE
@@ -127,7 +128,7 @@ TQMutexPrivate::~TQMutexPrivate()
// real mutex class
TQRealMutexPrivate::TQRealMutexPrivate(bool recurs)
- : recursive(recurs)
+ : count(0), recursive(recurs)
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@@ -146,36 +147,31 @@ void TQRealMutexPrivate::lock()
{
int ret = pthread_mutex_lock(&handle);
+ if (!ret) {
+ count++;
+ } else {
#ifdef QT_CHECK_RANGE
- if (ret)
tqWarning("Mutex lock failure: %s", strerror(ret));
#endif
+ }
}
void TQRealMutexPrivate::unlock()
{
+ count--;
int ret = pthread_mutex_unlock(&handle);
+ if (ret) {
+ count++;
#ifdef QT_CHECK_RANGE
- if (ret)
tqWarning("Mutex unlock failure: %s", strerror(ret));
#endif
+ }
}
bool TQRealMutexPrivate::locked()
{
- int ret = pthread_mutex_trylock(&handle);
-
- if (ret == EBUSY) {
- return TRUE;
- } else if (ret) {
-#ifdef QT_CHECK_RANGE
- tqWarning("Mutex locktest failure: %s", strerror(ret));
-#endif
- } else
- pthread_mutex_unlock(&handle);
-
- return FALSE;
+ return count > 0;
}
bool TQRealMutexPrivate::trylock()
@@ -201,7 +197,7 @@ int TQRealMutexPrivate::type() const
int TQRealMutexPrivate::level()
{
- return locked();
+ return count;
}