From e2b84761513c464b8c0c65a16ec758db2eb522ca Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 16 Jul 2023 10:04:09 +0200 Subject: [PATCH] QSlotObjectBase: add Deleter and typedef for a unique_ptr using it Use it in QMetaCallEvent, to have some automatic test coverage. Other code that might benefit has undergone changes since 5.15, so will be ported one-by-one to avoid conflicts on cherry-picks. Change-Id: I566bab1803e3675f75a9fdf294a4b0f047d21c11 Reviewed-by: Volker Hilsheimer (cherry picked from commit c58074b42dcd48a293fe493795d51ca2b101a280) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/kernel/qobject.cpp | 6 ++---- src/corelib/kernel/qobject_p.h | 2 +- src/corelib/kernel/qobjectdefs_impl.h | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 5a32c6f2147..9269e3b6cd9 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -551,7 +551,7 @@ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId, void **args, QSemaphore *semaphore) : QAbstractMetaCallEvent(sender, signalId, semaphore), - d({slotO, args, nullptr, 0, 0, ushort(-1)}), + d({QtPrivate::SlotObjUniquePtr{slotO}, args, nullptr, 0, 0, ushort(-1)}), prealloc_() { if (d.slotObj_) @@ -585,7 +585,7 @@ QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId, int nargs) : QAbstractMetaCallEvent(sender, signalId), - d({slotO, nullptr, nullptr, nargs, 0, ushort(-1)}), + d({QtPrivate::SlotObjUniquePtr(slotO), nullptr, nullptr, nargs, 0, ushort(-1)}), prealloc_() { if (d.slotObj_) @@ -607,8 +607,6 @@ QMetaCallEvent::~QMetaCallEvent() if (reinterpret_cast(d.args_) != reinterpret_cast(prealloc_)) free(d.args_); } - if (d.slotObj_) - d.slotObj_->destroyIfLastRef(); } /*! diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 5fcf138b443..937ac59f8eb 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -420,7 +420,7 @@ private: inline void allocArgs(); struct Data { - QtPrivate::QSlotObjectBase *slotObj_; + QtPrivate::SlotObjUniquePtr slotObj_; void **args_; QObjectPrivate::StaticMetaCallFunction callFunction_; int nargs_; diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 6f2dac783be..a9503595b2a 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -14,6 +14,8 @@ #include +#include + QT_BEGIN_NAMESPACE class QObject; class QObjectPrivate; @@ -413,6 +415,15 @@ namespace QtPrivate { public: explicit QSlotObjectBase(ImplFn fn) : m_impl(fn) {} + // A custom deleter compatible with std protocols (op()()) we well as + // the legacy QScopedPointer protocol (cleanup()). + struct Deleter { + void operator()(QSlotObjectBase *p) const noexcept + { if (p) p->destroyIfLastRef(); } + // for the non-standard QScopedPointer protocol: + static void cleanup(QSlotObjectBase *p) noexcept { Deleter{}(p); } + }; + inline int ref() noexcept { return m_ref.ref(); } #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) inline void destroyIfLastRef() noexcept @@ -439,6 +450,9 @@ namespace QtPrivate { Q_DISABLE_COPY_MOVE(QSlotObjectBase) }; + using SlotObjUniquePtr = std::unique_ptr; + // Implementation of QSlotObjectBase for which the slot is a callable (function, PMF, functor, or lambda). // Args and R are the List of arguments and the return type of the signal to which the slot is connected. template