1010// -----------------------------------------------------------------------------
1111PyObject* CPyCppyy::DispatchPtr::Get (bool borrowed) const
1212{
13+ PyGILState_STATE state = PyGILState_Ensure ();
14+ PyObject* result = nullptr ;
1315 if (fPyHardRef ) {
1416 if (!borrowed) Py_INCREF (fPyHardRef );
15- return fPyHardRef ;
16- }
17- if (fPyWeakRef ) {
18- PyObject* disp = CPyCppyy_GetWeakRef (fPyWeakRef );
19- if (disp) { // dispatcher object disappeared?
20- if (borrowed) Py_DECREF (disp);
21- return disp;
17+ result = fPyHardRef ;
18+ } else if (fPyWeakRef ) {
19+ result = CPyCppyy_GetWeakRef (fPyWeakRef );
20+ if (result) { // dispatcher object disappeared?
21+ if (borrowed) Py_DECREF (result);
2222 }
2323 }
24- return nullptr ;
24+ PyGILState_Release (state);
25+ return result;
2526}
2627
2728// -----------------------------------------------------------------------------
2829CPyCppyy::DispatchPtr::DispatchPtr (PyObject* pyobj, bool strong) : fPyHardRef(nullptr )
2930{
31+ PyGILState_STATE state = PyGILState_Ensure ();
3032 if (strong) {
3133 Py_INCREF (pyobj);
3234 fPyHardRef = pyobj;
@@ -36,15 +38,18 @@ CPyCppyy::DispatchPtr::DispatchPtr(PyObject* pyobj, bool strong) : fPyHardRef(nu
3638 fPyWeakRef = PyWeakref_NewRef (pyobj, nullptr );
3739 }
3840 ((CPPInstance*)pyobj)->SetDispatchPtr (this );
41+ PyGILState_Release (state);
3942}
4043
4144// -----------------------------------------------------------------------------
4245CPyCppyy::DispatchPtr::DispatchPtr (const DispatchPtr& other, void * cppinst) : fPyWeakRef(nullptr )
4346{
47+ PyGILState_STATE state = PyGILState_Ensure ();
4448 PyObject* pyobj = other.Get (false /* not borrowed */ );
4549 fPyHardRef = pyobj ? (PyObject*)((CPPInstance*)pyobj)->Copy (cppinst) : nullptr ;
4650 if (fPyHardRef ) ((CPPInstance*)fPyHardRef )->SetDispatchPtr (this );
4751 Py_XDECREF (pyobj);
52+ PyGILState_Release (state);
4853}
4954
5055// -----------------------------------------------------------------------------
@@ -53,6 +58,7 @@ CPyCppyy::DispatchPtr::~DispatchPtr() {
5358// of a dispatcher intermediate, then this delete is from the C++ side, and Python
5459// is "notified" by nulling out the reference and an exception will be raised on
5560// continued access
61+ PyGILState_STATE state = PyGILState_Ensure ();
5662 if (fPyWeakRef ) {
5763 PyObject* pyobj = CPyCppyy_GetWeakRef (fPyWeakRef );
5864 if (pyobj && ((CPPScope*)Py_TYPE (pyobj))->fFlags & CPPScope::kIsPython )
@@ -63,11 +69,13 @@ CPyCppyy::DispatchPtr::~DispatchPtr() {
6369 ((CPPInstance*)fPyHardRef )->GetObjectRaw () = nullptr ;
6470 Py_DECREF (fPyHardRef );
6571 }
72+ PyGILState_Release (state);
6673}
6774
6875// -----------------------------------------------------------------------------
6976CPyCppyy::DispatchPtr& CPyCppyy::DispatchPtr::assign (const DispatchPtr& other, void * cppinst)
7077{
78+ PyGILState_STATE state = PyGILState_Ensure ();
7179 if (this != &other) {
7280 Py_XDECREF (fPyWeakRef ); fPyWeakRef = nullptr ;
7381 Py_XDECREF (fPyHardRef );
@@ -76,6 +84,7 @@ CPyCppyy::DispatchPtr& CPyCppyy::DispatchPtr::assign(const DispatchPtr& other, v
7684 if (fPyHardRef ) ((CPPInstance*)fPyHardRef )->SetDispatchPtr (this );
7785 Py_XDECREF (pyobj);
7886 }
87+ PyGILState_Release (state);
7988 return *this ;
8089}
8190
@@ -93,8 +102,10 @@ void CPyCppyy::DispatchPtr::PythonOwns()
93102void CPyCppyy::DispatchPtr::CppOwns ()
94103{
95104// C++ maintains the hardref, keeping the PyObject alive w/o outstanding ref
105+ PyGILState_STATE state = PyGILState_Ensure ();
96106 if (fPyWeakRef ) {
97107 fPyHardRef = CPyCppyy_GetWeakRef (fPyWeakRef );
98108 Py_DECREF (fPyWeakRef ); fPyWeakRef = nullptr ;
99109 }
110+ PyGILState_Release (state);
100111}
0 commit comments