diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2011-06-22 11:38:19 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:15:27 -0300 |
commit | 27c3af50e31bdafec37efe55fbcaccf3b1c49d02 (patch) | |
tree | 0e85b1f13e275e138d7ed71bbb4d74fe0e42d93b | |
parent | 923ed37ea91de754e9c87d4d74f38283ebb1d257 (diff) |
Dealloc Python object before calling the C++ destructor.
This will avoid the problem of having Python objects with ref count zero on binding manager
while Python code using these objects can be triggered by the C++ object destruction.
This commit makes DestroyListenner class unused in whole PySide project, probably it will
be marked as deprecated in futher commits.
Reviewer: Luciano Wolf <luciano.wolf@openbossa.org>
Renato Araújo <renato.filho@openbossa.org>
-rw-r--r-- | generator/cppgenerator.cpp | 8 | ||||
-rw-r--r-- | libshiboken/basewrapper.cpp | 39 | ||||
-rw-r--r-- | libshiboken/basewrapper_p.h | 6 |
3 files changed, 35 insertions, 18 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp index f4649213b..25c3db030 100644 --- a/generator/cppgenerator.cpp +++ b/generator/cppgenerator.cpp @@ -599,12 +599,8 @@ void CppGenerator::writeDestructorNative(QTextStream &s, const AbstractMetaClass Indentation indentation(INDENT); s << wrapperName(metaClass) << "::~" << wrapperName(metaClass) << "()" << endl << '{' << endl; // kill pyobject - if (usePySideExtensions() && metaClass->isQObject()) { - s << INDENT << "PySide::DestroyListener::instance()->listen(this);" << endl; - } else { - s << INDENT << "SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(this);" << endl; - s << INDENT << "Shiboken::Object::destroy(wrapper, this);" << endl; - } + s << INDENT << "SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(this);" << endl; + s << INDENT << "Shiboken::Object::destroy(wrapper, this);" << endl; s << '}' << endl; } diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index 25307ac48..4c61c4a79 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -183,13 +183,16 @@ void SbkDeallocWrapper(PyObject* pyObj) Shiboken::DtorCallerVisitor visitor(sbkObj); Shiboken::walkThroughClassHierarchy(pyObj->ob_type, &visitor); } else { + void* cptr = sbkObj->d->cptr[0]; + Shiboken::Object::deallocData(sbkObj, true); + Shiboken::ThreadStateSaver threadSaver; threadSaver.save(); - sbkType->d->cpp_dtor(sbkObj->d->cptr[0]); + sbkType->d->cpp_dtor(cptr); } + } else { + Shiboken::Object::deallocData(sbkObj, true); } - //Always destroy object data during the python object destruction - Shiboken::Object::deallocData(sbkObj, true); } void SbkDeallocWrapperWithPrivateDtor(PyObject* self) @@ -322,7 +325,7 @@ namespace Shiboken static void decRefPyObjectList(const std::list<PyObject*> &pyObj, PyObject* skip = 0); -void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor) +static void _walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor) { PyObject* bases = currentType->tp_bases; Py_ssize_t numBases = PyTuple_GET_SIZE(bases); @@ -334,15 +337,22 @@ void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visi } else { SbkObjectType* sbkType = reinterpret_cast<SbkObjectType*>(type); if (sbkType->d->is_user_type) - walkThroughClassHierarchy(type, visitor); + _walkThroughClassHierarchy(type, visitor); else visitor->visit(sbkType); } if (visitor->wasFinished()) - return; + break; } } +void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visitor) +{ + _walkThroughClassHierarchy(currentType, visitor); + visitor->done(); +} + + bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr) { PyObject* sysModules = PyImport_GetModuleDict(); @@ -368,10 +378,19 @@ bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr) void DtorCallerVisitor::visit(SbkObjectType* node) { - Shiboken::ThreadStateSaver threadSaver; - threadSaver.save(); - node->d->cpp_dtor(m_pyObj->d->cptr[m_count]); - m_count++; + m_ptrs.push_back(std::make_pair(m_pyObj->d->cptr[m_ptrs.size()], node)); +} + +void DtorCallerVisitor::done() +{ + Shiboken::Object::deallocData(m_pyObj, true); + + std::list<std::pair<void*, SbkObjectType*> >::const_iterator it = m_ptrs.begin(); + for (; it != m_ptrs.end(); ++it) { + Shiboken::ThreadStateSaver threadSaver; + threadSaver.save(); + it->second->d->cpp_dtor(it->first); + } } void init() diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h index 25eb12205..c382d3505 100644 --- a/libshiboken/basewrapper_p.h +++ b/libshiboken/basewrapper_p.h @@ -136,6 +136,7 @@ public: HierarchyVisitor() : m_wasFinished(false) {} virtual ~HierarchyVisitor() {} virtual void visit(SbkObjectType* node) = 0; + virtual void done() {} void finish() { m_wasFinished = true; }; bool wasFinished() const { return m_wasFinished; } private: @@ -192,10 +193,11 @@ private: class DtorCallerVisitor : public HierarchyVisitor { public: - DtorCallerVisitor(SbkObject* pyObj) : m_count(0), m_pyObj(pyObj) {} + DtorCallerVisitor(SbkObject* pyObj) : m_pyObj(pyObj) {} void visit(SbkObjectType* node); + void done(); private: - int m_count; + std::list<std::pair<void*, SbkObjectType*> > m_ptrs; SbkObject* m_pyObj; }; |