|
1 | | -#![allow(implicit_provenance_casts)] // FIXME: this module systematically confuses pointers and integers |
2 | | - |
3 | 1 | pub use super::common::Env; |
4 | 2 | use crate::collections::HashMap; |
5 | 3 | use crate::ffi::{OsStr, OsString}; |
6 | 4 | use crate::io; |
7 | | -use crate::sync::atomic::{Atomic, AtomicUsize, Ordering}; |
8 | | -use crate::sync::{Mutex, Once}; |
| 5 | +use crate::sync::{Mutex, OnceLock}; |
| 6 | + |
| 7 | +type EnvStore = Mutex<HashMap<OsString, OsString>>; |
9 | 8 |
|
10 | 9 | // Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests |
11 | 10 | #[cfg_attr(test, linkage = "available_externally")] |
12 | 11 | #[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os3ENVE")] |
13 | | -static ENV: Atomic<usize> = AtomicUsize::new(0); |
14 | | -// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests |
15 | | -#[cfg_attr(test, linkage = "available_externally")] |
16 | | -#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os8ENV_INITE")] |
17 | | -static ENV_INIT: Once = Once::new(); |
18 | | -type EnvStore = Mutex<HashMap<OsString, OsString>>; |
19 | | - |
20 | | -fn get_env_store() -> Option<&'static EnvStore> { |
21 | | - unsafe { (ENV.load(Ordering::Relaxed) as *const EnvStore).as_ref() } |
22 | | -} |
23 | | - |
24 | | -fn create_env_store() -> &'static EnvStore { |
25 | | - ENV_INIT.call_once(|| { |
26 | | - ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed) |
27 | | - }); |
28 | | - unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) } |
29 | | -} |
| 12 | +static ENV: OnceLock<EnvStore> = OnceLock::new(); |
30 | 13 |
|
31 | 14 | pub fn env() -> Env { |
32 | | - let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> { |
33 | | - map.iter().map(|(k, v)| (k.clone(), v.clone())).collect() |
34 | | - }; |
35 | | - |
36 | | - let env = get_env_store().map(|env| clone_to_vec(&env.lock().unwrap())).unwrap_or_default(); |
| 15 | + let env = ENV |
| 16 | + .get() |
| 17 | + .map(|env| env.lock().unwrap().iter().map(|(k, v)| (k.clone(), v.clone())).collect()) |
| 18 | + .unwrap_or_default(); |
37 | 19 | Env::new(env) |
38 | 20 | } |
39 | 21 |
|
40 | 22 | pub fn getenv(k: &OsStr) -> Option<OsString> { |
41 | | - get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned()) |
| 23 | + ENV.get().and_then(|s| s.lock().unwrap().get(k).cloned()) |
42 | 24 | } |
43 | 25 |
|
44 | 26 | pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { |
45 | | - let (k, v) = (k.to_owned(), v.to_owned()); |
46 | | - create_env_store().lock().unwrap().insert(k, v); |
| 27 | + ENV.get_or_init(|| EnvStore::default()).lock().unwrap().insert(k.to_owned(), v.to_owned()); |
47 | 28 | Ok(()) |
48 | 29 | } |
49 | 30 |
|
50 | 31 | pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> { |
51 | | - if let Some(env) = get_env_store() { |
| 32 | + if let Some(env) = ENV.get() { |
52 | 33 | env.lock().unwrap().remove(k); |
53 | 34 | } |
54 | 35 | Ok(()) |
|
0 commit comments