diff --git a/src/platform/redox/clone.rs b/src/platform/redox/clone.rs index 4bb4da8efd..336c0937cf 100644 --- a/src/platform/redox/clone.rs +++ b/src/platform/redox/clone.rs @@ -7,6 +7,8 @@ use syscall::{ SetSighandlerData, SIGCONT, }; +use crate::sync::rwlock::Rwlock; + use super::{ extra::{create_set_addr_space_buf, FdGuard}, signal::sighandler_function, @@ -14,6 +16,26 @@ use super::{ pub use redox_exec::*; +static CLONE_LOCK: Rwlock = Rwlock::new(crate::pthread::Pshared::Private); + +struct Guard; +impl Drop for Guard { + fn drop(&mut self) { + CLONE_LOCK.unlock() + } +} + +pub fn rdlock() -> impl Drop { + CLONE_LOCK.acquire_read_lock(None); + + Guard +} +pub fn wrlock() -> impl Drop { + CLONE_LOCK.acquire_write_lock(None); + + Guard +} + /// Spawns a new context sharing the same address space as the current one (i.e. a new thread). pub unsafe fn rlct_clone_impl(stack: *mut usize) -> Result { let cur_pid_fd = FdGuard::new(syscall::open("thisproc:current/open_via_dup", O_CLOEXEC)?); diff --git a/src/platform/redox/mod.rs b/src/platform/redox/mod.rs index 8023077afe..36c844bc8e 100644 --- a/src/platform/redox/mod.rs +++ b/src/platform/redox/mod.rs @@ -277,7 +277,9 @@ impl Pal for Sys { } fn fork() -> pid_t { - e(clone::fork_impl()) as pid_t + let _guard = clone::wrlock(); + let res = clone::fork_impl(); + e(res) as pid_t } // FIXME: unsound @@ -789,8 +791,10 @@ impl Pal for Sys { unsafe fn rlct_clone( stack: *mut usize, ) -> Result { - clone::rlct_clone_impl(stack) - .map(|context_id| crate::pthread::OsTid { context_id }) + let _guard = clone::rdlock(); + let res = clone::rlct_clone_impl(stack); + + res.map(|context_id| crate::pthread::OsTid { context_id }) .map_err(|error| crate::pthread::Errno(error.errno)) } unsafe fn rlct_kill( diff --git a/src/sync/rwlock.rs b/src/sync/rwlock.rs index 30aae21c01..fe066a1798 100644 --- a/src/sync/rwlock.rs +++ b/src/sync/rwlock.rs @@ -16,7 +16,7 @@ const EXCLUSIVE: u32 = COUNT_MASK; // TODO: Add futex ops that use bitmasks. impl Rwlock { - pub fn new(_pshared: Pshared) -> Self { + pub const fn new(_pshared: Pshared) -> Self { Self { state: AtomicU32::new(0), }