Merge branch 'fork_clone_sync' into 'master'
Protect fork() and clone() behind a rwlock. See merge request redox-os/relibc!468
This commit is contained in:
@@ -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<usize> {
|
||||
let cur_pid_fd = FdGuard::new(syscall::open("thisproc:current/open_via_dup", O_CLOEXEC)?);
|
||||
|
||||
@@ -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<crate::pthread::OsTid, crate::pthread::Errno> {
|
||||
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(
|
||||
|
||||
+1
-1
@@ -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),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user