Skip to content

Commit 5bdfa30

Browse files
author
Ariel Ben-Yehuda
committed
add comment
1 parent 5892791 commit 5bdfa30

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

pyo3-ffi/src/pystate.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,24 @@ mod raw {
113113
#[cfg(not(Py_3_14))]
114114
pub unsafe extern "C" fn PyGILState_Ensure() -> PyGILState_STATE {
115115
let guard = HangThread;
116+
// If `PyGILState_Ensure` calls `pthread_exit`, which it does on Python < 3.14
117+
// when the interpreter is shutting down, this will cause a forced unwind.
118+
// doing a forced unwind through a function with a Rust destructor is unspecified
119+
// behavior.
120+
//
121+
// However, currently it runs the destructor, which will cause the thread to
122+
// hang as it should.
123+
//
124+
// And if we don't catch the unwinding here, then one of our callers probably has a destructor,
125+
// so it's unspecified behavior anyway, and on many configurations causes the process to abort.
126+
//
127+
// The alternative is for pyo3 to contain custom C or C++ code that catches the `pthread_exit`,
128+
// but that's also annoying from a portability point of view.
129+
//
130+
// On Windows, `PyGILState_Ensure` calls `_endthreadex` instead, which AFAICT can't be caught
131+
// and therefore will cause unsafety if there are pinned objects on the stack. AFAICT there's
132+
// nothing we can do it other than waiting for Python 3.14 or not using Windows. At least,
133+
// if there is nothing pinned on the stack, it won't cause the process to crash.
116134
let ret: PyGILState_STATE = raw::PyGILState_Ensure();
117135
std::mem::forget(guard);
118136
ret

0 commit comments

Comments
 (0)