From d18a9dd977a59bf735ed3b6a19e101d4b26a1cef Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 3 Jul 2023 07:43:28 +0200 Subject: [PATCH] QEventLoopLocker: use visit() to DRY ctors Collapse all three Private ctors into one (void*, Type) one. Task-number: QTBUG-114793 Pick-to: 6.6 Change-Id: Ia5c67c0ffdcddfdecb38fe3e095d60f6761f1160 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot --- src/corelib/kernel/qeventloop.cpp | 50 ++++++++++++++----------------- src/corelib/kernel/qeventloop.h | 7 +++++ 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index f3ddc84758..768175257f 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -312,35 +312,11 @@ void QEventLoop::quit() class QEventLoopLockerPrivate { - friend class QEventLoopLocker; public: - explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop) - : QEventLoopLockerPrivate(loop, EventLoop) - { - loop->ref(); - } - - explicit QEventLoopLockerPrivate(QThreadPrivate *thread) - : QEventLoopLockerPrivate(thread, Thread) - { - thread->ref(); - } - - explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app) - : QEventLoopLockerPrivate(app, Application) - { - app->ref(); - } - -private: + using Type = QEventLoopLocker::Type; QEventLoopPrivate *loop() const { return static_cast(pointer()); } QThreadPrivate *thread() const { return static_cast(pointer()); } QCoreApplicationPrivate *app() const { return static_cast(pointer()); } - enum Type { - EventLoop, - Thread, - Application - }; explicit QEventLoopLockerPrivate(void *ptr, Type t) noexcept : p{quintptr(ptr) | quintptr(t)} {} quintptr p; @@ -348,11 +324,19 @@ private: Type type() const { return Type(p & TypeMask); } void *pointer() const { return reinterpret_cast(p & ~TypeMask); } }; +namespace { // If any of these trigger, the Type bits will interfere with the pointer values: static_assert(alignof(QEventLoopPrivate) >= 4); static_assert(alignof(QThreadPrivate) >= 4); static_assert(alignof(QCoreApplicationPrivate) >= 4); +template +Private *o2p(QObject *o) +{ + return static_cast(QObjectPrivate::get(o)); +} +} // unnamed namespace + /*! \class QEventLoopLocker \inmodule QtCore @@ -381,7 +365,8 @@ static_assert(alignof(QCoreApplicationPrivate) >= 4); \sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled() */ QEventLoopLocker::QEventLoopLocker() - : d_ptr(new QEventLoopLockerPrivate(static_cast(QObjectPrivate::get(QCoreApplication::instance())))) + : QEventLoopLocker{o2p(QCoreApplication::instance()), + Type::Application} { } @@ -394,7 +379,7 @@ QEventLoopLocker::QEventLoopLocker() \sa QEventLoop::quit() */ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) - : d_ptr(new QEventLoopLockerPrivate(static_cast(QObjectPrivate::get(loop)))) + : QEventLoopLocker{o2p(loop), Type::EventLoop} { } @@ -407,7 +392,7 @@ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) \sa QThread::quit() */ QEventLoopLocker::QEventLoopLocker(QThread *thread) - : d_ptr(new QEventLoopLockerPrivate(static_cast(QObjectPrivate::get(thread)))) + : QEventLoopLocker{o2p(thread), Type::Thread} { } @@ -421,6 +406,15 @@ QEventLoopLocker::~QEventLoopLocker() delete d_ptr; } +/*! + \internal +*/ +QEventLoopLocker::QEventLoopLocker(void *ptr, Type t) noexcept + : d_ptr(new QEventLoopLockerPrivate{ptr, t}) +{ + visit([](auto p) { p->ref(); }); +} + /*! \internal */ diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h index 265ec76047..becabe2b14 100644 --- a/src/corelib/kernel/qeventloop.h +++ b/src/corelib/kernel/qeventloop.h @@ -63,11 +63,18 @@ public: private: Q_DISABLE_COPY(QEventLoopLocker) + friend class QEventLoopLockerPrivate; // // Private implementation details. // Do not call from public inline API! // + enum class Type : quintptr { + EventLoop, + Thread, + Application, + }; + explicit QEventLoopLocker(void *ptr, Type t) noexcept; QEventLoopLockerPrivate *d_ptr; template void visit(Func func) const;