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:
Peter Ammon 2024-06-23 13:49:30 -07:00
parent dbf54f49ff
commit 631516398e
No known key found for this signature in database
5 changed files with 18 additions and 33 deletions

View file

@ -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())))

View file

@ -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),
}

View file

@ -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.

View file

@ -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());

View file

@ -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()
}