QEventLoopLocker: inline Private into public class

The Private class consists of just one quintptr member now, so it fits
into the ex-d_ptr member of the public class.

Since no allocations take place anymore, and we widened the contract
to allow for nullptr arguments, mark the constructors as noexcept.

[ChangeLog][QtCore][QEventLoopLocker] No longer allocates; all
operations are noexcept now.

Fixes: QTBUG-114793
Pick-to: 6.6
Change-Id: I89699e331711f517d0502392dba106a47ccc9a0f
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Marc Mutz 2023-07-03 07:54:18 +02:00
parent 5560723e9d
commit d8a8a3a5dc
2 changed files with 13 additions and 26 deletions

View File

@ -310,20 +310,6 @@ void QEventLoop::quit()
{ exit(0); }
class QEventLoopLockerPrivate
{
public:
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()); }
explicit QEventLoopLockerPrivate(void *ptr, Type t) noexcept
: p{quintptr(ptr) | quintptr(t)} {}
quintptr p;
static constexpr quintptr TypeMask = 0x3;
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);
@ -364,7 +350,7 @@ Private *o2p(QObject *o)
\sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled()
*/
QEventLoopLocker::QEventLoopLocker()
QEventLoopLocker::QEventLoopLocker() noexcept
: QEventLoopLocker{o2p<QCoreApplicationPrivate>(QCoreApplication::instance()),
Type::Application}
{
@ -378,7 +364,7 @@ QEventLoopLocker::QEventLoopLocker()
\sa QEventLoop::quit()
*/
QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
QEventLoopLocker::QEventLoopLocker(QEventLoop *loop) noexcept
: QEventLoopLocker{o2p<QEventLoopPrivate>(loop), Type::EventLoop}
{
@ -391,7 +377,7 @@ QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
\sa QThread::quit()
*/
QEventLoopLocker::QEventLoopLocker(QThread *thread)
QEventLoopLocker::QEventLoopLocker(QThread *thread) noexcept
: QEventLoopLocker{o2p<QThreadPrivate>(thread), Type::Thread}
{
@ -403,14 +389,13 @@ QEventLoopLocker::QEventLoopLocker(QThread *thread)
QEventLoopLocker::~QEventLoopLocker()
{
visit([](auto p) { p->deref(); });
delete d_ptr;
}
/*!
\internal
*/
QEventLoopLocker::QEventLoopLocker(void *ptr, Type t) noexcept
: d_ptr(new QEventLoopLockerPrivate{ptr, t})
: p{quintptr(ptr) | quintptr(t)}
{
visit([](auto p) { p->ref(); });
}
@ -421,11 +406,10 @@ QEventLoopLocker::QEventLoopLocker(void *ptr, Type t) noexcept
template <typename Func>
void QEventLoopLocker::visit(Func f) const
{
using Type = QEventLoopLockerPrivate::Type;
const auto ptr = d_ptr->pointer();
const auto ptr = pointer();
if (!ptr)
return;
switch (d_ptr->type()) {
switch (type()) {
case Type::EventLoop: return f(static_cast<QEventLoopPrivate *>(ptr));
case Type::Thread: return f(static_cast<QThreadPrivate *>(ptr));
case Type::Application: return f(static_cast<QCoreApplicationPrivate *>(ptr));

View File

@ -56,9 +56,9 @@ class QEventLoopLockerPrivate;
class QEventLoopLocker
{
public:
Q_NODISCARD_CTOR Q_CORE_EXPORT QEventLoopLocker();
Q_NODISCARD_CTOR Q_CORE_EXPORT explicit QEventLoopLocker(QEventLoop *loop);
Q_NODISCARD_CTOR Q_CORE_EXPORT explicit QEventLoopLocker(QThread *thread);
Q_NODISCARD_CTOR Q_CORE_EXPORT QEventLoopLocker() noexcept;
Q_NODISCARD_CTOR Q_CORE_EXPORT explicit QEventLoopLocker(QEventLoop *loop) noexcept;
Q_NODISCARD_CTOR Q_CORE_EXPORT explicit QEventLoopLocker(QThread *thread) noexcept;
Q_CORE_EXPORT ~QEventLoopLocker();
private:
@ -75,7 +75,10 @@ private:
Application,
};
explicit QEventLoopLocker(void *ptr, Type t) noexcept;
QEventLoopLockerPrivate *d_ptr;
quintptr p;
static constexpr quintptr TypeMask = 0x3;
Type type() const { return Type(p & TypeMask); }
void *pointer() const { return reinterpret_cast<void *>(p & ~TypeMask); }
template <typename Func>
void visit(Func func) const;
};