mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Remove the notion of the "principal" environment stack
The "principal" environment stack was the one that was associated with the "principal" parser and would dispatch changes like to TZ, etc. This was always very suspicious, as a global; now we can remove it.
This commit is contained in:
parent
dbf54f49ff
commit
631516398e
5 changed files with 18 additions and 33 deletions
26
src/env/environment.rs
vendored
26
src/env/environment.rs
vendored
|
@ -187,13 +187,15 @@ impl EnvStack {
|
|||
}
|
||||
}
|
||||
|
||||
// Creates a new EnvStack which dispatches variable changes.
|
||||
// This should be associated with the principal larser.
|
||||
pub fn new_dispatching() -> EnvStack {
|
||||
// Create a "sub-stack" of the given stack.
|
||||
// This shares all nodes (variable scopes) with the parent stack.
|
||||
// can_push_pop is always set.
|
||||
pub fn create_child(&self, dispatches_var_changes: bool) -> EnvStack {
|
||||
let inner = EnvMutex::new(self.inner.lock().clone());
|
||||
EnvStack {
|
||||
inner: EnvStackImpl::new(),
|
||||
inner,
|
||||
can_push_pop: true,
|
||||
dispatches_var_changes: true,
|
||||
dispatches_var_changes,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,11 +203,6 @@ impl EnvStack {
|
|||
self.inner.lock()
|
||||
}
|
||||
|
||||
/// Return whether we are the principal stack.
|
||||
pub fn is_principal(&self) -> bool {
|
||||
std::ptr::eq(self, &**Self::principal())
|
||||
}
|
||||
|
||||
/// Helpers to get and set the proc statuses.
|
||||
/// These correspond to $status and $pipestatus.
|
||||
pub fn get_last_statuses(&self) -> Statuses {
|
||||
|
@ -387,13 +384,6 @@ impl EnvStack {
|
|||
})
|
||||
}
|
||||
|
||||
/// Access the principal variable stack, associated with the principal parser.
|
||||
pub fn principal() -> &'static Arc<EnvStack> {
|
||||
use std::sync::OnceLock;
|
||||
static PRINCIPAL_STACK: OnceLock<Arc<EnvStack>> = OnceLock::new();
|
||||
PRINCIPAL_STACK.get_or_init(|| Arc::new(EnvStack::new_dispatching()))
|
||||
}
|
||||
|
||||
pub fn set_argv(&self, argv: Vec<WString>) {
|
||||
self.set(L!("argv"), EnvMode::LOCAL, argv);
|
||||
}
|
||||
|
@ -575,7 +565,7 @@ fn setup_path() {
|
|||
pub static INHERITED_VARS: OnceCell<HashMap<WString, WString>> = OnceCell::new();
|
||||
|
||||
pub fn env_init(paths: Option<&ConfigPaths>, do_uvars: bool, default_paths: bool) {
|
||||
let vars = &**EnvStack::principal();
|
||||
let vars = EnvStack::globals();
|
||||
|
||||
let env_iter: Vec<_> = std::env::vars_os()
|
||||
.map(|(k, v)| (str2wcstring(k.as_bytes()), str2wcstring(v.as_bytes())))
|
||||
|
|
4
src/env/environment_impl.rs
vendored
4
src/env/environment_impl.rs
vendored
|
@ -300,6 +300,7 @@ struct PerprocData {
|
|||
statuses: Statuses,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EnvScopedImpl {
|
||||
// A linked list of scopes.
|
||||
locals: EnvNodeRef,
|
||||
|
@ -690,6 +691,7 @@ impl ModResult {
|
|||
}
|
||||
|
||||
/// A mutable "subclass" of EnvScopedImpl.
|
||||
#[derive(Clone)]
|
||||
pub struct EnvStackImpl {
|
||||
pub base: EnvScopedImpl,
|
||||
|
||||
|
@ -1122,7 +1124,7 @@ pub struct EnvMutex<T> {
|
|||
}
|
||||
|
||||
impl<T> EnvMutex<T> {
|
||||
fn new(inner: T) -> Self {
|
||||
pub fn new(inner: T) -> Self {
|
||||
Self {
|
||||
inner: UnsafeCell::new(inner),
|
||||
}
|
||||
|
|
|
@ -455,18 +455,11 @@ impl Parser {
|
|||
pub fn principal_parser() -> &'static Parser {
|
||||
use std::cell::OnceCell;
|
||||
static PRINCIPAL: MainThread<OnceCell<ParserRef>> = MainThread::new(OnceCell::new());
|
||||
PRINCIPAL
|
||||
.get()
|
||||
// The parser is !Send/!Sync and strictly single-threaded, but we can have
|
||||
// multi-threaded access to its variables stack (why, though?) so EnvStack::principal()
|
||||
// returns an Arc<EnvStack> instead of an Rc<EnvStack>. Since the Arc<EnvStack> is
|
||||
// statically allocated and always valid (not even destroyed on exit), we can safely
|
||||
// transform the Arc<T> into an Rc<T> and save Parser from needing atomic ref counting
|
||||
// to manage its further references.
|
||||
.get_or_init(|| {
|
||||
let env_rc = unsafe { Rc::from_raw(&**EnvStack::principal() as *const _) };
|
||||
Parser::new(env_rc, true)
|
||||
})
|
||||
PRINCIPAL.get().get_or_init(|| {
|
||||
let dispatches_var_changes = true;
|
||||
let env = Rc::new(EnvStack::globals().create_child(dispatches_var_changes));
|
||||
Parser::new(env, true)
|
||||
})
|
||||
}
|
||||
|
||||
/// Assert that this parser is allowed to execute on the current thread.
|
||||
|
|
|
@ -57,7 +57,7 @@ impl Environment for PwdEnvironment {
|
|||
|
||||
/// Helper for test_timezone_env_vars().
|
||||
fn return_timezone_hour(tstamp: SystemTime, timezone: &wstr) -> libc::c_int {
|
||||
let vars = EnvStack::new_dispatching();
|
||||
let vars = EnvStack::globals().create_child(true /* dispatches_var_changes */);
|
||||
|
||||
vars.set_one(L!("TZ"), EnvMode::EXPORT, timezone.to_owned());
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ pub mod prelude {
|
|||
signal_reset_handlers();
|
||||
|
||||
// Set PWD from getcwd - fixes #5599
|
||||
EnvStack::principal().set_pwd_from_getcwd();
|
||||
EnvStack::globals().set_pwd_from_getcwd();
|
||||
});
|
||||
reader_init()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue