Rollup merge of #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 91c3eee173
, 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.
This commit is contained in:
commit
6df9df7e36
2 changed files with 3 additions and 22 deletions
|
@ -14,11 +14,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||||
imp::init(argc, argv)
|
imp::init(argc, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// One-time global cleanup.
|
|
||||||
pub unsafe fn cleanup() {
|
|
||||||
imp::cleanup()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the command line arguments
|
/// Returns the command line arguments
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
imp::args()
|
imp::args()
|
||||||
|
@ -82,16 +77,10 @@ mod imp {
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
|
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
|
||||||
|
|
||||||
use crate::sys_common::mutex::StaticMutex;
|
|
||||||
|
|
||||||
static ARGC: AtomicIsize = AtomicIsize::new(0);
|
static ARGC: AtomicIsize = AtomicIsize::new(0);
|
||||||
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
|
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
|
||||||
// We never call `ENV_LOCK.init()`, so it is UB to attempt to
|
|
||||||
// acquire this mutex reentrantly!
|
|
||||||
static LOCK: StaticMutex = StaticMutex::new();
|
|
||||||
|
|
||||||
unsafe fn really_init(argc: isize, argv: *const *const u8) {
|
unsafe fn really_init(argc: isize, argv: *const *const u8) {
|
||||||
let _guard = LOCK.lock();
|
|
||||||
ARGC.store(argc, Ordering::Relaxed);
|
ARGC.store(argc, Ordering::Relaxed);
|
||||||
ARGV.store(argv as *mut _, Ordering::Relaxed);
|
ARGV.store(argv as *mut _, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
@ -127,21 +116,16 @@ mod imp {
|
||||||
init_wrapper
|
init_wrapper
|
||||||
};
|
};
|
||||||
|
|
||||||
pub unsafe fn cleanup() {
|
|
||||||
let _guard = LOCK.lock();
|
|
||||||
ARGC.store(0, Ordering::Relaxed);
|
|
||||||
ARGV.store(ptr::null_mut(), Ordering::Relaxed);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
Args { iter: clone().into_iter() }
|
Args { iter: clone().into_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone() -> Vec<OsString> {
|
fn clone() -> Vec<OsString> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _guard = LOCK.lock();
|
// Load ARGC and ARGV without a lock. If the store to either ARGV or
|
||||||
let argc = ARGC.load(Ordering::Relaxed);
|
// ARGC isn't visible yet, we'll return an empty argument list.
|
||||||
let argv = ARGV.load(Ordering::Relaxed);
|
let argv = ARGV.load(Ordering::Relaxed);
|
||||||
|
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
|
||||||
(0..argc)
|
(0..argc)
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
|
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
|
||||||
|
@ -159,8 +143,6 @@ mod imp {
|
||||||
|
|
||||||
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
|
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {}
|
||||||
|
|
||||||
pub fn cleanup() {}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
use crate::os::unix::prelude::*;
|
use crate::os::unix::prelude::*;
|
||||||
|
|
|
@ -123,7 +123,6 @@ pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
||||||
// SAFETY: must be called only once during runtime cleanup.
|
// SAFETY: must be called only once during runtime cleanup.
|
||||||
// NOTE: this is not guaranteed to run, for example when the program aborts.
|
// NOTE: this is not guaranteed to run, for example when the program aborts.
|
||||||
pub unsafe fn cleanup() {
|
pub unsafe fn cleanup() {
|
||||||
args::cleanup();
|
|
||||||
stack_overflow::cleanup();
|
stack_overflow::cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue