From acaf9b0d2c2c46164fe86b42266bdf7e90870bf6 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 Change-Id: Ia5c67c0ffdcddfdecb38fe3e095d60f6761f1160 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot (cherry picked from commit d18a9dd977a59bf735ed3b6a19e101d4b26a1cef) Reviewed-by: Marc Mutz --- 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 4f1077b7125..edde9492f88 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -296,35 +296,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; @@ -332,11 +308,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 @@ -365,7 +349,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} { } @@ -378,7 +363,7 @@ QEventLoopLocker::QEventLoopLocker() \sa QEventLoop::quit() */ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) - : d_ptr(new QEventLoopLockerPrivate(static_cast(QObjectPrivate::get(loop)))) + : QEventLoopLocker{o2p(loop), Type::EventLoop} { } @@ -391,7 +376,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} { } @@ -405,6 +390,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 33ab9415e3e..c2b03a94278 100644 --- a/src/corelib/kernel/qeventloop.h +++ b/src/corelib/kernel/qeventloop.h @@ -61,11 +61,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;