Port QObjectPrivate::connectImpl() to SlotObjUniquePtr internally

... removing the custom scope-guard which was .dismiss()ed too early
(the allocation of 'c' could theoretically fail, and the old code
would leak the slot object in that case; nothing we're generally
guarding against in Qt, but it's a nice drive-by gain, probably shuts
up static checkers, and makes readers wonder less about the lifetime
of the slot object).

As mentioned in the patch porting QObject::connectImpl(), leave the
unique_ptr out of the function's signature, see there for rationale
(key-word: tail-callability).

Pick-to: 6.6 6.5
Change-Id: Ib90371b9768a72fd62d080b71eef2c82f851db81
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2023-07-19 21:24:14 +02:00
parent 9338207018
commit 18857db2dd

View File

@ -5135,14 +5135,10 @@ static void connectWarning(const QObject *sender,
*/
QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int signal_index,
const QObject *receiver, void **slot,
QtPrivate::QSlotObjectBase *slotObj, int type,
QtPrivate::QSlotObjectBase *slotObjRaw, int type,
const int *types, const QMetaObject *senderMetaObject)
{
auto connectFailureGuard = qScopeGuard([&]()
{
if (slotObj)
slotObj->destroyIfLastRef();
});
QtPrivate::SlotObjUniquePtr slotObj(slotObjRaw);
if (!sender || !receiver || !slotObj || !senderMetaObject) {
connectWarning(sender, senderMetaObject, receiver, "invalid nullptr parameter");
@ -5154,8 +5150,6 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
return QMetaObject::Connection();
}
connectFailureGuard.dismiss();
QObject *s = const_cast<QObject *>(sender);
QObject *r = const_cast<QObject *>(receiver);
@ -5168,10 +5162,8 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
const QObjectPrivate::Connection *c2 = connections->signalVector.loadRelaxed()->at(signal_index).first.loadRelaxed();
while (c2) {
if (c2->receiver.loadRelaxed() == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
slotObj->destroyIfLastRef();
if (c2->receiver.loadRelaxed() == receiver && c2->isSlotObject && c2->slotObj->compare(slot))
return QMetaObject::Connection();
}
c2 = c2->nextConnectionList.loadRelaxed();
}
}
@ -5191,9 +5183,9 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
td->ref();
c->receiverThreadData.storeRelaxed(td);
c->receiver.storeRelaxed(r);
c->slotObj = slotObj;
c->connectionType = type;
c->isSlotObject = true;
c->slotObj = slotObj.release();
if (types) {
c->argumentTypes.storeRelaxed(types);
c->ownArgumentTypes = false;