summaryrefslogtreecommitdiffstats
path: root/pyuno/source/module/pyuno_runtime.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'pyuno/source/module/pyuno_runtime.cxx')
-rw-r--r--pyuno/source/module/pyuno_runtime.cxx31
1 files changed, 27 insertions, 4 deletions
diff --git a/pyuno/source/module/pyuno_runtime.cxx b/pyuno/source/module/pyuno_runtime.cxx
index d307f9af363c..5b10bede5275 100644
--- a/pyuno/source/module/pyuno_runtime.cxx
+++ b/pyuno/source/module/pyuno_runtime.cxx
@@ -977,8 +977,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);
@@ -986,9 +999,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()