From 64443aa173ad80759246c7e25e8e19de93adb061 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Wed, 29 Apr 2026 14:16:35 +0800 Subject: [PATCH] Lower OnceLock to LazyLock LazyLock is less powerful so we should use it when possible. Ref: https://github.com/fish-shell/fish-shell/pull/12661#discussion_r3158097032 --- crates/common/src/lib.rs | 9 ++++----- src/env/config_paths.rs | 7 +++---- src/env/environment.rs | 8 ++++---- src/env/environment_impl.rs | 9 +++------ src/env/var.rs | 7 +++---- src/exec.rs | 8 +++++--- src/fs.rs | 7 ++++--- src/operation_context.rs | 7 +++---- src/universal_notifier/mod.rs | 9 ++++----- 9 files changed, 33 insertions(+), 38 deletions(-) diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index c1df7e530..740bf7253 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -18,7 +18,7 @@ unix::ffi::OsStrExt as _, }, sync::{ - Arc, OnceLock, + Arc, LazyLock, atomic::{AtomicI32, AtomicU32, Ordering}, }, time, @@ -1018,9 +1018,8 @@ pub fn read_unquoted_escape( /// session. We err on the side of assuming it's not a console session. This approach isn't /// bullet-proof and that's OK. pub fn is_console_session() -> bool { - static IS_CONSOLE_SESSION: OnceLock = OnceLock::new(); // TODO(terminal-workaround) - *IS_CONSOLE_SESSION.get_or_init(|| { + static IS_CONSOLE_SESSION: LazyLock = LazyLock::new(|| // No console session on Apple, and ttyname may hang (#12506). !cfg!(apple) && nix::unistd::ttyname(unsafe { std::os::fd::BorrowedFd::borrow_raw(STDIN_FILENO) }) @@ -1037,8 +1036,8 @@ pub fn is_console_session() -> bool { // and that $TERM is simple, e.g. `xterm` or `vt100`, not `xterm-something` or `sun-color`. is_console_tty && env::var_os("TERM").is_none_or(|t| !t.as_bytes().contains(&b'-')) - }) - }) + })); + *IS_CONSOLE_SESSION } /// Exits without invoking destructors (via _exit), useful for code after fork. diff --git a/src/env/config_paths.rs b/src/env/config_paths.rs index d7520f984..d7f656977 100644 --- a/src/env/config_paths.rs +++ b/src/env/config_paths.rs @@ -4,7 +4,7 @@ use std::ffi::OsStr; use std::os::unix::ffi::OsStrExt as _; use std::path::{Path, PathBuf}; -use std::sync::OnceLock; +use std::sync::LazyLock; /// A struct of configuration directories, determined in main() that fish will optionally pass to /// env_init. @@ -22,7 +22,6 @@ pub struct ConfigPaths { impl ConfigPaths { pub fn new() -> Self { - FISH_PATH.get_or_init(compute_fish_path); let exec_path = get_fish_path(); flog!( config, @@ -167,11 +166,11 @@ pub enum FishPath { LookUpInPath, } -static FISH_PATH: OnceLock = OnceLock::new(); +static FISH_PATH: LazyLock = LazyLock::new(compute_fish_path); /// Get the absolute path to the fish executable itself pub fn get_fish_path() -> &'static FishPath { - FISH_PATH.get().unwrap() + &FISH_PATH } fn compute_fish_path() -> FishPath { diff --git a/src/env/environment.rs b/src/env/environment.rs index d00e3563a..282ea6ebb 100644 --- a/src/env/environment.rs +++ b/src/env/environment.rs @@ -405,14 +405,14 @@ pub fn universal_sync(&self, always: bool, is_repainting: bool) -> Vec { /// A variable stack that only represents globals. /// Do not push or pop from this. pub fn globals() -> &'static EnvStack { - use std::sync::OnceLock; - static GLOBALS: OnceLock = OnceLock::new(); - GLOBALS.get_or_init(|| EnvStack { + use std::sync::LazyLock; + static GLOBALS: LazyLock = LazyLock::new(|| EnvStack { inner: EnvStackImpl::new(), can_push_pop: false, // Do not dispatch variable changes - this is used at startup when we are importing env vars. dispatches_var_changes: false, - }) + }); + &GLOBALS } pub fn set_argv(&self, argv: Vec, is_repainting: bool) { diff --git a/src/env/environment_impl.rs b/src/env/environment_impl.rs index 3ba1d2ad7..c51ed3377 100644 --- a/src/env/environment_impl.rs +++ b/src/env/environment_impl.rs @@ -27,13 +27,10 @@ /// Getter for universal variables. /// This is typically initialized in env_init(), and is considered empty before then. pub fn uvars() -> MutexGuard<'static, EnvUniversal> { - use std::sync::OnceLock; + use std::sync::LazyLock; /// Universal variables instance. - static UVARS: OnceLock> = OnceLock::new(); - UVARS - .get_or_init(|| Mutex::new(EnvUniversal::new())) - .lock() - .unwrap() + static UVARS: LazyLock> = LazyLock::new(|| Mutex::new(EnvUniversal::new())); + UVARS.lock().unwrap() } /// Whether we were launched with no_config; in this case setting a uvar instead sets a global. diff --git a/src/env/var.rs b/src/env/var.rs index 48a6a1635..0dc270a17 100644 --- a/src/env/var.rs +++ b/src/env/var.rs @@ -130,13 +130,12 @@ pub struct EnvVar { impl Default for EnvVar { fn default() -> Self { - use std::sync::OnceLock; + use std::sync::LazyLock; /// A shared read-only empty list. - static EMPTY_LIST: OnceLock> = OnceLock::new(); - let empty_list = EMPTY_LIST.get_or_init(|| Arc::new([])); + static EMPTY_LIST: LazyLock> = LazyLock::new(|| Arc::new([])); EnvVar { - values: Arc::clone(empty_list), + values: Arc::clone(&*EMPTY_LIST), flags: EnvVarFlags::empty(), } } diff --git a/src/exec.rs b/src/exec.rs index 1b54f6f2a..45692d259 100644 --- a/src/exec.rs +++ b/src/exec.rs @@ -54,6 +54,7 @@ sys::stat, unistd::{getpgrp, getpid}, }; +use std::sync::LazyLock; use std::{ ffi::CStr, io::{Read as _, Write as _}, @@ -62,7 +63,7 @@ os::fd::{AsRawFd as _, FromRawFd as _, OwnedFd, RawFd}, slice, sync::{ - Arc, OnceLock, + Arc, atomic::{AtomicUsize, Ordering}, }, }; @@ -72,9 +73,10 @@ /// to their target fds. /// TODO: this IO could be multiplexed using FdMonitor. fn exec_thread_pool() -> &'static Arc { - static EXEC_THREAD_POOL: OnceLock> = OnceLock::new(); // Use an unbounded queue because otherwise we risk deadlock. - EXEC_THREAD_POOL.get_or_init(|| ThreadPool::new(1, usize::MAX)) + static EXEC_THREAD_POOL: LazyLock> = + LazyLock::new(|| ThreadPool::new(1, usize::MAX)); + &EXEC_THREAD_POOL } /// Execute the processes specified by `j` in the parser \p. diff --git a/src/fs.rs b/src/fs.rs index 53058798d..75287c761 100644 --- a/src/fs.rs +++ b/src/fs.rs @@ -126,9 +126,10 @@ pub fn new(locking_mode: LockingMode, file_path: &wstr) -> std::io::Result { // Cygwin's `flock` is currently not thread safe (#11933) #[cfg(cygwin)] - static FLOCK_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); - #[cfg(cygwin)] - let _lock = FLOCK_LOCK.lock().unwrap(); + let _lock = { + static FLOCK_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(()); + FLOCK_LOCK.lock().unwrap() + }; // Try locking the directory. Retry if locking was interrupted. while unsafe { libc::flock(dir_fd.as_raw_fd(), locking_mode.flock_op()) } == -1 { diff --git a/src/operation_context.rs b/src/operation_context.rs index 34995f9b4..d2e6b36bc 100644 --- a/src/operation_context.rs +++ b/src/operation_context.rs @@ -57,10 +57,9 @@ pub fn vars(&self) -> &dyn Environment { // Return an "empty" context which contains no variables, no parser, and never cancels. pub fn empty() -> OperationContext<'static> { - use std::sync::OnceLock; - static NULL_ENV: OnceLock = OnceLock::new(); - let null_env = NULL_ENV.get_or_init(EnvStack::new); - OperationContext::background(null_env, EXPANSION_LIMIT_DEFAULT) + use std::sync::LazyLock; + static NULL_ENV: LazyLock = LazyLock::new(EnvStack::new); + OperationContext::background(&*NULL_ENV, EXPANSION_LIMIT_DEFAULT) } // Return an operation context that contains only global variables, no parser, and never diff --git a/src/universal_notifier/mod.rs b/src/universal_notifier/mod.rs index 40262ae3d..cb65f65d2 100644 --- a/src/universal_notifier/mod.rs +++ b/src/universal_notifier/mod.rs @@ -1,4 +1,4 @@ -use std::{os::fd::RawFd, sync::OnceLock}; +use std::{os::fd::RawFd, sync::LazyLock}; #[cfg(apple)] mod notifyd; @@ -67,9 +67,8 @@ pub fn create_notifier() -> Box { Box::new(NullNotifier) } -// Default instance. Other instances are possible for testing. -static DEFAULT_NOTIFIER: OnceLock> = OnceLock::new(); - pub fn default_notifier() -> &'static dyn UniversalNotifier { - DEFAULT_NOTIFIER.get_or_init(create_notifier).as_ref() + // Default instance. Other instances are possible for testing. + static DEFAULT_NOTIFIER: LazyLock> = LazyLock::new(create_notifier); + &**DEFAULT_NOTIFIER }