Browse Source

force exit in std::thread

pull/235/head
ssrlive 6 months ago
parent
commit
d9dcbf9408
  1. 9
      src/bin/main.rs
  2. 6
      src/general_api.rs
  3. 2
      src/lib.rs
  4. 5
      src/win_svc.rs

9
src/bin/main.rs

@ -26,11 +26,12 @@ fn main() -> Result<(), BoxError> {
let rt = tokio::runtime::Builder::new_multi_thread().enable_all().build()?;
rt.block_on(async move {
let res = main_async(args).await;
// Start a timer to force exit after FORCE_EXIT_TIMEOUT second
let _h = tokio::spawn(async move {
log::info!("Starting {}-seconds exit timer", tun2proxy::FORCE_EXIT_TIMEOUT);
// Start a timer to force exit after FORCE_EXIT_TIMEOUT seconds. Use a std thread
// so the timer is not cancelled when the tokio runtime is being shut down.
let _h = std::thread::spawn(move || {
log::info!("Starting {:?} exit timer", tun2proxy::FORCE_EXIT_TIMEOUT);
// Delay some seconds then try to exit current process if not exited yet, normally this case should not happen
tokio::time::sleep(std::time::Duration::from_secs(tun2proxy::FORCE_EXIT_TIMEOUT)).await;
std::thread::sleep(tun2proxy::FORCE_EXIT_TIMEOUT);
log::info!("Forcing exit now.");
std::process::exit(-1);
});

6
src/general_api.rs

@ -132,9 +132,11 @@ pub fn general_run_for_api(args: Args, tun_mtu: u16, packet_information: bool) -
let args_clone = args.clone();
let res = rt.block_on(async move {
let ret = general_run_async(args_clone, tun_mtu, packet_information, shutdown_token).await;
let _h = tokio::spawn(async move {
// Spawn a std thread to force exit after timeout so it isn't cancelled
// when the tokio runtime is dropped.
let _h = std::thread::spawn(move || {
// Delay some seconds then try to exit current process if not exited yet, normally this case should not happen
tokio::time::sleep(std::time::Duration::from_secs(crate::FORCE_EXIT_TIMEOUT)).await;
std::thread::sleep(crate::FORCE_EXIT_TIMEOUT);
log::info!("Forcing exit now.");
std::process::exit(-1);
});

2
src/lib.rs

@ -44,7 +44,7 @@ static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
pub use general_api::general_run_async;
pub const FORCE_EXIT_TIMEOUT: u64 = 2; // seconds
pub const FORCE_EXIT_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(2);
mod android;
mod args;

5
src/win_svc.rs

@ -83,9 +83,10 @@ fn run_service(_arguments: Vec<std::ffi::OsString>) -> Result<(), crate::BoxErro
Ok(sessions) => log::debug!("tun2proxy exited normally, current session count: {sessions}"),
Err(e) => log::error!("failed to run tun2proxy with error: {e:?}"),
}
let _h = tokio::spawn(async move {
// Spawn a std thread so the timer survives runtime shutdown and reliably exits.
let _h = std::thread::spawn(move || {
// Delay some seconds then try to exit current process if not exited yet, normally this case should not happen
tokio::time::sleep(std::time::Duration::from_secs(crate::FORCE_EXIT_TIMEOUT)).await;
std::thread::sleep(crate::FORCE_EXIT_TIMEOUT);
log::info!("Forcing exit now.");
std::process::exit(-1);
});

Loading…
Cancel
Save