From 27c3af50e31bdafec37efe55fbcaccf3b1c49d02 Mon Sep 17 00:00:00 2001 From: Hugo Parente Lima Date: Wed, 22 Jun 2011 11:38:19 -0300 Subject: Dealloc Python object before calling the C++ destructor. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Renato Araújo --- libshiboken/basewrapper.cpp | 39 +++++++++++++++++++++++++++++---------- libshiboken/basewrapper_p.h | 6 ++++-- 2 files changed, 33 insertions(+), 12 deletions(-) (limited to 'libshiboken') 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 &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(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 >::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 > m_ptrs; SbkObject* m_pyObj; }; -- cgit v1.2.3