environment_impl: drop usage of lazy_static

This commit is contained in:
tranzystorekk
2024-12-31 19:53:21 +01:00
committed by Peter Ammon
parent 967c4b2272
commit 3129c9e939
3 changed files with 19 additions and 15 deletions

1
Cargo.lock generated
View File

@@ -118,7 +118,6 @@ dependencies = [
"cc",
"errno",
"fish-printf",
"lazy_static",
"libc",
"lru",
"nix",

View File

@@ -35,7 +35,6 @@ pcre2 = { git = "https://github.com/fish-shell/rust-pcre2", tag = "0.2.9-utf32",
bitflags = "2.5.0"
errno = "0.3.0"
lazy_static = "1.4.0"
libc = "0.2.155"
# lru pulls in hashbrown by default, which uses a faster (though less DoS resistant) hashing algo.
# disabling default features uses the stdlib instead, but it doubles the time to rewrite the history

View File

@@ -14,7 +14,7 @@
use crate::wchar::prelude::*;
use crate::wutil::fish_wcstol_radix;
use lazy_static::lazy_static;
use once_cell::sync::Lazy;
use std::cell::{RefCell, UnsafeCell};
use std::collections::HashSet;
use std::ffi::CString;
@@ -201,16 +201,28 @@ fn changed_exported(&mut self) {
}
}
// RefCell except we promise it can be used as Sync.
// Safety: in order to do anything with this, the caller must be holding ENV_LOCK.
struct EnvNodeSyncCell(RefCell<EnvNode>);
impl EnvNodeSyncCell {
fn new(node: EnvNode) -> Self {
Self(RefCell::new(node))
}
}
unsafe impl Sync for EnvNodeSyncCell {}
/// EnvNodeRef is a reference to an EnvNode. It may be shared between different environments.
/// The type Arc<RefCell<...>> may look suspicious, but all accesses to the EnvNode are protected by a global lock.
/// All accesses to the EnvNode are protected by a global lock.
#[derive(Clone)]
struct EnvNodeRef(Arc<RefCell<EnvNode>>);
struct EnvNodeRef(Arc<EnvNodeSyncCell>);
impl Deref for EnvNodeRef {
type Target = RefCell<EnvNode>;
fn deref(&self) -> &Self::Target {
&self.0
&self.0 .0
}
}
@@ -219,7 +231,7 @@ fn new(is_new_scope: bool, next: Option<EnvNodeRef>) -> EnvNodeRef {
// Accesses are protected by the global lock.
#[allow(unknown_lints)]
#[allow(clippy::arc_with_non_send_sync)]
EnvNodeRef(Arc::new(RefCell::new(EnvNode {
EnvNodeRef(Arc::new(EnvNodeSyncCell::new(EnvNode {
env: VarTable::new(),
new_scope: is_new_scope,
export_gen: 0,
@@ -248,9 +260,6 @@ fn iter(&self) -> EnvNodeIter {
}
}
// Safety: in order to do anything with an EnvNodeRef, the caller must be holding ENV_LOCK.
unsafe impl Sync for EnvNodeRef {}
/// Helper to iterate over a chain of EnvNodeRefs.
struct EnvNodeIter {
current: Option<EnvNodeRef>,
@@ -276,10 +285,7 @@ fn next(&mut self) -> Option<EnvNodeRef> {
}
}
lazy_static! {
// All accesses to the EnvNode are protected by a global lock.
static ref GLOBAL_NODE: EnvNodeRef = EnvNodeRef::new(false, None);
}
static GLOBAL_NODE: Lazy<EnvNodeRef> = Lazy::new(|| EnvNodeRef::new(false, None));
/// Recursive helper to snapshot a series of nodes.
fn copy_node_chain(node: &EnvNodeRef) -> EnvNodeRef {
@@ -293,7 +299,7 @@ fn copy_node_chain(node: &EnvNodeRef) -> EnvNodeRef {
};
#[allow(unknown_lints)]
#[allow(clippy::arc_with_non_send_sync)]
EnvNodeRef(Arc::new(RefCell::new(new_node)))
EnvNodeRef(Arc::new(EnvNodeSyncCell::new(new_node)))
}
/// A struct wrapping up parser-local variables. These are conceptually variables that differ in