diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2010-10-01 18:28:38 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:07:20 -0300 |
commit | 0eddf25bcb9833d94f1860d8bb3be859f2971930 (patch) | |
tree | 1d6a3560532cf00efd4a37479d26fe1a1977c764 /libshiboken | |
parent | dadcc2efac417680073cae92c1ca64580af7d327 (diff) |
Avoid possible race condition when destroying wrappers.
Diffstat (limited to 'libshiboken')
-rw-r--r-- | libshiboken/bindingmanager.cpp | 13 |
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; |