|
1 | 1 | //! The interpreter-exit signal native waits poll so Python daemon threads leave native frames before finalization. |
2 | 2 |
|
3 | | -use pyo3::prelude::{Bound, Py, PyAny, PyAnyMethods, PyResult, Python}; |
4 | | -use pyo3::sync::PyOnceLock; |
| 3 | +use std::sync::atomic::{AtomicBool, Ordering}; |
5 | 4 |
|
6 | | -use crate::bindings::_helpers::boundary::python_calls::imported; |
7 | | - |
8 | | -static EXIT_SIGNAL: PyOnceLock<Py<PyAny>> = PyOnceLock::new(); |
9 | | - |
10 | | -/// The process-wide `threading.Event` set once interpreter exit begins. |
11 | | -fn exit_signal(py: Python<'_>) -> PyResult<Bound<'_, PyAny>> { |
12 | | - EXIT_SIGNAL |
13 | | - .get_or_try_init(py, || { |
14 | | - imported(py, "threading", "Event")? |
15 | | - .call0() |
16 | | - .map(Bound::unbind) |
17 | | - }) |
18 | | - .map(|signal| signal.bind(py).clone()) |
19 | | -} |
| 5 | +static EXIT_SIGNAL: AtomicBool = AtomicBool::new(false); |
20 | 6 |
|
21 | 7 | /// Whether an exit hook has started stopping native daemon threads. |
22 | | -pub(crate) fn interpreter_exiting(py: Python<'_>) -> PyResult<bool> { |
23 | | - exit_signal(py)?.call_method0("is_set")?.is_truthy() |
| 8 | +pub(crate) fn interpreter_exiting() -> bool { |
| 9 | + EXIT_SIGNAL.load(Ordering::SeqCst) |
24 | 10 | } |
25 | 11 |
|
26 | 12 | /// Tell every native wait to stop waiting on Python work that may outlive the interpreter. |
27 | | -pub(crate) fn signal_interpreter_exit(py: Python<'_>) -> PyResult<()> { |
28 | | - exit_signal(py)?.call_method0("set")?; |
29 | | - Ok(()) |
| 13 | +pub(crate) fn signal_interpreter_exit() { |
| 14 | + EXIT_SIGNAL.store(true, Ordering::SeqCst); |
30 | 15 | } |
0 commit comments