aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-06-18 09:53:06 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-06-26 15:14:14 +0200
commit52f29458d7d6cb379d28d84021819516723d9169 (patch)
treeafad9317cbf204ff6716c24ec4041b4495bfd36d
parentb7e8b5e4114c034a750433d661b20944ce8b303c (diff)
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 <cristian.maureira-fredes@qt.io>
-rw-r--r--sources/pyside2/PySide2/QtCore/typesystem_core_common.xml8
-rw-r--r--sources/pyside2/PySide2/glue/qtcore.cpp28
-rw-r--r--sources/shiboken2/libshiboken/gilstate.cpp7
-rw-r--r--sources/shiboken2/libshiboken/gilstate.h1
4 files changed, 43 insertions, 1 deletions
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 @@
<enum-type name="IteratorFlag" flags="IteratorFlags"/>
</object-type>
<object-type name="QThread">
+ <inject-code file="../glue/qtcore.cpp" class="native" position="beginning" snippet="qthread_pthread_cleanup"/>
<enum-type name="Priority"/>
<modify-function signature="currentThreadId()" remove="all"/>
- <modify-function signature="run()" allow-thread="yes"/>
+ <modify-function signature="run()" allow-thread="yes">
+ <inject-code file="../glue/qtcore.cpp" class="native" position="beginning"
+ snippet="qthread_pthread_cleanup_install"/>
+ <inject-code file="../glue/qtcore.cpp" class="native" position="end"
+ snippet="qthread_pthread_cleanup_uninstall"/>
+ </modify-function>
<modify-function signature="exec()" rename="exec_" allow-thread="yes"/>
<modify-function signature="msleep(unsigned long)" allow-thread="yes"/>
<modify-function signature="sleep(unsigned long)" allow-thread="yes"/>
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 <stdio.h>
+# include <pthread.h>
+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<Shiboken::GilState *>(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;