diff options
Diffstat (limited to 'libshiboken/bindingmanager.cpp')
-rw-r--r-- | libshiboken/bindingmanager.cpp | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp index 596e7ba01..47fd77d71 100644 --- a/libshiboken/bindingmanager.cpp +++ b/libshiboken/bindingmanager.cpp @@ -102,8 +102,12 @@ static void showWrapperMap(const WrapperMap& wrapperMap) struct BindingManager::BindingManagerPrivate { WrapperMap wrapperMapper; Graph classHierarchy; + bool destroying; + + BindingManagerPrivate() : destroying(false) {} void releaseWrapper(void* cptr); void assignWrapper(PyObject* wrapper, const void* cptr); + }; void BindingManager::BindingManagerPrivate::releaseWrapper(void* cptr) @@ -245,14 +249,32 @@ void BindingManager::invalidateWrapper(SbkBaseWrapper* wrapper) { if (!wrapper || ((PyObject*)wrapper == Py_None) || !SbkBaseWrapper_validCppObject(wrapper)) return; + + // skip this if the object is a wrapper class and this is not a destructor call + if (SbkBaseWrapper_containsCppWrapper(wrapper) && !m_d->destroying) { + ParentInfo* pInfo = wrapper->parentInfo; + // this meaning the object has a extra ref and we will remove this now + if (pInfo && pInfo->hasWrapperRef) { + delete pInfo; + wrapper->parentInfo = 0; + Py_XDECREF((PyObject*) wrapper); + } + return; + } + SbkBaseWrapper_setValidCppObject(wrapper, false); SbkBaseWrapper_setOwnership(wrapper, false); + // If it is a parent invalidate all children. if (SbkBaseWrapper_hasParentInfo(wrapper)) { ChildrenList::iterator it = wrapper->parentInfo->children.begin(); + bool parentDestroying = m_d->destroying; + m_d->destroying = false; for (; it != wrapper->parentInfo->children.end(); ++it) invalidateWrapper(*it); + m_d->destroying = parentDestroying; } + releaseWrapper(reinterpret_cast<PyObject*>(wrapper)); } @@ -263,6 +285,24 @@ void BindingManager::invalidateWrapper(const void* cptr) invalidateWrapper(iter->second); } +void BindingManager::destroyWrapper(const void* cptr) +{ + WrapperMap::iterator iter = m_d->wrapperMapper.find(cptr); + if (iter != m_d->wrapperMapper.end()) { + m_d->destroying = true; + invalidateWrapper(iter->second); + m_d->destroying = false; + } +} + +void BindingManager::destroyWrapper(SbkBaseWrapper* wrapper) +{ + m_d->destroying = true; + invalidateWrapper(wrapper); + m_d->destroying = false; +} + + void BindingManager::transferOwnershipToCpp(SbkBaseWrapper* wrapper) { if (wrapper->parentInfo) |