summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-09-04 10:41:56 +0200
committerLars Knoll <lars.knoll@qt.io>2020-10-17 12:02:49 +0200
commit77d812683f0ad595606f9833613dd49bb2fda26d (patch)
treec1fb2f4a3e680db9c5597574fe8684571da0e0f5 /src
parentf76530a6171ca417865863b66e3ea439c27d057e (diff)
Refactor QMutexLocker to be able to handle recursive mutexes
Since we're going to split QMutex and QRecursiveMutex into separate classes, make sure QMutexLocker is prepared for that. Change-Id: Id5e9a955d1db7c8ee663dd3811ad6448dad0aeae Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qprocess_p.h2
-rw-r--r--src/corelib/kernel/qeventloop.cpp4
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp4
-rw-r--r--src/corelib/thread/qmutex.cpp2
-rw-r--r--src/corelib/thread/qmutex.h71
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h2
-rw-r--r--src/network/ssl/qsslsocket_mac.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp4
8 files changed, 39 insertions, 52 deletions
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 9518b099f2..b04e05114d 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -147,7 +147,7 @@ public:
inline Value prepareValue(const QString &value) const { return value; }
inline QString valueToString(const Value &value) const { return value; }
#else
- struct NameMapMutexLocker : public QMutexLocker
+ struct NameMapMutexLocker : public QMutexLocker<QMutex>
{
NameMapMutexLocker(const QProcessEnvironmentPrivate *d) : QMutexLocker(&d->nameMapMutex) {}
};
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index 5a5dfb06aa..1938a65ca5 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -179,10 +179,10 @@ int QEventLoop::exec(ProcessEventsFlags flags)
struct LoopReference {
QEventLoopPrivate *d;
- QMutexLocker &locker;
+ QMutexLocker<QMutex> &locker;
bool exceptionCaught;
- LoopReference(QEventLoopPrivate *d, QMutexLocker &locker) : d(d), locker(locker), exceptionCaught(true)
+ LoopReference(QEventLoopPrivate *d, QMutexLocker<QMutex> &locker) : d(d), locker(locker), exceptionCaught(true)
{
d->inExec = true;
d->exit.storeRelease(false);
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index 835db956ed..14f9f389e8 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -601,7 +601,7 @@ int QtAndroidPrivate::acuqireServiceSetup(int flags)
void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *listener)
{
- QMutexLocker lock(g_onBindListenerMutex);
+ QMutexLocker lock(g_onBindListenerMutex());
*g_onBindListener = listener;
if (!g_serviceSetupLockers->deref())
g_waitForServiceSetupSemaphore->release();
@@ -609,7 +609,7 @@ void QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *liste
jobject QtAndroidPrivate::callOnBindListener(jobject intent)
{
- QMutexLocker lock(g_onBindListenerMutex);
+ QMutexLocker lock(g_onBindListenerMutex());
if (*g_onBindListener)
return (*g_onBindListener)->onBind(intent);
return nullptr;
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 7ae07a3aa2..531f417f92 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -423,7 +423,7 @@ QRecursiveMutex::~QRecursiveMutex()
\ingroup thread
- Locking and unlocking a QMutex in complex functions and
+ Locking and unlocking a QMutex or QRecursiveMutex in complex functions and
statements or in exception handling code is error-prone and
difficult to debug. QMutexLocker can be used in such situations
to ensure that the state of the mutex is always well-defined.
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index b29a7e3a9b..9042ce5f5e 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -174,6 +174,7 @@ public:
private:
Q_DISABLE_COPY(QMutex)
+ template<typename Mutex>
friend class QMutexLocker;
friend class QRecursiveMutex;
friend class ::tst_QMutex;
@@ -207,6 +208,7 @@ private:
class QRecursiveMutex : private QMutex
{
// ### Qt 6: make it independent of QMutex
+ template<typename Mutex>
friend class QMutexLocker;
public:
Q_CORE_EXPORT QRecursiveMutex();
@@ -222,65 +224,49 @@ public:
#endif
};
-class Q_CORE_EXPORT QMutexLocker
+template <typename Mutex>
+class QMutexLocker
{
public:
-#ifndef Q_CLANG_QDOC
- inline explicit QMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT
+ inline explicit QMutexLocker(Mutex *mutex) QT_MUTEX_LOCK_NOEXCEPT
{
- Q_ASSERT_X((reinterpret_cast<quintptr>(m) & quintptr(1u)) == quintptr(0),
- "QMutexLocker", "QMutex pointer is misaligned");
- val = quintptr(m);
- if (Q_LIKELY(m)) {
- // call QMutex::lock() instead of QBasicMutex::lock()
- static_cast<QMutex *>(m)->lock();
- val |= 1;
+ m = mutex;
+ if (Q_LIKELY(mutex)) {
+ mutex->lock();
+ isLocked = true;
}
}
- explicit QMutexLocker(QRecursiveMutex *m) QT_MUTEX_LOCK_NOEXCEPT
- : QMutexLocker{static_cast<QBasicMutex*>(m)} {}
-#else
- QMutexLocker(QMutex *) { }
- QMutexLocker(QRecursiveMutex *) {}
-#endif
- inline ~QMutexLocker() { unlock(); }
+ inline ~QMutexLocker() {
+ unlock();
+ }
inline void unlock() noexcept
{
- if ((val & quintptr(1u)) == quintptr(1u)) {
- val &= ~quintptr(1u);
- mutex()->unlock();
- }
+ if (!isLocked)
+ return;
+ m->unlock();
+ isLocked = false;
}
inline void relock() QT_MUTEX_LOCK_NOEXCEPT
{
- if (val) {
- if ((val & quintptr(1u)) == quintptr(0u)) {
- mutex()->lock();
- val |= quintptr(1u);
- }
+ if (isLocked)
+ return;
+ if (m) {
+ m->lock();
+ isLocked = true;
}
}
-#if defined(Q_CC_MSVC)
-#pragma warning( push )
-#pragma warning( disable : 4312 ) // ignoring the warning from /Wp64
-#endif
-
- inline QMutex *mutex() const
+ Mutex *mutex() const
{
- return reinterpret_cast<QMutex *>(val & ~quintptr(1u));
+ return m;
}
-
-#if defined(Q_CC_MSVC)
-#pragma warning( pop )
-#endif
-
private:
Q_DISABLE_COPY(QMutexLocker)
- quintptr val;
+ Mutex *m;
+ bool isLocked = false;
};
#else // !QT_CONFIG(thread) && !Q_CLANG_QDOC
@@ -320,15 +306,16 @@ private:
class QRecursiveMutex : public QMutex {};
-class Q_CORE_EXPORT QMutexLocker
+template<typename Mutex>
+class QMutexLocker
{
public:
- inline explicit QMutexLocker(QMutex *) noexcept {}
+ inline explicit QMutexLocker(Mutex *) noexcept {}
inline ~QMutexLocker() noexcept {}
inline void unlock() noexcept {}
void relock() noexcept {}
- inline QMutex *mutex() const noexcept { return nullptr; }
+ inline Mutex *mutex() const noexcept { return nullptr; }
private:
Q_DISABLE_COPY(QMutexLocker)
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index 83edfd5879..abd9b56c94 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -162,7 +162,7 @@ public:
static bool relock(QBasicMutex *, QBasicMutex *) { return false; }
};
-using QBasicMutexLocker = QMutexLocker;
+using QBasicMutexLocker = QMutexLocker<QBasicMutex>;
#endif
diff --git a/src/network/ssl/qsslsocket_mac.cpp b/src/network/ssl/qsslsocket_mac.cpp
index 4096fb68c6..9eb9609315 100644
--- a/src/network/ssl/qsslsocket_mac.cpp
+++ b/src/network/ssl/qsslsocket_mac.cpp
@@ -314,7 +314,7 @@ OSStatus QSslSocketBackendPrivate::WriteCallback(QSslSocketBackendPrivate *socke
void QSslSocketPrivate::ensureInitialized()
{
- const QMutexLocker locker(qt_securetransport_mutex);
+ const QMutexLocker locker(qt_securetransport_mutex());
if (s_loadedCiphersAndCerts)
return;
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index c5f82502fc..39d011d684 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -2233,7 +2233,7 @@ bool QSslSocketPrivate::ensureLibraryLoaded()
if (!q_resolveOpenSslSymbols())
return false;
- const QMutexLocker locker(qt_opensslInitMutex);
+ const QMutexLocker locker(qt_opensslInitMutex());
if (!s_libraryLoaded) {
// Initialize OpenSSL.
@@ -2265,7 +2265,7 @@ bool QSslSocketPrivate::ensureLibraryLoaded()
void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
{
- const QMutexLocker locker(qt_opensslInitMutex);
+ const QMutexLocker locker(qt_opensslInitMutex());
if (s_loadedCiphersAndCerts)
return;