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
Pick-to: 6.6
Change-Id: I0e21bd8745cc75a9c04b71343c398ad953283857
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
bb10
parent
97adda8675
commit
c70257e9b2
|
|
@ -314,52 +314,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…
Reference in New Issue