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.

Pick-to: 6.6 6.5
Change-Id: I566bab1803e3675f75a9fdf294a4b0f047d21c11
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Marc Mutz 2023-07-16 10:04:09 +02:00
parent 4601717378
commit c58074b42d
3 changed files with 17 additions and 5 deletions

View File

@ -552,7 +552,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_)
@ -586,7 +586,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_)
@ -608,8 +608,6 @@ QMetaCallEvent::~QMetaCallEvent()
if (reinterpret_cast<void *>(d.args_) != reinterpret_cast<void *>(prealloc_))
free(d.args_);
}
if (d.slotObj_)
d.slotObj_->destroyIfLastRef();
}
/*!

View File

@ -420,7 +420,7 @@ private:
inline void allocArgs();
struct Data {
QtPrivate::QSlotObjectBase *slotObj_;
QtPrivate::SlotObjUniquePtr slotObj_;
void **args_;
QObjectPrivate::StaticMetaCallFunction callFunction_;
int nargs_;

View File

@ -14,6 +14,8 @@
#include <QtCore/qfunctionaltools_impl.h>
#include <memory>
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<QSlotObjectBase,
QSlotObjectBase::Deleter>;
// 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 <typename Func, typename Args, typename R>