MCPcopy Create free account
hub / github.com/dgrunwald/rust-cpython / prepare_freethreaded_python

Function prepare_freethreaded_python

src/pythonrun.rs:47–82  ·  view source on GitHub ↗

Prepares the use of Python in a free-threaded context. If the Python interpreter is not already initialized, this function will initialize it with disabled signal handling (Python will not raise the `KeyboardInterrupt` exception). Python signal handling depends on the notion of a 'main thread', which must be the thread that initializes the Python interpreter. If both the Python interpreter and P

()

Source from the content-addressed store, hash-verified

45/// will ensure that Python threading is initialized.
46///
47pub fn prepare_freethreaded_python() {
48 // Protect against race conditions when Python is not yet initialized
49 // and multiple threads concurrently call 'prepare_freethreaded_python()'.
50 // Note that we do not protect against concurrent initialization of the Python runtime
51 // by other users of the Python C API.
52 START.call_once(|| unsafe {
53 if ffi::Py_IsInitialized() != 0 {
54 // If Python is already initialized, we expect Python threading to also be initialized,
55 // as we can't make the existing Python main thread acquire the GIL.
56 assert!(ffi::PyEval_ThreadsInitialized() != 0);
57 } else {
58 #[cfg(feature = "python27-sys")]
59 {
60 // If Python isn't initialized yet, we expect that Python threading isn't initialized either.
61 assert!(ffi::PyEval_ThreadsInitialized() == 0);
62 // Note: starting with Python 3.2 it's no longer possible to initialize threading
63 // without initializing Python; and in Python 3.7 PyEval_ThreadsInitialized() started
64 // misbehaving when Python was not initialized yet.
65 }
66 // Initialize Python.
67 // We use Py_InitializeEx() with initsigs=0 to disable Python signal handling.
68 // Signal handling depends on the notion of a 'main thread', which doesn't exist in this case.
69 // Note that the 'main thread' notion in Python isn't documented properly;
70 // and running Python without one is not officially supported.
71 ffi::Py_InitializeEx(0);
72 ffi::PyEval_InitThreads();
73 // PyEval_InitThreads() will acquire the GIL,
74 // but we don't want to hold it at this point
75 // (it's not acquired in the other code paths)
76 // So immediately release the GIL:
77 let _thread_state = ffi::PyEval_SaveThread();
78 // Note that the PyThreadState returned by PyEval_SaveThread is also held in TLS by the Python runtime,
79 // and will be restored by PyGILState_Ensure.
80 }
81 });
82}
83
84/// RAII type that represents the Global Interpreter Lock acquisition.
85///

Callers 1

acquireMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected