diff options
author | Olivier Goffart <ogoffart@kde.org> | 2011-10-20 17:11:18 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-31 12:16:11 +0100 |
commit | 73b682d816ec12afbf8064a44e462dd89e4c38df (patch) | |
tree | 667bc44e7fce3b618b2ceb3e70b7d087f7bff77b /src/corelib/thread/qmutex.cpp | |
parent | 72257f642944a347b806ac34934d0fb8bc472b1c (diff) |
QRecursiveMutexPrivate should not inherit from QMutexPrivate
QMutexPrivate takes more memory than necessary, and also initialize
platform specific ressources.
Change-Id: I70be1b89b1c21499645785ae47693a6b2514e28b
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
Diffstat (limited to 'src/corelib/thread/qmutex.cpp')
-rw-r--r-- | src/corelib/thread/qmutex.cpp | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp index 88aee2b4c9..6ba0a8ca35 100644 --- a/src/corelib/thread/qmutex.cpp +++ b/src/corelib/thread/qmutex.cpp @@ -150,11 +150,16 @@ QMutex::QMutex(RecursionMode mode) */ QMutex::~QMutex() { - if (isRecursive()) - delete static_cast<QRecursiveMutexPrivate *>(d_ptr.load()); - else if (d_ptr.load()) { + QMutexData *d = d_ptr.load(); + if (quintptr(d) > 0x3 && d->recursive) { + delete static_cast<QRecursiveMutexPrivate *>(d); + } else if (d) { #ifndef Q_OS_LINUX - if (d_ptr.load()->possiblyUnlocked.load() && tryLock()) { unlock(); return; } + if (d != dummyLocked() && static_cast<QMutexPrivate *>(d)->possiblyUnlocked.load() + && tryLock()) { + unlock(); + return; + } #endif qWarning("QMutex: destroying locked mutex"); } @@ -233,7 +238,7 @@ QMutex::~QMutex() */ bool QBasicMutex::isRecursive() { - QMutexPrivate *d = d_ptr.load(); + QMutexData *d = d_ptr.load(); if (quintptr(d) <= 0x3) return false; return d->recursive; @@ -342,30 +347,31 @@ bool QBasicMutex::isRecursive() { bool QBasicMutex::lockInternal(int timeout) { while (!fastTryLock()) { - QMutexPrivate *d = d_ptr.loadAcquire(); - if (!d) // if d is 0, the mutex is unlocked + QMutexData *copy = d_ptr.loadAcquire(); + if (!copy) // if d is 0, the mutex is unlocked continue; - if (d == dummyLocked()) { + if (copy == dummyLocked()) { if (timeout == 0) return false; QMutexPrivate *newD = QMutexPrivate::allocate(); - if (!d_ptr.testAndSetOrdered(d, newD)) { + if (!d_ptr.testAndSetOrdered(dummyLocked(), newD)) { //Either the mutex is already unlocked, or another thread already set it. newD->deref(); continue; } - d = newD; + copy = newD; //the d->refCount is already 1 the deref will occurs when we unlock - } else if (d->recursive) { - return static_cast<QRecursiveMutexPrivate *>(d)->lock(timeout); + } else if (copy->recursive) { + return static_cast<QRecursiveMutexPrivate *>(copy)->lock(timeout); } + QMutexPrivate *d = static_cast<QMutexPrivate *>(copy); if (timeout == 0 && !d->possiblyUnlocked.load()) return false; if (!d->ref()) - continue; //that QMutexPrivate was already released + continue; //that QMutexData was already released if (d != d_ptr.loadAcquire()) { //Either the mutex is already unlocked, or relocked with another mutex @@ -433,15 +439,17 @@ bool QBasicMutex::lockInternal(int timeout) */ void QBasicMutex::unlockInternal() { - QMutexPrivate *d = d_ptr.loadAcquire(); - Q_ASSERT(d); //we must be locked - Q_ASSERT(d != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed + QMutexData *copy = d_ptr.loadAcquire(); + Q_ASSERT(copy); //we must be locked + Q_ASSERT(copy != dummyLocked()); // testAndSetRelease(dummyLocked(), 0) failed - if (d->recursive) { - static_cast<QRecursiveMutexPrivate *>(d)->unlock(); + if (copy->recursive) { + static_cast<QRecursiveMutexPrivate *>(copy)->unlock(); return; } + QMutexPrivate *d = reinterpret_cast<QMutexPrivate *>(copy); + if (d->waiters.fetchAndAddRelease(-QMutexPrivate::BigNumber) == 0) { //there is no one waiting on this mutex anymore, set the mutex as unlocked (d = 0) if (d_ptr.testAndSetRelease(d, 0)) { |