summaryrefslogtreecommitdiff
path: root/pyuno
diff options
context:
space:
mode:
Diffstat (limited to 'pyuno')
-rw-r--r--pyuno/inc/pyuno.hxx1
-rw-r--r--pyuno/source/module/pyuno.cxx9
-rw-r--r--pyuno/source/module/pyuno_runtime.cxx31
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()