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:
|
||||
explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop)
|
||||
: loop(loop), type(EventLoop)
|
||||
: QEventLoopLockerPrivate(loop, EventLoop)
|
||||
{
|
||||
loop->ref();
|
||||
}
|
||||
|
||||
explicit QEventLoopLockerPrivate(QThreadPrivate *thread)
|
||||
: thread(thread), type(Thread)
|
||||
: QEventLoopLockerPrivate(thread, Thread)
|
||||
{
|
||||
thread->ref();
|
||||
}
|
||||
|
||||
explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app)
|
||||
: app(app), type(Application)
|
||||
: QEventLoopLockerPrivate(app, Application)
|
||||
{
|
||||
app->ref();
|
||||
}
|
||||
|
||||
~QEventLoopLockerPrivate()
|
||||
{
|
||||
switch (type)
|
||||
switch (type())
|
||||
{
|
||||
case EventLoop:
|
||||
loop->deref();
|
||||
loop()->deref();
|
||||
break;
|
||||
case Thread:
|
||||
thread->deref();
|
||||
thread()->deref();
|
||||
break;
|
||||
default:
|
||||
app->deref();
|
||||
app()->deref();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
QEventLoopPrivate * loop;
|
||||
QThreadPrivate * thread;
|
||||
QCoreApplicationPrivate * app;
|
||||
};
|
||||
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
|
||||
};
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user