Fix bug 953 - "Segfault when QObject is garbage collected after QTimer.singeShot"
Reviewer: Renato Araújo <renato.filho@openbossa.org>
Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
parent
01b90a3a58
commit
b261ff4642
3 changed files with 28 additions and 4 deletions
|
|
@ -323,11 +323,13 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id,
|
||||||
PyObject* pp_name = 0;
|
PyObject* pp_name = 0;
|
||||||
QMetaProperty mp;
|
QMetaProperty mp;
|
||||||
PyObject* pySelf = 0;
|
PyObject* pySelf = 0;
|
||||||
|
int methodCount = metaObject->methodCount();
|
||||||
|
int propertyCount = metaObject->propertyCount();
|
||||||
|
|
||||||
if (call != QMetaObject::InvokeMetaMethod) {
|
if (call != QMetaObject::InvokeMetaMethod) {
|
||||||
mp = metaObject->property(id);
|
mp = metaObject->property(id);
|
||||||
if (!mp.isValid())
|
if (!mp.isValid())
|
||||||
return id - metaObject->methodCount();
|
return id - methodCount;
|
||||||
|
|
||||||
Shiboken::GilState gil;
|
Shiboken::GilState gil;
|
||||||
pySelf = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(object);
|
pySelf = (PyObject*)Shiboken::BindingManager::instance().retrieveWrapper(object);
|
||||||
|
|
@ -337,7 +339,7 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id,
|
||||||
if (!pp) {
|
if (!pp) {
|
||||||
qWarning("Invalid property: %s.", mp.name());
|
qWarning("Invalid property: %s.", mp.name());
|
||||||
Py_XDECREF(pp_name);
|
Py_XDECREF(pp_name);
|
||||||
return id - metaObject->methodCount();
|
return id - methodCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,10 +364,13 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id,
|
||||||
qWarning("Unsupported meta invocation type.");
|
qWarning("Unsupported meta invocation type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WARNING Isn't safe to call any metaObject and/or object methods beyond this point
|
||||||
|
// because the object can be deleted inside the called slot.
|
||||||
|
|
||||||
if (call == QMetaObject::InvokeMetaMethod)
|
if (call == QMetaObject::InvokeMetaMethod)
|
||||||
id = id - metaObject->methodCount();
|
id = id - methodCount;
|
||||||
else
|
else
|
||||||
id = id - metaObject->propertyCount();
|
id = id - propertyCount;
|
||||||
|
|
||||||
if (pp || pp_name) {
|
if (pp || pp_name) {
|
||||||
Shiboken::GilState gil;
|
Shiboken::GilState gil;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ PYSIDE_TEST(bug_920.py)
|
||||||
PYSIDE_TEST(bug_927.py)
|
PYSIDE_TEST(bug_927.py)
|
||||||
PYSIDE_TEST(bug_931.py)
|
PYSIDE_TEST(bug_931.py)
|
||||||
PYSIDE_TEST(bug_938.py)
|
PYSIDE_TEST(bug_938.py)
|
||||||
|
PYSIDE_TEST(bug_953.py)
|
||||||
PYSIDE_TEST(blocking_signals_test.py)
|
PYSIDE_TEST(blocking_signals_test.py)
|
||||||
PYSIDE_TEST(classinfo_test.py)
|
PYSIDE_TEST(classinfo_test.py)
|
||||||
PYSIDE_TEST(child_event_test.py)
|
PYSIDE_TEST(child_event_test.py)
|
||||||
|
|
|
||||||
18
tests/QtCore/bug_953.py
Normal file
18
tests/QtCore/bug_953.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
from PySide.QtCore import *
|
||||||
|
|
||||||
|
class Dispatcher(QObject):
|
||||||
|
_me = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(Dispatcher, self).__init__()
|
||||||
|
self._me = self
|
||||||
|
QTimer.singleShot(0, self._finish)
|
||||||
|
|
||||||
|
def _finish(self):
|
||||||
|
del self._me # It can't crash here!
|
||||||
|
QTimer.singleShot(10, QCoreApplication.instance().quit)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QCoreApplication([])
|
||||||
|
Dispatcher()
|
||||||
|
app.exec_()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue