From d9e3c8899f80eabafed3cc03ea9d6ecdf38396b8 Mon Sep 17 00:00:00 2001 From: Renato Filho Date: Tue, 30 Aug 2011 16:12:14 -0300 Subject: Fixed cyclic dependency resolution. Reviewer: Hugo Parente Luciano Wolf --- libshiboken/basewrapper.cpp | 69 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 16 deletions(-) (limited to 'libshiboken') diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp index d41bfd15b..006b9c62a 100644 --- a/libshiboken/basewrapper.cpp +++ b/libshiboken/basewrapper.cpp @@ -34,6 +34,10 @@ #include #include "threadstatesaver.h" +namespace { + void _destroyParentInfo(SbkObject* obj, bool keepReference); +} + extern "C" { @@ -107,6 +111,26 @@ static PyGetSetDef SbkObjectGetSetList[] = { static int SbkObject_traverse(PyObject* self, visitproc visit, void* arg) { SbkObject* sbkSelf = reinterpret_cast(self); + + //Visit children + Shiboken::ParentInfo* pInfo = sbkSelf->d->parentInfo; + if (pInfo) { + std::set::const_iterator it = pInfo->children.begin(); + for(; it != pInfo->children.end(); ++it) + Py_VISIT(*it); + } + + //Visit refs + Shiboken::RefCountMap* rInfo = sbkSelf->d->referredObjects; + if (rInfo) { + Shiboken::RefCountMap::const_iterator it = rInfo->begin(); + for (; it != rInfo->end(); ++it) { + std::list::const_iterator ref = it->second.begin(); + for(; ref != it->second.end(); ++ref) + Py_VISIT(*ref); + } + } + if (sbkSelf->ob_dict) Py_VISIT(sbkSelf->ob_dict); return 0; @@ -115,6 +139,14 @@ static int SbkObject_traverse(PyObject* self, visitproc visit, void* arg) static int SbkObject_clear(PyObject* self) { SbkObject* sbkSelf = reinterpret_cast(self); + + Shiboken::Object::removeParent(sbkSelf); + + if (sbkSelf->d->parentInfo) + _destroyParentInfo(sbkSelf, true); + + Shiboken::Object::clearReferences(sbkSelf); + if (sbkSelf->ob_dict) Py_CLEAR(sbkSelf->ob_dict); return 0; @@ -323,6 +355,26 @@ PyObject* SbkObjectTpNew(PyTypeObject* subtype, PyObject*, PyObject*) } //extern "C" + +namespace +{ + +void _destroyParentInfo(SbkObject* obj, bool keepReference) +{ + Shiboken::ParentInfo* pInfo = obj->d->parentInfo; + if (pInfo) { + while(!pInfo->children.empty()) { + SbkObject* first = *pInfo->children.begin(); + // Mark child as invalid + Shiboken::Object::invalidate(first); + Shiboken::Object::removeParent(first, false, keepReference); + } + Shiboken::Object::removeParent(obj, false); + } +} + +} + namespace Shiboken { @@ -682,6 +734,7 @@ void setTypeUserData(SbkObjectType* self, void* userData, DeleteUserDataFunc d_f } // namespace ObjectType + namespace Object { @@ -714,22 +767,6 @@ static void setSequenceOwnership(PyObject* pyObj, bool owner) } } - -static void _destroyParentInfo(SbkObject* obj, bool keepReference) -{ - ParentInfo* pInfo = obj->d->parentInfo; - if (pInfo) { - while(!pInfo->children.empty()) { - SbkObject* first = *pInfo->children.begin(); - // Mark child as invalid - Shiboken::Object::invalidate(first); - removeParent(first, false, keepReference); - } - removeParent(obj, false); - } -} - - void setValidCpp(SbkObject* pyObj, bool value) { pyObj->d->validCppObject = value; -- cgit v1.2.3