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 <thiago.macieira@intel.com>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
(cherry picked from commit d18a9dd977a59bf735ed3b6a19e101d4b26a1cef)
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Marc Mutz 2023-07-03 07:43:28 +02:00
parent 74571f3455
commit acaf9b0d2c
2 changed files with 29 additions and 28 deletions

View File

@ -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<QEventLoopPrivate *>(pointer()); }
QThreadPrivate *thread() const { return static_cast<QThreadPrivate *>(pointer()); }
QCoreApplicationPrivate *app() const { return static_cast<QCoreApplicationPrivate *>(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<void *>(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 <typename Private>
Private *o2p(QObject *o)
{
return static_cast<Private*>(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<QCoreApplicationPrivate*>(QObjectPrivate::get(QCoreApplication::instance()))))
: QEventLoopLocker{o2p<QCoreApplicationPrivate>(QCoreApplication::instance()),
Type::Application}
{
}
@ -378,7 +363,7 @@ QEventLoopLocker::QEventLoopLocker()
\sa QEventLoop::quit()
*/
QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
: d_ptr(new QEventLoopLockerPrivate(static_cast<QEventLoopPrivate*>(QObjectPrivate::get(loop))))
: QEventLoopLocker{o2p<QEventLoopPrivate>(loop), Type::EventLoop}
{
}
@ -391,7 +376,7 @@ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
\sa QThread::quit()
*/
QEventLoopLocker::QEventLoopLocker(QThread *thread)
: d_ptr(new QEventLoopLockerPrivate(static_cast<QThreadPrivate*>(QObjectPrivate::get(thread))))
: QEventLoopLocker{o2p<QThreadPrivate>(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
*/

View File

@ -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 <typename Func>
void visit(Func func) const;