QEventLoopLocker: rewrite to hold public classes

... instead of Private ones, at the cost of having to befriend of all
the lockable classes, because we need access to their d_func()'s.

This simplifies the code, because we don't need the manual QClass to
QClassPrivate mapping (o2p) anymore, we can just use d_func(). This also
paves the way to make QEventLoopLocker almost completely inline and use
a 3-pointer form of QBiPointer, once available, to hide the bit
fiddling. We couldn't make such a change if the class continued to hold
pointers to QClassPrivate's.

Task-number: QTBUG-114793
Change-Id: Id300e4d45d6cacabe090a46cd6433c5ead3c8b0c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 416e07e0575922323b76e4e7768409b203292837)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2023-07-04 22:28:50 +02:00 committed by Qt Cherry-pick Bot
parent ad010d77d9
commit 75d5ad3ac9
4 changed files with 17 additions and 21 deletions

View File

@ -32,6 +32,7 @@ class QTranslator;
class QPostEventList; class QPostEventList;
class QAbstractEventDispatcher; class QAbstractEventDispatcher;
class QAbstractNativeEventFilter; class QAbstractNativeEventFilter;
class QEventLoopLocker;
#if QT_CONFIG(permissions) || defined(Q_QDOC) #if QT_CONFIG(permissions) || defined(Q_QDOC)
class QPermission; class QPermission;
@ -58,6 +59,7 @@ class Q_CORE_EXPORT QCoreApplication
#endif #endif
Q_DECLARE_PRIVATE(QCoreApplication) Q_DECLARE_PRIVATE(QCoreApplication)
friend class QEventLoopLocker;
public: public:
enum { ApplicationFlags = QT_VERSION enum { ApplicationFlags = QT_VERSION
}; };

View File

@ -293,19 +293,10 @@ bool QEventLoop::event(QEvent *event)
void QEventLoop::quit() void QEventLoop::quit()
{ exit(0); } { exit(0); }
namespace {
// If any of these trigger, the Type bits will interfere with the pointer values: // If any of these trigger, the Type bits will interfere with the pointer values:
static_assert(alignof(QEventLoopPrivate) >= 4); static_assert(alignof(QEventLoop) >= 4);
static_assert(alignof(QThreadPrivate) >= 4); static_assert(alignof(QThread) >= 4);
static_assert(alignof(QCoreApplicationPrivate) >= 4); static_assert(alignof(QCoreApplication) >= 4);
template <typename Private>
Private *o2p(QObject *o)
{
return static_cast<Private*>(QObjectPrivate::get(o));
}
} // unnamed namespace
/*! /*!
\class QEventLoopLocker \class QEventLoopLocker
@ -335,8 +326,7 @@ Private *o2p(QObject *o)
\sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled() \sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled()
*/ */
QEventLoopLocker::QEventLoopLocker() noexcept QEventLoopLocker::QEventLoopLocker() noexcept
: QEventLoopLocker{o2p<QCoreApplicationPrivate>(QCoreApplication::instance()), : QEventLoopLocker{QCoreApplication::instance(), Type::Application}
Type::Application}
{ {
} }
@ -349,7 +339,7 @@ QEventLoopLocker::QEventLoopLocker() noexcept
\sa QEventLoop::quit() \sa QEventLoop::quit()
*/ */
QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) noexcept QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) noexcept
: QEventLoopLocker{o2p<QEventLoopPrivate>(loop), Type::EventLoop} : QEventLoopLocker{loop, Type::EventLoop}
{ {
} }
@ -362,7 +352,7 @@ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) noexcept
\sa QThread::quit() \sa QThread::quit()
*/ */
QEventLoopLocker::QEventLoopLocker(QThread *thread) noexcept QEventLoopLocker::QEventLoopLocker(QThread *thread) noexcept
: QEventLoopLocker{o2p<QThreadPrivate>(thread), Type::Thread} : QEventLoopLocker{thread, Type::Thread}
{ {
} }
@ -372,7 +362,7 @@ QEventLoopLocker::QEventLoopLocker(QThread *thread) noexcept
*/ */
QEventLoopLocker::~QEventLoopLocker() QEventLoopLocker::~QEventLoopLocker()
{ {
visit([](auto p) { p->deref(); }); visit([](auto p) { p->d_func()->deref(); });
} }
/*! /*!
@ -381,7 +371,7 @@ QEventLoopLocker::~QEventLoopLocker()
QEventLoopLocker::QEventLoopLocker(void *ptr, Type t) noexcept QEventLoopLocker::QEventLoopLocker(void *ptr, Type t) noexcept
: p{quintptr(ptr) | quintptr(t)} : p{quintptr(ptr) | quintptr(t)}
{ {
visit([](auto p) { p->ref(); }); visit([](auto p) { p->d_func()->ref(); });
} }
/*! /*!
@ -394,9 +384,9 @@ void QEventLoopLocker::visit(Func f) const
if (!ptr) if (!ptr)
return; return;
switch (type()) { switch (type()) {
case Type::EventLoop: return f(static_cast<QEventLoopPrivate *>(ptr)); case Type::EventLoop: return f(static_cast<QEventLoop *>(ptr));
case Type::Thread: return f(static_cast<QThreadPrivate *>(ptr)); case Type::Thread: return f(static_cast<QThread *>(ptr));
case Type::Application: return f(static_cast<QCoreApplicationPrivate *>(ptr)); case Type::Application: return f(static_cast<QCoreApplication *>(ptr));
} }
Q_UNREACHABLE(); Q_UNREACHABLE();
} }

View File

@ -8,12 +8,14 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QEventLoopLocker;
class QEventLoopPrivate; class QEventLoopPrivate;
class Q_CORE_EXPORT QEventLoop : public QObject class Q_CORE_EXPORT QEventLoop : public QObject
{ {
Q_OBJECT Q_OBJECT
Q_DECLARE_PRIVATE(QEventLoop) Q_DECLARE_PRIVATE(QEventLoop)
friend class QEventLoopLocker;
public: public:
explicit QEventLoop(QObject *parent = nullptr); explicit QEventLoop(QObject *parent = nullptr);

View File

@ -24,6 +24,7 @@ QT_BEGIN_NAMESPACE
class QThreadData; class QThreadData;
class QThreadPrivate; class QThreadPrivate;
class QAbstractEventDispatcher; class QAbstractEventDispatcher;
class QEventLoopLocker;
class Q_CORE_EXPORT QThread : public QObject class Q_CORE_EXPORT QThread : public QObject
{ {
@ -109,6 +110,7 @@ protected:
private: private:
Q_DECLARE_PRIVATE(QThread) Q_DECLARE_PRIVATE(QThread)
friend class QEventLoopLocker;
#if QT_CONFIG(cxx11_future) #if QT_CONFIG(cxx11_future)
[[nodiscard]] static QThread *createThreadImpl(std::future<void> &&future); [[nodiscard]] static QThread *createThreadImpl(std::future<void> &&future);