Skip to content

Commit 6df9df7

Browse files
Rollup merge of rust-lang#87236 - sunfishcode:avoid-locking-args, r=joshtriplett
Simplify command-line argument initialization on unix Simplify Rust's command-line argument initialization code on unix: - The cleanup code isn't needed, because it was just zeroing out non-owning variables at runtime cleanup time. After 91c3eee, Rust's command-line initialization code on unix no longer allocates `CString`s and a `Vec` at startup time. - The `Mutex` isn't needed; if there's somehow a call to `args()` before argument initialization has happened, the code returns return an empty list, which we can do with a null check. With these changes, a simple cdylib that doesn't use threads avoids getting `pthread_mutex_lock`/`pthread_mutex_unlock` in its symbol table.
2 parents 65b7aa9 + c3df0ae commit 6df9df7

File tree

2 files changed

+3
-22
lines changed

2 files changed

+3
-22
lines changed

library/std/src/sys/unix/args.rs

+3-21
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
1414
imp::init(argc, argv)
1515
}
1616

17-
/// One-time global cleanup.
18-
pub unsafe fn cleanup() {
19-
imp::cleanup()
20-
}
21-
2217
/// Returns the command line arguments
2318
pub fn args() -> Args {
2419
imp::args()
@@ -82,16 +77,10 @@ mod imp {
8277
use crate::ptr;
8378
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
8479

85-
use crate::sys_common::mutex::StaticMutex;
86-
8780
static ARGC: AtomicIsize = AtomicIsize::new(0);
8881
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
89-
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
90-
// acquire this mutex reentrantly!
91-
static LOCK: StaticMutex = StaticMutex::new();
9282

9383
unsafe fn really_init(argc: isize, argv: *const *const u8) {
94-
let _guard = LOCK.lock();
9584
ARGC.store(argc, Ordering::Relaxed);
9685
ARGV.store(argv as *mut _, Ordering::Relaxed);
9786
}
@@ -127,21 +116,16 @@ mod imp {
127116
init_wrapper
128117
};
129118

130-
pub unsafe fn cleanup() {
131-
let _guard = LOCK.lock();
132-
ARGC.store(0, Ordering::Relaxed);
133-
ARGV.store(ptr::null_mut(), Ordering::Relaxed);
134-
}
135-
136119
pub fn args() -> Args {
137120
Args { iter: clone().into_iter() }
138121
}
139122

140123
fn clone() -> Vec<OsString> {
141124
unsafe {
142-
let _guard = LOCK.lock();
143-
let argc = ARGC.load(Ordering::Relaxed);
125+
// Load ARGC and ARGV without a lock. If the store to either ARGV or
126+
// ARGC isn't visible yet, we'll return an empty argument list.
144127
let argv = ARGV.load(Ordering::Relaxed);
128+
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
145129
(0..argc)
146130
.map(|i| {
147131
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
@@ -159,8 +143,6 @@ mod imp {
159143

160144
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
161145

162-
pub fn cleanup() {}
163-
164146
#[cfg(target_os = "macos")]
165147
pub fn args() -> Args {
166148
use crate::os::unix::prelude::*;

library/std/src/sys/unix/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
123123
// SAFETY: must be called only once during runtime cleanup.
124124
// NOTE: this is not guaranteed to run, for example when the program aborts.
125125
pub unsafe fn cleanup() {
126-
args::cleanup();
127126
stack_overflow::cleanup();
128127
}
129128

0 commit comments

Comments
 (0)