From 4097ee0cdf767b592f05662e44cb8bfbf8aef4af Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 May 2025 21:47:42 +1000 Subject: [PATCH] chore(gui-client): only read `is_finished` once (#9095) For at least 1 user, the threads shut down correctly, but we didn't seem to have exited the loop. In https://firezone-inc.sentry.io/issues/6335839279/events/c11596de18924ee3a1b64ced89b1fba2/?project=4508008945549312, we can see that both flags are marked as `true` yet we still emitted the message. The only way how I can explain this is that the thread shut down in between the two times we've called the `is_finished` function. To ensure this doesn't happen, we now only read it once. This however also shows that 5s may not be enough time for WinTUN to shutdown. Therefore, we increase the grace period to 10s. --- .../src/tun_device_manager/windows.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/rust/bin-shared/src/tun_device_manager/windows.rs b/rust/bin-shared/src/tun_device_manager/windows.rs index 24b50aa83..533061b77 100644 --- a/rust/bin-shared/src/tun_device_manager/windows.rs +++ b/rust/bin-shared/src/tun_device_manager/windows.rs @@ -212,6 +212,8 @@ struct TunState { impl Drop for Tun { fn drop(&mut self) { + const SHUTDOWN_WAIT: Duration = Duration::from_secs(10); + let recv_thread = self .recv_thread .take() @@ -226,13 +228,20 @@ impl Drop for Tun { let start = Instant::now(); - while !recv_thread.is_finished() || !send_thread.is_finished() { - std::thread::sleep(Duration::from_millis(100)); + loop { + let recv_thread_finished = recv_thread.is_finished(); + let send_thread_finished = send_thread.is_finished(); - if start.elapsed() > Duration::from_secs(5) { - tracing::warn!(recv_thread_finished = %recv_thread.is_finished(), send_thread_finished = %send_thread.is_finished(), "TUN worker threads did not exit gracefully in 5s"); + if recv_thread_finished && send_thread_finished { + break; + } + + if start.elapsed() > SHUTDOWN_WAIT { + tracing::warn!(%recv_thread_finished, %send_thread_finished, "TUN worker threads did not exit gracefully in {SHUTDOWN_WAIT:?}"); return; } + + std::thread::sleep(Duration::from_millis(100)); } tracing::debug!(