Skip to content

Commit 3465d5f

Browse files
committed
explain mem::forget(env_lock) in fork/exec
1 parent 2cd2070 commit 3465d5f

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

library/std/src/sys/unix/process/process_unix.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ impl Command {
6666
//
6767
// Note that as soon as we're done with the fork there's no need to hold
6868
// a lock any more because the parent won't do anything and the child is
69-
// in its own process. Thus the parent drops the lock guard while the child
70-
// forgets it to avoid unlocking it on a new thread, which would be invalid.
69+
// in its own process. Thus the parent drops the lock guard immediately.
70+
// The child calls `mem::forget` to leak the lock, which is crucial because
71+
// releasing a lock is not async-signal-safe.
7172
let env_lock = sys::os::env_read_lock();
7273
let (pid, pidfd) = unsafe { self.do_fork()? };
7374

7475
if pid == 0 {
7576
crate::panic::always_abort();
76-
mem::forget(env_lock);
77+
mem::forget(env_lock); // avoid non-async-signal-safe unlocking
7778
drop(input);
7879
let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
7980
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;

0 commit comments

Comments
 (0)