use quote::quote;
use crate::codegen::format_tokens_static;
pub(crate) fn generate(async_methods: bool) -> String {
let init_async = async_methods.then(|| {
quote! {
pub fn init_async_runtime() {
let _ = ::pyo3_async_runtimes::tokio::init_with_runtime(rt());
}
}
});
let tokens = quote! {
use std::sync::OnceLock;
use tokio::runtime::{Builder, Runtime};
pub fn rt() -> &'static Runtime {
static RUNTIME: OnceLock<Runtime> = OnceLock::new();
static PID: OnceLock<u32> = OnceLock::new();
let pid = std::process::id();
let runtime_pid = *PID.get_or_init(|| pid);
if pid != runtime_pid {
panic!(
"Forked process detected: current PID is {pid} but the tokio runtime was \
created by {runtime_pid}. The tokio runtime does not support forked processes \
(https://github.com/tokio-rs/tokio/issues/4301). When using Python \
multiprocessing, set the start method to 'spawn' or 'forkserver'."
);
}
RUNTIME.get_or_init(|| {
Builder::new_multi_thread()
.enable_all()
.build()
.expect("failed to build the tokio runtime")
})
}
#init_async
};
format_tokens_static(tokens)
}