about summary refs log tree commit diff
path: root/library/std/src/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-13 00:37:28 +0000
committerbors <bors@rust-lang.org>2022-10-13 00:37:28 +0000
commit2a9217601c0e5ae83fa8bca6797137a6d2f7e4e5 (patch)
treec25ae335d6dc9bd35d582122abccbfcda152eab8 /library/std/src/sys
parent0938e1680daf66ca6aad428aedf9a920a0dab5ad (diff)
parent95b0b2d34956c232ace714c1f5971b20e2767c6c (diff)
downloadrust-2a9217601c0e5ae83fa8bca6797137a6d2f7e4e5.tar.gz
rust-2a9217601c0e5ae83fa8bca6797137a6d2f7e4e5.zip
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.
Diffstat (limited to 'library/std/src/sys')
-rw-r--r--library/std/src/sys/wasi/mod.rs3
-rw-r--r--library/std/src/sys/wasi/os.rs34
2 files changed, 28 insertions, 9 deletions
diff --git a/library/std/src/sys/wasi/mod.rs b/library/std/src/sys/wasi/mod.rs
index 683a07a34dc..c8c47763a34 100644
--- a/library/std/src/sys/wasi/mod.rs
+++ b/library/std/src/sys/wasi/mod.rs
@@ -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;
diff --git a/library/std/src/sys/wasi/os.rs b/library/std/src/sys/wasi/os.rs
index cab2887dfcf..f5513e9996d 100644
--- a/library/std/src/sys/wasi/os.rs
+++ b/library/std/src/sys/wasi/os.rs
@@ -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;
@@ -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 {
+            Box::new(())
+        }
+        pub fn env_write_lock() -> impl Drop {
+            Box::new(())
+        }
+    }
 }
 
 pub fn errno() -> i32 {
@@ -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() {
@@ -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()?;
@@ -189,7 +205,7 @@ 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)
         })
     })
@@ -197,7 +213,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
 
 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)
     })
 }