From 52f29458d7d6cb379d28d84021819516723d9169 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 18 Jun 2020 09:53:06 +0200 Subject: pthreads: Try to abandon the GIL in case a thread was terminated When terminating a thread using QThread::terminate() via (pthread_cancel(), QThread::run() is aborted and the lock is released, but ~GilState() is still executed for some reason. Add a cancel handler to the thread which tells GilState to abandon the lock. Fixes: PYSIDE-1282 Change-Id: I70abd42b5a2afd49aaa8cc5e8be0a92ed63f49d3 Reviewed-by: Cristian Maureira-Fredes --- .../PySide2/QtCore/typesystem_core_common.xml | 8 ++++++- sources/pyside2/PySide2/glue/qtcore.cpp | 28 ++++++++++++++++++++++ sources/shiboken2/libshiboken/gilstate.cpp | 7 ++++++ sources/shiboken2/libshiboken/gilstate.h | 1 + 4 files changed, 43 insertions(+), 1 deletion(-) (limited to 'sources') diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml index 26193a0aa..8294947ed 100644 --- a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml @@ -1460,9 +1460,15 @@ + - + + + + diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp index 111e324b9..41ee743e7 100644 --- a/sources/pyside2/PySide2/glue/qtcore.cpp +++ b/sources/pyside2/PySide2/glue/qtcore.cpp @@ -1960,3 +1960,31 @@ PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first)); PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second)); return %out; // @snippet return-qpair + +// @snippet qthread_pthread_cleanup +#ifdef Q_OS_UNIX +# include +# include +static void qthread_pthread_cleanup(void *arg) +{ + // PYSIDE 1282: When terminating a thread using QThread::terminate() + // (pthread_cancel()), QThread::run() is aborted and the lock is released, + // but ~GilState() is still executed for some reason. Prevent it from + // releasing. + auto gil = reinterpret_cast(arg); + gil->abandon(); +} +#endif // Q_OS_UNIX +// @snippet qthread_pthread_cleanup + +// @snippet qthread_pthread_cleanup_install +#ifdef Q_OS_UNIX +pthread_cleanup_push(qthread_pthread_cleanup, &gil); +#endif +// @snippet qthread_pthread_cleanup_install + +// @snippet qthread_pthread_cleanup_uninstall +#ifdef Q_OS_UNIX +pthread_cleanup_pop(0); +#endif +// @snippet qthread_pthread_cleanup_uninstall diff --git a/sources/shiboken2/libshiboken/gilstate.cpp b/sources/shiboken2/libshiboken/gilstate.cpp index a59c6f01e..76a4d0e61 100644 --- a/sources/shiboken2/libshiboken/gilstate.cpp +++ b/sources/shiboken2/libshiboken/gilstate.cpp @@ -63,5 +63,12 @@ void GilState::release() } } +// Abandon the lock: Only for special situations, like termination of a +// POSIX thread (PYSIDE 1282). +void GilState::abandon() +{ + m_locked = false; +} + } // namespace Shiboken diff --git a/sources/shiboken2/libshiboken/gilstate.h b/sources/shiboken2/libshiboken/gilstate.h index d22f688ba..fbf39ead0 100644 --- a/sources/shiboken2/libshiboken/gilstate.h +++ b/sources/shiboken2/libshiboken/gilstate.h @@ -57,6 +57,7 @@ public: GilState(); ~GilState(); void release(); + void abandon(); private: PyGILState_STATE m_gstate; bool m_locked = false; -- cgit v1.2.3