aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/pysidesignal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/libpyside/pysidesignal.cpp')
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
index 5df42261c..cdc3042c0 100644
--- a/sources/pyside6/libpyside/pysidesignal.cpp
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -6,6 +6,7 @@
#include "pysidesignal_p.h"
#include "pysideutils.h"
#include "pysidestaticstrings.h"
+#include "pysideweakref.h"
#include "signalmanager.h"
#include <shiboken.h>
@@ -342,6 +343,7 @@ static void signalInstanceFree(void *vself)
}
delete dataPvt;
self->d = nullptr;
+ self->deleted = true;
Py_TYPE(pySelf)->tp_base->tp_free(self);
}
@@ -550,6 +552,13 @@ static PyObject *signalInstanceEmit(PyObject *self, PyObject *args)
{
PySideSignalInstance *source = reinterpret_cast<PySideSignalInstance *>(self);
+ // PYSIDE-2201: Check if the object has vanished meanwhile.
+ // Tried to revive it without exception, but this gives problems.
+ if (source->deleted) {
+ PyErr_Format(PyExc_RuntimeError, "The SignalInstance object was already deleted");
+ return nullptr;
+ }
+
Shiboken::AutoDecRef pyArgs(PyList_New(0));
int numArgsGiven = PySequence_Fast_GET_SIZE(args);
int numArgsInSignature = argCountInSignature(source->d->signature);
@@ -932,9 +941,16 @@ static void appendSignature(PySideSignal *self, const SignalSignature &signature
self->data->signatures.append({signature.m_parameterTypes, signature.m_attributes});
}
+static void sourceGone(void *data)
+{
+ auto *self = reinterpret_cast<PySideSignalInstance *>(data);
+ self->deleted = true;
+}
+
static void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySideSignal *signal, PyObject *source, int index)
{
self->d = new PySideSignalInstancePrivate;
+ self->deleted = false;
PySideSignalInstancePrivate *selfPvt = self->d;
selfPvt->next = nullptr;
if (signal->data->signalName.isEmpty())
@@ -950,6 +966,10 @@ static void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySid
selfPvt->homonymousMethod = signal->homonymousMethod;
Py_INCREF(selfPvt->homonymousMethod);
}
+ // PYSIDE-2201: We have no reference to source. Let's take a weakref to get
+ // notified when source gets deleted.
+ PySide::WeakRef::create(source, sourceGone, self);
+
index++;
if (index < signal->data->signatures.size()) {
@@ -1009,6 +1029,7 @@ PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMet
previous->d->next = item;
item->d = new PySideSignalInstancePrivate;
+ item->deleted = false;
PySideSignalInstancePrivate *selfPvt = item->d;
selfPvt->source = source;
Py_INCREF(selfPvt->source); // PYSIDE-79: an INCREF is missing.