diff options
| author | Ralf Jung <post@ralfj.de> | 2025-01-30 22:15:26 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-03-04 08:44:05 +0100 |
| commit | 7b5e847ae5b8d2da27455ffd3fe55cc2e2dccf6d (patch) | |
| tree | b5589d2de086f98d1847195187c97fbedbabb691 /library/std/src/process.rs | |
| parent | 81d8edc2000aa38b08ad09fce22d90f1990b6459 (diff) | |
| download | rust-7b5e847ae5b8d2da27455ffd3fe55cc2e2dccf6d.tar.gz rust-7b5e847ae5b8d2da27455ffd3fe55cc2e2dccf6d.zip | |
exit: document interaction with C
Diffstat (limited to 'library/std/src/process.rs')
| -rw-r--r-- | library/std/src/process.rs | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/library/std/src/process.rs b/library/std/src/process.rs index bdd4844b651..2ae93d84ba4 100644 --- a/library/std/src/process.rs +++ b/library/std/src/process.rs @@ -2003,9 +2003,9 @@ impl ExitCode { /// /// Note that this has the same caveats as [`process::exit()`][exit], namely that this function /// terminates the process immediately, so no destructors on the current stack or any other - /// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply - /// return this ExitCode from the `main` function, as demonstrated in the [type - /// documentation](#examples). + /// thread's stack will be run. Also see those docs for some important notes on interop with C + /// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from + /// the `main` function, as demonstrated in the [type documentation](#examples). /// /// # Differences from `process::exit()` /// @@ -2297,6 +2297,34 @@ impl Child { /// considered undesirable. Note that returning from `main` also calls `exit`, so making `exit` an /// unsafe operation is not an option.) /// +/// ## Safe interop with C code +/// +/// This function is safe to call as long as `exit` is only ever invoked from Rust. However, on some +/// platforms this function is implemented by calling the C function [`exit`][C-exit]. As of C23, +/// the C standard does not permit multiple threads to call `exit` concurrently. Rust mitigates this +/// with a lock, but if C code calls `exit`, that can still cause undefined behavior. Note that +/// returning from `main` is equivalent to calling `exit`. +/// +/// Therefore, it is undefined behavior to have two concurrent threads perform the following +/// without synchronization: +/// - One thread calls Rust's `exit` function or returns from Rust's `main` function +/// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function +/// +/// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining +/// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the +/// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C +/// code, and concurrent `exit` again causes undefined behavior. +/// +/// Individual C implementations might provide more guarantees than the standard and permit concurrent +/// calls to `exit`; consult the documentation of your C implementation for details. +/// +/// For some of the on-going discussion to make `exit` thread-safe in C, see: +/// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600) +/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845) +/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997) +/// +/// [C-exit]: https://en.cppreference.com/w/c/program/exit +/// /// ## Platform-specific behavior /// /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit` |
