diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-10-09 15:33:59 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-10-09 15:26:51 +0000 |
commit | ab63b7fe0e5faef42dff542a46d31af7a836dc3e (patch) | |
tree | 45db19d9d1946c65b750ab920afc2641a3b0041d | |
parent | 29afca66064c41c5a6a8ce8a26647bef9a4df9ad (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.cpp | 13 | ||||
-rw-r--r-- | sources/pyside6/libpyside/dynamicslot_p.h | 3 |
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; |