summaryrefslogtreecommitdiffstats
path: root/Python/thread_pthread.h
diff options
context:
space:
mode:
authorJeremy Maitin-Shepard <jeremy@jeremyms.com>2024-10-02 16:17:49 (GMT)
committerGitHub <noreply@github.com>2024-10-02 16:17:49 (GMT)
commit8cc5aa47ee464ddfd8da5461edecf4a5c72df2ff (patch)
tree41cdda0e2be153a4363cec9d616856444b306273 /Python/thread_pthread.h
parent113b2d7583cdbf79da18e696f299a9aca24b599b (diff)
downloadcpython-8cc5aa47ee464ddfd8da5461edecf4a5c72df2ff.zip
cpython-8cc5aa47ee464ddfd8da5461edecf4a5c72df2ff.tar.gz
cpython-8cc5aa47ee464ddfd8da5461edecf4a5c72df2ff.tar.bz2
gh-87135: Hang non-main threads that attempt to acquire the GIL during finalization (GH-105805)
Instead of surprise crashes and memory corruption, we now hang threads that attempt to re-enter the Python interpreter after Python runtime finalization has started. These are typically daemon threads (our long standing mis-feature) but could also be threads spawned by extension modules that then try to call into Python. This marks the `PyThread_exit_thread` public C API as deprecated as there is no plausible safe way to accomplish that on any supported platform in the face of things like C++ code with finalizers anywhere on a thread's stack. Doing this was the least bad option. Co-authored-by: Gregory P. Smith <greg@krypto.org>
Diffstat (limited to 'Python/thread_pthread.h')
-rw-r--r--Python/thread_pthread.h15
1 files changed, 13 insertions, 2 deletions
diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h
index f588b46..c010b3a 100644
--- a/Python/thread_pthread.h
+++ b/Python/thread_pthread.h
@@ -16,6 +16,7 @@
#undef destructor
#endif
#include <signal.h>
+#include <unistd.h> /* pause(), also getthrid() on OpenBSD */
#if defined(__linux__)
# include <sys/syscall.h> /* syscall(SYS_gettid) */
@@ -23,8 +24,6 @@
# include <pthread_np.h> /* pthread_getthreadid_np() */
#elif defined(__FreeBSD_kernel__)
# include <sys/syscall.h> /* syscall(SYS_thr_self) */
-#elif defined(__OpenBSD__)
-# include <unistd.h> /* getthrid() */
#elif defined(_AIX)
# include <sys/thread.h> /* thread_self() */
#elif defined(__NetBSD__)
@@ -419,6 +418,18 @@ PyThread_exit_thread(void)
#endif
}
+void _Py_NO_RETURN
+PyThread_hang_thread(void)
+{
+ while (1) {
+#if defined(__wasi__)
+ sleep(9999999); // WASI doesn't have pause() ?!
+#else
+ pause();
+#endif
+ }
+}
+
#ifdef USE_SEMAPHORES
/*