put tokio runtime in dedicated thread (#1086)

* put tokio runtime in dedicated thread

* more

* more

* more

* more
This commit is contained in:
Logan McNaughton
2026-06-16 11:33:27 +02:00
committed by GitHub
parent 19142a30c6
commit c290e60af1
5 changed files with 36 additions and 14 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde-big-array = "0.5"
sha2 = "0.11"
tokio = {version = "1.46", features = ["rt-multi-thread", "macros", "fs", "process"] }
tokio = {version = "1.46", features = ["rt-multi-thread", "fs", "process"] }
spin_sleep = "1.3"
encoding_rs = "0.8"
mimalloc = "0.1"
+19 -5
View File
@@ -104,6 +104,19 @@ fn set_app_id() {
}
}
pub fn create_runtime() -> (tokio::sync::oneshot::Sender<()>, tokio::runtime::Handle) {
let (tx, rx) = std::sync::mpsc::channel();
let (close_tx, close_rx) = tokio::sync::oneshot::channel::<()>();
std::thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().expect("Failed to build runtime");
tx.send(rt.handle().clone()).unwrap();
rt.block_on(close_rx).unwrap();
});
(close_tx, rx.recv().unwrap())
}
pub fn run(args: Args, arg_count: usize) -> std::io::Result<()> {
let dirs = ui::get_dirs();
@@ -213,9 +226,7 @@ pub fn run(args: Args, arg_count: usize) -> std::io::Result<()> {
tx.send(false).unwrap();
}
tokio::task::block_in_place(move || {
rx.blocking_recv().unwrap();
});
rx.blocking_recv().unwrap();
ra_config
} else {
@@ -334,8 +345,10 @@ pub fn run(args: Args, arg_count: usize) -> std::io::Result<()> {
#[cfg(target_os = "android")]
#[unsafe(no_mangle)]
#[tokio::main]
async fn android_main(app: slint::android::AndroidApp) {
fn android_main(app: slint::android::AndroidApp) {
let (close_tx, handle) = create_runtime();
let _guard = handle.enter();
slint::android::init_with_event_listener(app.clone(), move |event| match event {
slint::android::android_activity::PollEvent::Main(main_event) => match main_event {
slint::android::android_activity::MainEvent::TerminateWindow { .. } => {
@@ -368,6 +381,7 @@ async fn android_main(app: slint::android::AndroidApp) {
std::fs::create_dir_all(dirs.data_dir.join("states")).unwrap();
ui::gui::app_window(&app_window, true);
close_tx.send(()).unwrap();
*android::WEAK_SLINT_WINDOW.lock().unwrap() = None;
*android::ANDROID_APP.lock().unwrap() = None;
}
+7 -3
View File
@@ -5,8 +5,12 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
use clap::Parser;
#[tokio::main]
async fn main() -> std::io::Result<()> {
fn main() -> std::io::Result<()> {
let (close_tx, handle) = gopher64::create_runtime();
let _guard = handle.enter();
let args = gopher64::Args::parse();
gopher64::run(args, std::env::args().count())
let result = gopher64::run(args, std::env::args().count());
close_tx.send(()).unwrap();
result
}
+2 -3
View File
@@ -150,9 +150,8 @@ pub fn load_game(
let tx_ptr = Box::into_raw(Box::new(tx)) as *mut std::ffi::c_void;
ra_load_game(rom.as_ptr(), rom_size, tx_ptr);
};
tokio::task::block_in_place(move || {
rx.blocking_recv().unwrap();
});
rx.blocking_recv().unwrap();
let mut c_title = std::ptr::null();
let mut c_image_url = std::ptr::null();
+7 -2
View File
@@ -1,4 +1,5 @@
use crate::Args;
use crate::create_runtime;
use crate::run;
use crate::ui;
use clap::Parser;
@@ -158,17 +159,21 @@ fn argv_to_strings(argc: std::ffi::c_int, argv: *mut *mut std::ffi::c_char) -> V
}
#[unsafe(no_mangle)]
#[tokio::main]
pub async extern "C" fn gopher64_sdl_main(
pub extern "C" fn gopher64_sdl_main(
argc: std::ffi::c_int,
argv: *mut *mut std::ffi::c_char,
) -> std::ffi::c_int {
let (close_tx, handle) = create_runtime();
let _guard = handle.enter();
let raw = argv_to_strings(argc, argv);
let args = Args::try_parse_from(raw).unwrap();
if let Err(err) = run(args, argc as usize) {
close_tx.send(()).unwrap();
eprintln!("Error running game: {err:?}");
return 1;
}
close_tx.send(()).unwrap();
0
}