From 4395e1e06bf2586d42a338466c98c6a5b95b2c91 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 19 Jul 2023 10:40:43 +0200 Subject: [PATCH] QMetaCallEvent: add ctors and create() overloads taking SlotObjUniquePtr This makes it clear who is responsible for obtaining additional strong reference to the slot objects, because these functions no longer do. Change-Id: I39187e3c441d8f82d50d907731f1cbdfb2a95b9d Reviewed-by: Thiago Macieira (cherry picked from commit 00dbd3cd26d2cf4dbcde3a8f517d0d6b6d0bc9ca) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qobject.cpp | 35 ++++++++++++++++++++++++++++++++-- src/corelib/kernel/qobject_p.h | 24 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 2c481bdfaeb..b85da48c49d 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -558,6 +558,21 @@ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, d.slotObj_->ref(); } +/*! + \internal + + Used for blocking queued connections, just passes \a args through without + allocating any memory. + */ +QMetaCallEvent::QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotO, + const QObject *sender, int signalId, + void **args, QSemaphore *semaphore) + : QAbstractMetaCallEvent(sender, signalId, semaphore), + d{std::move(slotO), args, nullptr, 0, 0, ushort(-1)}, + prealloc_() +{ +} + /*! \internal @@ -593,6 +608,22 @@ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, allocArgs(); } +/*! + \internal + + Allocates memory for \a nargs; code creating an event needs to initialize + the void* and int arrays by accessing \a args() and \a types(), respectively. + */ +QMetaCallEvent::QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotO, + const QObject *sender, int signalId, + int nargs) + : QAbstractMetaCallEvent(sender, signalId), + d{std::move(slotO), nullptr, nullptr, nargs, 0, ushort(-1)}, + prealloc_() +{ + allocArgs(); +} + /*! \internal */ @@ -624,12 +655,12 @@ void QMetaCallEvent::placeMetaCall(QObject *object) } } -QMetaCallEvent* QMetaCallEvent::create_impl(QtPrivate::QSlotObjectBase *slotObj, +QMetaCallEvent* QMetaCallEvent::create_impl(QtPrivate::SlotObjUniquePtr slotObj, const QObject *sender, int signal_index, size_t argc, const void* const argp[], const QMetaType metaTypes[]) { - auto metaCallEvent = std::make_unique(slotObj, sender, + auto metaCallEvent = std::make_unique(std::move(slotObj), sender, signal_index, int(argc)); void **args = metaCallEvent->args(); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index ae3744aa715..41f1c2f8202 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -375,6 +375,9 @@ public: QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId, void **args, QSemaphore *semaphore); + QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotObj, + const QObject *sender, int signalId, + void **args, QSemaphore *semaphore); // queued - args allocated by event, copied by caller QMetaCallEvent(ushort method_offset, ushort method_relative, @@ -384,6 +387,9 @@ public: QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId, int nargs); + QMetaCallEvent(QtPrivate::SlotObjUniquePtr slotObj, + const QObject *sender, int signalId, + int nargs); ~QMetaCallEvent() override; @@ -396,6 +402,15 @@ public: constexpr auto argc = sizeof...(Args) + 1; return create_impl(slotObj, sender, signal_index, argc, argp, metaTypes); } + template + static QMetaCallEvent *create(QtPrivate::SlotObjUniquePtr slotObj, const QObject *sender, + int signal_index, const Args &...argv) + { + const void* const argp[] = { nullptr, std::addressof(argv)... }; + const QMetaType metaTypes[] = { QMetaType::fromType(), QMetaType::fromType()... }; + constexpr auto argc = sizeof...(Args) + 1; + return create_impl(std::move(slotObj), sender, signal_index, argc, argp, metaTypes); + } inline int id() const { return d.method_offset_ + d.method_relative_; } inline const void * const* args() const { return d.args_; } @@ -407,6 +422,15 @@ public: private: static QMetaCallEvent *create_impl(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, + int signal_index, size_t argc, const void * const argp[], + const QMetaType metaTypes[]) + { + if (slotObj) + slotObj->ref(); + return create_impl(QtPrivate::SlotObjUniquePtr{slotObj}, sender, + signal_index, argc, argp, metaTypes); + } + static QMetaCallEvent *create_impl(QtPrivate::SlotObjUniquePtr slotObj, const QObject *sender, int signal_index, size_t argc, const void * const argp[], const QMetaType metaTypes[]); inline void allocArgs();