mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 05:53:59 +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.
|
// Create a "sub-stack" of the given stack.
|
||||||
// This should be associated with the principal larser.
|
// This shares all nodes (variable scopes) with the parent stack.
|
||||||
pub fn new_dispatching() -> EnvStack {
|
// 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 {
|
EnvStack {
|
||||||
inner: EnvStackImpl::new(),
|
inner,
|
||||||
can_push_pop: true,
|
can_push_pop: true,
|
||||||
dispatches_var_changes: true,
|
dispatches_var_changes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +203,6 @@ impl EnvStack {
|
||||||
self.inner.lock()
|
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.
|
/// Helpers to get and set the proc statuses.
|
||||||
/// These correspond to $status and $pipestatus.
|
/// These correspond to $status and $pipestatus.
|
||||||
pub fn get_last_statuses(&self) -> Statuses {
|
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>) {
|
pub fn set_argv(&self, argv: Vec<WString>) {
|
||||||
self.set(L!("argv"), EnvMode::LOCAL, argv);
|
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 static INHERITED_VARS: OnceCell<HashMap<WString, WString>> = OnceCell::new();
|
||||||
|
|
||||||
pub fn env_init(paths: Option<&ConfigPaths>, do_uvars: bool, default_paths: bool) {
|
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()
|
let env_iter: Vec<_> = std::env::vars_os()
|
||||||
.map(|(k, v)| (str2wcstring(k.as_bytes()), str2wcstring(v.as_bytes())))
|
.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,
|
statuses: Statuses,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct EnvScopedImpl {
|
pub struct EnvScopedImpl {
|
||||||
// A linked list of scopes.
|
// A linked list of scopes.
|
||||||
locals: EnvNodeRef,
|
locals: EnvNodeRef,
|
||||||
|
@ -690,6 +691,7 @@ impl ModResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A mutable "subclass" of EnvScopedImpl.
|
/// A mutable "subclass" of EnvScopedImpl.
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct EnvStackImpl {
|
pub struct EnvStackImpl {
|
||||||
pub base: EnvScopedImpl,
|
pub base: EnvScopedImpl,
|
||||||
|
|
||||||
|
@ -1122,7 +1124,7 @@ pub struct EnvMutex<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EnvMutex<T> {
|
impl<T> EnvMutex<T> {
|
||||||
fn new(inner: T) -> Self {
|
pub fn new(inner: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: UnsafeCell::new(inner),
|
inner: UnsafeCell::new(inner),
|
||||||
}
|
}
|
||||||
|
|
|
@ -455,18 +455,11 @@ impl Parser {
|
||||||
pub fn principal_parser() -> &'static Parser {
|
pub fn principal_parser() -> &'static Parser {
|
||||||
use std::cell::OnceCell;
|
use std::cell::OnceCell;
|
||||||
static PRINCIPAL: MainThread<OnceCell<ParserRef>> = MainThread::new(OnceCell::new());
|
static PRINCIPAL: MainThread<OnceCell<ParserRef>> = MainThread::new(OnceCell::new());
|
||||||
PRINCIPAL
|
PRINCIPAL.get().get_or_init(|| {
|
||||||
.get()
|
let dispatches_var_changes = true;
|
||||||
// The parser is !Send/!Sync and strictly single-threaded, but we can have
|
let env = Rc::new(EnvStack::globals().create_child(dispatches_var_changes));
|
||||||
// multi-threaded access to its variables stack (why, though?) so EnvStack::principal()
|
Parser::new(env, true)
|
||||||
// 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)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assert that this parser is allowed to execute on the current thread.
|
/// 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().
|
/// Helper for test_timezone_env_vars().
|
||||||
fn return_timezone_hour(tstamp: SystemTime, timezone: &wstr) -> libc::c_int {
|
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());
|
vars.set_one(L!("TZ"), EnvMode::EXPORT, timezone.to_owned());
|
||||||
|
|
||||||
|
|
|
@ -107,7 +107,7 @@ pub mod prelude {
|
||||||
signal_reset_handlers();
|
signal_reset_handlers();
|
||||||
|
|
||||||
// Set PWD from getcwd - fixes #5599
|
// Set PWD from getcwd - fixes #5599
|
||||||
EnvStack::principal().set_pwd_from_getcwd();
|
EnvStack::globals().set_pwd_from_getcwd();
|
||||||
});
|
});
|
||||||
reader_init()
|
reader_init()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue