diff options
Diffstat (limited to 'pyuno')
-rw-r--r-- | pyuno/inc/pyuno.hxx | 1 | ||||
-rw-r--r-- | pyuno/source/module/pyuno.cxx | 9 | ||||
-rw-r--r-- | pyuno/source/module/pyuno_runtime.cxx | 31 |
3 files changed, 33 insertions, 8 deletions
diff --git a/pyuno/inc/pyuno.hxx b/pyuno/inc/pyuno.hxx index 9c621e71cffe..e2cdc5f0329e 100644 --- a/pyuno/inc/pyuno.hxx +++ b/pyuno/inc/pyuno.hxx @@ -277,6 +277,7 @@ public: class LO_DLLPUBLIC_PYUNO PyThreadAttach { PyThreadState *tstate; + bool m_isNewState; PyThreadAttach ( const PyThreadAttach & ) = delete; PyThreadAttach & operator = ( const PyThreadAttach & ) = delete; public: diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx index d554f5ca769c..a6a875addc46 100644 --- a/pyuno/source/module/pyuno.cxx +++ b/pyuno/source/module/pyuno.cxx @@ -336,13 +336,14 @@ static int lcl_PySlice_GetIndicesEx( PyObject *pObject, sal_Int32 nLen, sal_Int3 { Py_ssize_t nStart_ssize, nStop_ssize, nStep_ssize, nSliceLength_ssize; - int nResult = PySlice_GetIndicesEx( + int nResult = #if PY_VERSION_HEX >= 0x030200f0 - pObject, + PySlice_GetIndicesEx(pObject, + nLen, &nStart_ssize, &nStop_ssize, &nStep_ssize, &nSliceLength_ssize ); #else - reinterpret_cast<PySliceObject*>(pObject), -#endif + PySlice_GetIndicesEx(reinterpret_cast<PySliceObject*>(pObject), nLen, &nStart_ssize, &nStop_ssize, &nStep_ssize, &nSliceLength_ssize ); +#endif if (nResult == -1) return -1; diff --git a/pyuno/source/module/pyuno_runtime.cxx b/pyuno/source/module/pyuno_runtime.cxx index 62b3861288c3..5fa923c236dc 100644 --- a/pyuno/source/module/pyuno_runtime.cxx +++ b/pyuno/source/module/pyuno_runtime.cxx @@ -974,8 +974,21 @@ Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, PyThreadAttach::PyThreadAttach( PyInterpreterState *interp) + : m_isNewState(false) { - tstate = PyThreadState_New( interp ); + // note: *may* be called recursively, with PyThreadDetach between - in + // that case, don't create *new* PyThreadState but reuse! +#ifndef NDEBUG + PyThreadState const*const current = _PyThreadState_UncheckedGet(); + // dereference isn't safe but let's hope it's tolerable for debugging purpose + assert((current == nullptr || current->thread_id != PyThread_get_thread_ident()) && "recursive PyThreadAttach"); +#endif + tstate = PyGILState_GetThisThreadState(); // from TLS, possibly detached + if (!tstate) + { + m_isNewState = true; + tstate = PyThreadState_New( interp ); + } if( !tstate ) throw RuntimeException( "Couldn't create a pythreadstate" ); PyEval_AcquireThread( tstate); @@ -983,9 +996,19 @@ PyThreadAttach::PyThreadAttach( PyInterpreterState *interp) PyThreadAttach::~PyThreadAttach() { - PyThreadState_Clear( tstate ); - PyEval_ReleaseThread( tstate ); - PyThreadState_Delete( tstate ); + if (m_isNewState) + { // Clear needs GIL! + PyThreadState_Clear( tstate ); + } + if (m_isNewState) + { // note: PyThreadState_Delete(tstate) cannot be called, it will assert + // because it requires a PyThreadState to be set, but not the tstate! + PyThreadState_DeleteCurrent(); + } + else + { + PyEval_ReleaseThread( tstate ); + } } PyThreadDetach::PyThreadDetach() |