aboutsummaryrefslogtreecommitdiffstats
path: root/libshiboken
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2010-10-01 18:28:38 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:07:20 -0300
commit0eddf25bcb9833d94f1860d8bb3be859f2971930 (patch)
tree1d6a3560532cf00efd4a37479d26fe1a1977c764 /libshiboken
parentdadcc2efac417680073cae92c1ca64580af7d327 (diff)
Avoid possible race condition when destroying wrappers.
Diffstat (limited to 'libshiboken')
-rw-r--r--libshiboken/bindingmanager.cpp13
1 files changed, 7 insertions, 6 deletions
diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp
index 36a5abc72..5149a4dec 100644
--- a/libshiboken/bindingmanager.cpp
+++ b/libshiboken/bindingmanager.cpp
@@ -27,6 +27,7 @@
#include "bindingmanager.h"
#include "google/dense_hash_map"
#include "sbkdbg.h"
+#include "gilstate.h"
namespace Shiboken
{
@@ -259,6 +260,8 @@ void BindingManager::invalidateWrapper(SbkBaseWrapper* wrapper)
if (!wrapper || ((PyObject*)wrapper == Py_None) || !SbkBaseWrapper_validCppObject(wrapper))
return;
+ GilState gil; // lock the gil to assure no one is changing the value of m_d->destroying
+
// 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;
@@ -278,7 +281,7 @@ void BindingManager::invalidateWrapper(SbkBaseWrapper* wrapper)
if (SbkBaseWrapper_hasParentInfo(wrapper)) {
ChildrenList::iterator it = wrapper->parentInfo->children.begin();
bool parentDestroying = m_d->destroying;
- m_d->destroying = false;
+ m_d->destroying = false;
for (; it != wrapper->parentInfo->children.end(); ++it)
invalidateWrapper(*it);
m_d->destroying = parentDestroying;
@@ -297,15 +300,13 @@ void BindingManager::invalidateWrapper(const void* cptr)
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;
- }
+ if (iter != m_d->wrapperMapper.end())
+ destroyWrapper(reinterpret_cast<SbkBaseWrapper*>(iter->second));
}
void BindingManager::destroyWrapper(SbkBaseWrapper* wrapper)
{
+ GilState gil;
m_d->destroying = true;
invalidateWrapper(wrapper);
m_d->destroying = false;