aboutsummaryrefslogtreecommitdiffstats
diff options
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-10-09 15:33:59 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2024-10-09 15:26:51 +0000
commitab63b7fe0e5faef42dff542a46d31af7a836dc3e (patch)
tree45db19d9d1946c65b750ab920afc2641a3b0041d
parent29afca66064c41c5a6a8ce8a26647bef9a4df9ad (diff)
Fix disconnecting from C functions (qobject_connect_notify_test flakyness)v6.8.0
Callables wrapping C-function and their objects (as returned by "qobject.deleteLater()") may be temporary objects like methods. For the connection cache key, use self and the actual C-function as so that a disconnect succeeds. This did not show in the old design since the disconnect code did expensive checks to retrieve the slot index of the function and used the index code path. Amends 33bd61d13d8d9e3794b6049891be62f3351313d9. Task-number: PYSIDE-2810 Task-number: PYSIDE-2221 Change-Id: Ic33af0d5da60589df16ca35c17824da592910a4d Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io> (cherry picked from commit c866be38d9c14555c897a85e5b51c5e0f8347964) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--sources/pyside6/libpyside/dynamicslot.cpp13
-rw-r--r--sources/pyside6/libpyside/dynamicslot_p.h3
2 files changed, 12 insertions, 4 deletions
diff --git a/sources/pyside6/libpyside/dynamicslot.cpp b/sources/pyside6/libpyside/dynamicslot.cpp
index b0ae59470..ce8ed191c 100644
--- a/sources/pyside6/libpyside/dynamicslot.cpp
+++ b/sources/pyside6/libpyside/dynamicslot.cpp
@@ -28,6 +28,8 @@ DynamicSlot::SlotType DynamicSlot::slotType(PyObject *callback)
return SlotType::Method;
if (PySide::isCompiledMethod(callback) != 0)
return SlotType::CompiledMethod;
+ if (PyCFunction_Check(callback) != 0)
+ return SlotType::C_Function;
return SlotType::Callable;
}
@@ -200,6 +202,7 @@ DynamicSlot* DynamicSlot::create(PyObject *callback)
Py_DECREF(pythonSelf);
return new PysideReceiverMethodSlot(function, pythonSelf);
}
+ case SlotType::C_Function: // Treat C-function as normal callables
case SlotType::Callable:
break;
}
@@ -239,7 +242,7 @@ struct ConnectionKey
const QObject *sender;
int senderIndex;
const PyObject *object;
- const PyObject *method;
+ const void *method;
friend constexpr size_t qHash(const ConnectionKey &k, size_t seed = 0) noexcept
{
@@ -269,7 +272,7 @@ QDebug operator<<(QDebug debug, const ConnectionKey &k)
debug << ", index=" << k.senderIndex << ", target="
<< PySide::debugPyObject(const_cast<PyObject *>(k.object));
if (k.method != nullptr)
- debug << ", method=" << PySide::debugPyObject(const_cast<PyObject *>(k.method));
+ debug << ", method=" << k.method;
debug << ')';
return debug;
}
@@ -296,7 +299,7 @@ static ConnectionKey connectionKey(const QObject *sender, int senderIndex,
PyObject *callback)
{
PyObject *object{};
- PyObject *method{};
+ void *method{};
switch (DynamicSlot::slotType(callback)) {
case DynamicSlot::SlotType::Method:
@@ -315,6 +318,10 @@ static ConnectionKey connectionKey(const QObject *sender, int senderIndex,
case DynamicSlot::SlotType::Callable:
method = callback;
break;
+ case DynamicSlot::SlotType::C_Function:
+ object = PyCFunction_GetSelf(callback);
+ method = reinterpret_cast<void *>(PyCFunction_GetFunction(callback));
+ break;
}
return {sender, senderIndex, object, method};
diff --git a/sources/pyside6/libpyside/dynamicslot_p.h b/sources/pyside6/libpyside/dynamicslot_p.h
index 77ddcffa3..bad05d7f4 100644
--- a/sources/pyside6/libpyside/dynamicslot_p.h
+++ b/sources/pyside6/libpyside/dynamicslot_p.h
@@ -22,7 +22,8 @@ public:
{
Callable,
Method,
- CompiledMethod
+ CompiledMethod,
+ C_Function
};
virtual ~DynamicSlot() = default;