Skip to content

Commit 2a92176

Browse files
committed
Auto merge of #102372 - abrown:issue-102157, r=thomcc
Allow compiling the `wasm32-wasi` std library with atomics The issue #102157 demonstrates how currently the `-Z build-std` option will fail when re-compiling the standard library with `RUSTFLAGS` like `RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C link-args=--shared-memory"`. This change attempts to resolve those build issues by depending on the the WebAssembly `futex` module and providing an implementation for `env_lock`. Fixes #102157.
2 parents 0938e16 + 95b0b2d commit 2a92176

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

library/std/src/sys/wasi/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ pub mod cmath;
2525
pub mod env;
2626
pub mod fd;
2727
pub mod fs;
28+
#[allow(unused)]
29+
#[path = "../wasm/atomics/futex.rs"]
30+
pub mod futex;
2831
pub mod io;
2932
#[path = "../unsupported/locks/mod.rs"]
3033
pub mod locks;

library/std/src/sys/wasi/os.rs

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#![deny(unsafe_op_in_unsafe_fn)]
22

3-
use crate::any::Any;
43
use crate::error::Error as StdError;
54
use crate::ffi::{CStr, OsStr, OsString};
65
use crate::fmt;
76
use crate::io;
87
use crate::marker::PhantomData;
8+
use crate::ops::Drop;
99
use crate::os::wasi::prelude::*;
1010
use crate::path::{self, PathBuf};
1111
use crate::str;
@@ -24,10 +24,26 @@ mod libc {
2424
}
2525
}
2626

27-
#[cfg(not(target_feature = "atomics"))]
28-
pub unsafe fn env_lock() -> impl Any {
29-
// No need for a lock if we're single-threaded, but this function will need
30-
// to get implemented for multi-threaded scenarios
27+
cfg_if::cfg_if! {
28+
if #[cfg(target_feature = "atomics")] {
29+
// Access to the environment must be protected by a lock in multi-threaded scenarios.
30+
use crate::sync::{PoisonError, RwLock};
31+
static ENV_LOCK: RwLock<()> = RwLock::new(());
32+
pub fn env_read_lock() -> impl Drop {
33+
ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner)
34+
}
35+
pub fn env_write_lock() -> impl Drop {
36+
ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner)
37+
}
38+
} else {
39+
// No need for a lock if we are single-threaded.
40+
pub fn env_read_lock() -> impl Drop {
41+
Box::new(())
42+
}
43+
pub fn env_write_lock() -> impl Drop {
44+
Box::new(())
45+
}
46+
}
3147
}
3248

3349
pub fn errno() -> i32 {
@@ -144,7 +160,7 @@ impl Iterator for Env {
144160

145161
pub fn env() -> Env {
146162
unsafe {
147-
let _guard = env_lock();
163+
let _guard = env_read_lock();
148164
let mut environ = libc::environ;
149165
let mut result = Vec::new();
150166
if !environ.is_null() {
@@ -175,7 +191,7 @@ pub fn env() -> Env {
175191

176192
pub fn getenv(k: &OsStr) -> Option<OsString> {
177193
let s = run_with_cstr(k.as_bytes(), |k| unsafe {
178-
let _guard = env_lock();
194+
let _guard = env_read_lock();
179195
Ok(libc::getenv(k.as_ptr()) as *const libc::c_char)
180196
})
181197
.ok()?;
@@ -189,15 +205,15 @@ pub fn getenv(k: &OsStr) -> Option<OsString> {
189205
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
190206
run_with_cstr(k.as_bytes(), |k| {
191207
run_with_cstr(v.as_bytes(), |v| unsafe {
192-
let _guard = env_lock();
208+
let _guard = env_write_lock();
193209
cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
194210
})
195211
})
196212
}
197213

198214
pub fn unsetenv(n: &OsStr) -> io::Result<()> {
199215
run_with_cstr(n.as_bytes(), |nbuf| unsafe {
200-
let _guard = env_lock();
216+
let _guard = env_write_lock();
201217
cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
202218
})
203219
}

0 commit comments

Comments
 (0)