summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Araujo Oliveira Filho <renato.filho@openbossa.org>2010-12-14 15:19:37 -0300
committerRenato Araujo Oliveira Filho <renato.filho@openbossa.org>2010-12-14 17:40:50 -0300
commitfb4035a69475759e58e25d5aa0f061d6c212f4af (patch)
tree7166c73411f374dbeda8f712c608d7afd650f92a
parentb915f12df2349760309c2f7227bcdbad3c73a7da (diff)
downloadshiboken-fb4035a69475759e58e25d5aa0f061d6c212f4af.tar.gz
shiboken-fb4035a69475759e58e25d5aa0f061d6c212f4af.tar.xz
shiboken-fb4035a69475759e58e25d5aa0f061d6c212f4af.zip
Fix object destruction process to avoid pass a invalid object during the
__del__ function. Fix bug #505 Reviewer: Luciano Wolf <luciano.wolf@openbossa.org> Marcelo Lira <marcelo.lira@openbossa.org>
-rw-r--r--generator/cppgenerator.cpp2
-rw-r--r--libshiboken/basewrapper.cpp27
-rw-r--r--libshiboken/basewrapper.h1
-rw-r--r--libshiboken/bindingmanager.cpp3
4 files changed, 20 insertions, 13 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index 55747d37..5b7b0d03 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -464,7 +464,7 @@ void CppGenerator::writeDestructorNative(QTextStream &s, const AbstractMetaClass
Indentation indentation(INDENT);
s << wrapperName(metaClass) << "::~" << wrapperName(metaClass) << "()" << endl << '{' << endl;
s << INDENT << "SbkObject* wrapper = Shiboken::BindingManager::instance().retrieveWrapper(this);" << endl;
- s << INDENT << "Shiboken::Object::destroy(wrapper);" << endl;
+ s << INDENT << "Shiboken::Object::destroy(wrapper, this);" << endl;
s << '}' << endl;
}
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp
index 72615dbb..1f2499d0 100644
--- a/libshiboken/basewrapper.cpp
+++ b/libshiboken/basewrapper.cpp
@@ -813,6 +813,11 @@ PyObject* newObject(SbkObjectType* instanceType,
void destroy(SbkObject* self)
{
+ destroy(self, 0);
+}
+
+void destroy(SbkObject* self, void* cppData)
+{
// Skip if this is called with NULL pointer this can happen in derived classes
if (!self)
return;
@@ -820,16 +825,9 @@ void destroy(SbkObject* self)
// This can be called in c++ side
Shiboken::GilState gil;
- // We will marks this object as invalid because this function will be called from wrapper destructor
- // If The object has ownership and this was destroyed then is necessary invalidate to avoid future used by Python
- self->d->validCppObject = false;
-
// Remove all references attached to this object
clearReferences(self);
- // Remove from BindinManager
- Shiboken::BindingManager::instance().releaseWrapper(self);
-
// Remove the object from parent control
// Verify if this object has parent
@@ -847,6 +845,13 @@ void destroy(SbkObject* self)
// This can cause the object death
Py_DECREF((PyObject*)self);
}
+
+ //Python Object is not destroyed yet
+ if (cppData && Shiboken::BindingManager::instance().hasWrapper(cppData)) {
+ // Remove from BindinManager
+ Shiboken::BindingManager::instance().releaseWrapper(self);
+ }
+
// After this point the object can be death do not use the self pointer bellow
}
@@ -875,7 +880,7 @@ void removeParent(SbkObject* child, bool giveOwnershipBack, bool keepReference)
child->d->hasOwnership = giveOwnershipBack;
// Remove parent ref
- Py_DECREF(child);
+ Py_CLEAR(child);
}
void setParent(PyObject* parent, PyObject* child)
@@ -951,11 +956,11 @@ void deallocData(SbkObject* self, bool cleanup)
_destroyParentInfo(self, true);
clearReferences(self);
-
- // Remove from BindinManager
- Shiboken::BindingManager::instance().releaseWrapper(self);
}
+ // Remove from BindinManager
+ Shiboken::BindingManager::instance().releaseWrapper(self);
+
Py_XDECREF(self->ob_dict);
delete[] self->d->cptr;
self->d->cptr = 0;
diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h
index 46bc641d..99e35474 100644
--- a/libshiboken/basewrapper.h
+++ b/libshiboken/basewrapper.h
@@ -294,6 +294,7 @@ LIBSHIBOKEN_API void makeValid(SbkObject* self);
* Destroy any data in Shiboken structure and c++ pointer if the pyboject has the ownership
**/
LIBSHIBOKEN_API void destroy(SbkObject* self);
+LIBSHIBOKEN_API void destroy(SbkObject* self, void* cppData);
/**
* Set user data on type of \p wrapper.
diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp
index 2bcf2deb..68bfe485 100644
--- a/libshiboken/bindingmanager.cpp
+++ b/libshiboken/bindingmanager.cpp
@@ -148,7 +148,7 @@ BindingManager::~BindingManager()
* the BindingManager is being destroyed the interpreter is alredy
* shutting down. */
while (!m_d->wrapperMapper.empty()) {
- Object::destroy(m_d->wrapperMapper.begin()->second);
+ Object::destroy(m_d->wrapperMapper.begin()->second, const_cast<void*>(m_d->wrapperMapper.begin()->first));
}
assert(m_d->wrapperMapper.size() == 0);
delete m_d;
@@ -204,6 +204,7 @@ void BindingManager::releaseWrapper(SbkObject* sbkObj)
}
}
}
+ sbkObj->d->validCppObject = false;
}
SbkObject* BindingManager::retrieveWrapper(const void* cptr)