]> git.lizzy.rs Git - rust.git/commitdiff
explain mem::forget(env_lock) in fork/exec
authorRalf Jung <post@ralfj.de>
Mon, 12 Dec 2022 08:49:42 +0000 (09:49 +0100)
committerRalf Jung <post@ralfj.de>
Mon, 12 Dec 2022 20:02:49 +0000 (21:02 +0100)
library/std/src/sys/unix/process/process_unix.rs

index 56a805cef7318fe8e6ed00f57997d90647a03b22..c0716a089bc38b1b2b3be521c41165e259daeb46 100644 (file)
@@ -66,14 +66,15 @@ pub fn spawn(
         //
         // Note that as soon as we're done with the fork there's no need to hold
         // a lock any more because the parent won't do anything and the child is
-        // in its own process. Thus the parent drops the lock guard while the child
-        // forgets it to avoid unlocking it on a new thread, which would be invalid.
+        // in its own process. Thus the parent drops the lock guard immediately.
+        // The child calls `mem::forget` to leak the lock, which is crucial because
+        // releasing a lock is not async-signal-safe.
         let env_lock = sys::os::env_read_lock();
         let (pid, pidfd) = unsafe { self.do_fork()? };
 
         if pid == 0 {
             crate::panic::always_abort();
-            mem::forget(env_lock);
+            mem::forget(env_lock); // avoid non-async-signal-safe unlocking
             drop(input);
             let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
             let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;