QEventLoopLockerPrivate: store the tag in the pointer variable
There's enough space in the LSB of the three pointers to encode the type. Saves sizeof(void*) in the Private class, but, more importantly, paves the way for the next patch to get rid of the Private class and its memory allocation altogether, turning QEventLoopLocker::d_ptr into what this patch still calls QEventLoopLockerPrivate::p. Neither QTaggedPointer nor QML's QBiPointer apply here. QTaggedPointer only supports a single T, plus flags; QBiPointer supports only two Ts, and one flag; we need three Ts and no flags. This could be a QVariantPointer<QEventLoopPrivate, QCoreApplicationPriivate*, QThreadPrivate*> I'm thinking about it; just would want to find a second use-case for it. Task-number: QTBUG-114793 Change-Id: I0e21bd8745cc75a9c04b71343c398ad953283857 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit c70257e9b22226f52caade22b085fb6508fb1ec1) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
8b1f858f65
commit
3d70617c71
@ -298,52 +298,59 @@ class QEventLoopLockerPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop)
|
explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop)
|
||||||
: loop(loop), type(EventLoop)
|
: QEventLoopLockerPrivate(loop, EventLoop)
|
||||||
{
|
{
|
||||||
loop->ref();
|
loop->ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit QEventLoopLockerPrivate(QThreadPrivate *thread)
|
explicit QEventLoopLockerPrivate(QThreadPrivate *thread)
|
||||||
: thread(thread), type(Thread)
|
: QEventLoopLockerPrivate(thread, Thread)
|
||||||
{
|
{
|
||||||
thread->ref();
|
thread->ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app)
|
explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app)
|
||||||
: app(app), type(Application)
|
: QEventLoopLockerPrivate(app, Application)
|
||||||
{
|
{
|
||||||
app->ref();
|
app->ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
~QEventLoopLockerPrivate()
|
~QEventLoopLockerPrivate()
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type())
|
||||||
{
|
{
|
||||||
case EventLoop:
|
case EventLoop:
|
||||||
loop->deref();
|
loop()->deref();
|
||||||
break;
|
break;
|
||||||
case Thread:
|
case Thread:
|
||||||
thread->deref();
|
thread()->deref();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
app->deref();
|
app()->deref();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union {
|
QEventLoopPrivate *loop() const { return static_cast<QEventLoopPrivate *>(pointer()); }
|
||||||
QEventLoopPrivate * loop;
|
QThreadPrivate *thread() const { return static_cast<QThreadPrivate *>(pointer()); }
|
||||||
QThreadPrivate * thread;
|
QCoreApplicationPrivate *app() const { return static_cast<QCoreApplicationPrivate *>(pointer()); }
|
||||||
QCoreApplicationPrivate * app;
|
|
||||||
};
|
|
||||||
enum Type {
|
enum Type {
|
||||||
EventLoop,
|
EventLoop,
|
||||||
Thread,
|
Thread,
|
||||||
Application
|
Application
|
||||||
};
|
};
|
||||||
const Type type;
|
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); }
|
||||||
};
|
};
|
||||||
|
// 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);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QEventLoopLocker
|
\class QEventLoopLocker
|
||||||
|
Loading…
x
Reference in New Issue
Block a user