Add comments explaining the unix command-line argument support.

Following up on #87236, add comments to the unix command-line argument
support explaining that the code doesn't mutate the system-provided
argc/argv, and that this is why the code doesn't need a lock or special
memory ordering.
This commit is contained in:
Dan Gohman 2021-07-19 07:06:42 -07:00
parent 8df945c471
commit 2a56a681c4

View File

@ -77,10 +77,18 @@ mod imp {
use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
// The system-provided argc and argv, which we store in static memory
// here so that we can defer the work of parsing them until its actually
// needed.
//
// Note that we never mutate argv/argc, the argv array, or the argv
// strings, which allows the code in this file to be very simple.
static ARGC: AtomicIsize = AtomicIsize::new(0);
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
unsafe fn really_init(argc: isize, argv: *const *const u8) {
// These don't need to be ordered with each other or other stores,
// because they only hold the unmodified system-provide argv/argc.
ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed);
}
@ -122,8 +130,14 @@ mod imp {
fn clone() -> Vec<OsString> {
unsafe {
// Load ARGC and ARGV without a lock. If the store to either ARGV or
// ARGC isn't visible yet, we'll return an empty argument list.
// Load ARGC and ARGV, which hold the unmodified system-provided
// argc/argv, so we can read the pointed-to memory without atomics
// or synchronization.
//
// If either ARGC or ARGV is still zero or null, then either there
// really are no arguments, or someone is asking for `args()`
// before initialization has completed, and we return an empty
// list.
let argv = ARGV.load(Ordering::Relaxed);
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
(0..argc)