diff --git a/src/core/alloc/je.rs b/src/core/alloc/je.rs index ad1a6ce6..9b0fcae7 100644 --- a/src/core/alloc/je.rs +++ b/src/core/alloc/je.rs @@ -274,6 +274,10 @@ pub fn set_dirty_decay>>(arena: I, decay_ms: isize) -> Res } } +pub fn background_thread_enable(enable: bool) -> Result { + set::(&mallctl!("background_thread"), enable.into()).map(is_nonzero!()) +} + #[inline] #[must_use] pub fn is_affine_arena() -> bool { is_percpu_arena() || is_phycpu_arena() } diff --git a/src/main/runtime.rs b/src/main/runtime.rs index d590f261..d06e7f5e 100644 --- a/src/main/runtime.rs +++ b/src/main/runtime.rs @@ -98,12 +98,7 @@ pub(super) fn shutdown(server: &Arc, runtime: tokio::runtime::Runtime) { Level::INFO }; - debug!( - timeout = ?SHUTDOWN_TIMEOUT, - "Waiting for runtime..." - ); - - runtime.shutdown_timeout(SHUTDOWN_TIMEOUT); + wait_shutdown(server, runtime); let runtime_metrics = server .server .metrics @@ -115,13 +110,23 @@ pub(super) fn shutdown(server: &Arc, runtime: tokio::runtime::Runtime) { #[cfg(not(tokio_unstable))] #[tracing::instrument(name = "stop", level = "info", skip_all)] -pub(super) fn shutdown(_server: &Arc, runtime: tokio::runtime::Runtime) { +pub(super) fn shutdown(server: &Arc, runtime: tokio::runtime::Runtime) { + wait_shutdown(server, runtime); +} + +fn wait_shutdown(_server: &Arc, runtime: tokio::runtime::Runtime) { debug!( timeout = ?SHUTDOWN_TIMEOUT, "Waiting for runtime..." ); runtime.shutdown_timeout(SHUTDOWN_TIMEOUT); + + // Join any jemalloc threads so they don't appear in use at exit. + #[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))] + tuwunel_core::alloc::je::background_thread_enable(false) + .log_debug_err() + .ok(); } #[tracing::instrument( @@ -180,6 +185,7 @@ fn set_worker_mallctl(id: usize) { let muzzy_auto_disable = tuwunel_core::utils::available_parallelism() >= DISABLE_MUZZY_THRESHOLD; + if matches!(muzzy_option, Some(false) | None if muzzy_auto_disable) { set_muzzy_decay(-1).log_debug_err().ok(); }