@@ -2003,9 +2003,9 @@ impl ExitCode {
20032003 ///
20042004 /// Note that this has the same caveats as [`process::exit()`][exit], namely that this function
20052005 /// terminates the process immediately, so no destructors on the current stack or any other
2006- /// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply
2007- /// return this ExitCode from the `main` function, as demonstrated in the [type
2008- /// documentation](#examples).
2006+ /// thread's stack will be run. Also see those docs for some important notes on interop with C
2007+ /// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from
2008+ /// the `main` function, as demonstrated in the [type documentation](#examples).
20092009 ///
20102010 /// # Differences from `process::exit()`
20112011 ///
@@ -2297,6 +2297,34 @@ impl Child {
22972297/// considered undesirable. Note that returning from `main` also calls `exit`, so making `exit` an
22982298/// unsafe operation is not an option.)
22992299///
2300+ /// ## Safe interop with C code
2301+ ///
2302+ /// This function is safe to call as long as `exit` is only ever invoked from Rust. However, on some
2303+ /// platforms this function is implemented by calling the C function [`exit`][C-exit]. As of C23,
2304+ /// the C standard does not permit multiple threads to call `exit` concurrently. Rust mitigates this
2305+ /// with a lock, but if C code calls `exit`, that can still cause undefined behavior. Note that
2306+ /// returning from `main` is equivalent to calling `exit`.
2307+ ///
2308+ /// Therefore, it is undefined behavior to have two concurrent threads perform the following
2309+ /// without synchronization:
2310+ /// - One thread calls Rust's `exit` function or returns from Rust's `main` function
2311+ /// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function
2312+ ///
2313+ /// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining
2314+ /// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the
2315+ /// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C
2316+ /// code, and concurrent `exit` again causes undefined behavior.
2317+ ///
2318+ /// Individual C implementations might provide more guarantees than the standard and permit concurrent
2319+ /// calls to `exit`; consult the documentation of your C implementation for details.
2320+ ///
2321+ /// For some of the on-going discussion to make `exit` thread-safe in C, see:
2322+ /// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600)
2323+ /// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845)
2324+ /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997)
2325+ ///
2326+ /// [C-exit]: https://en.cppreference.com/w/c/program/exit
2327+ ///
23002328/// ## Platform-specific behavior
23012329///
23022330/// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`
0 commit comments