Skip to content

Commit

Permalink
Rollup merge of rust-lang#102372 - abrown:issue-102157, r=thomcc
Browse files Browse the repository at this point in the history
Allow compiling the `wasm32-wasi` std library with atomics

The issue rust-lang#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 rust-lang#102157.
  • Loading branch information
matthiaskrgr authored Oct 11, 2022
2 parents 518263d + 9530ba0 commit ac478d4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 9 deletions.
3 changes: 3 additions & 0 deletions library/std/src/sys/wasi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub mod cmath;
pub mod env;
pub mod fd;
pub mod fs;
#[allow(unused)]
#[path = "../wasm/atomics/futex.rs"]
pub mod futex;
pub mod io;
#[path = "../unsupported/locks/mod.rs"]
pub mod locks;
Expand Down
34 changes: 25 additions & 9 deletions library/std/src/sys/wasi/os.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#![deny(unsafe_op_in_unsafe_fn)]

use crate::any::Any;
use crate::error::Error as StdError;
use crate::ffi::{CStr, OsStr, OsString};
use crate::fmt;
use crate::io;
use crate::marker::PhantomData;
use crate::ops::Drop;
use crate::os::wasi::prelude::*;
use crate::path::{self, PathBuf};
use crate::str;
Expand All @@ -24,10 +24,26 @@ mod libc {
}
}

#[cfg(not(target_feature = "atomics"))]
pub unsafe fn env_lock() -> impl Any {
// No need for a lock if we're single-threaded, but this function will need
// to get implemented for multi-threaded scenarios
cfg_if::cfg_if! {
if #[cfg(target_feature = "atomics")] {
// Access to the environment must be protected by a lock in multi-threaded scenarios.
use crate::sync::{PoisonError, RwLock};
static ENV_LOCK: RwLock<()> = RwLock::new(());
pub fn env_read_lock() -> impl Drop {
ENV_LOCK.read().unwrap_or_else(PoisonError::into_inner)
}
pub fn env_write_lock() -> impl Drop {
ENV_LOCK.write().unwrap_or_else(PoisonError::into_inner)
}
} else {
// No need for a lock if we are single-threaded.
pub fn env_read_lock() -> impl Drop {
()
}
pub fn env_write_lock() -> impl Drop {
()
}
}
}

pub fn errno() -> i32 {
Expand Down Expand Up @@ -144,7 +160,7 @@ impl Iterator for Env {

pub fn env() -> Env {
unsafe {
let _guard = env_lock();
let _guard = env_read_lock();
let mut environ = libc::environ;
let mut result = Vec::new();
if !environ.is_null() {
Expand Down Expand Up @@ -175,7 +191,7 @@ pub fn env() -> Env {

pub fn getenv(k: &OsStr) -> Option<OsString> {
let s = run_with_cstr(k.as_bytes(), |k| unsafe {
let _guard = env_lock();
let _guard = env_read_lock();
Ok(libc::getenv(k.as_ptr()) as *const libc::c_char)
})
.ok()?;
Expand All @@ -189,15 +205,15 @@ pub fn getenv(k: &OsStr) -> Option<OsString> {
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
run_with_cstr(k.as_bytes(), |k| {
run_with_cstr(v.as_bytes(), |v| unsafe {
let _guard = env_lock();
let _guard = env_write_lock();
cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop)
})
})
}

pub fn unsetenv(n: &OsStr) -> io::Result<()> {
run_with_cstr(n.as_bytes(), |nbuf| unsafe {
let _guard = env_lock();
let _guard = env_write_lock();
cvt(libc::unsetenv(nbuf.as_ptr())).map(drop)
})
}
Expand Down

0 comments on commit ac478d4

Please sign in to comment.