about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDan Gohman <dev@sunfishcode.online>2021-07-17 12:33:31 -0700
committerDan Gohman <dev@sunfishcode.online>2021-07-17 13:35:38 -0700
commit9bb11ba51135b0398b5a8b9feca24149d96fa5e8 (patch)
tree06c9d5764401c31d6aab9d83736e54987dee7dab
parent46010c4618d4602cd6999c613fce7081fad438c2 (diff)
downloadrust-9bb11ba51135b0398b5a8b9feca24149d96fa5e8.tar.gz
rust-9bb11ba51135b0398b5a8b9feca24149d96fa5e8.zip
Remove an unnecessary `Mutex` around argument initialization.
In the command-line argument initialization code, remove the Mutex
around the `ARGV` and `ARGC` variables, and simply check whether
ARGV is non-null before dereferencing it. This way, if either of
ARGV or ARGC is not initialized, we'll get an empty argument list.

This allows simple cdylibs to avoid having
`pthread_mutex_lock`/`pthread_mutex_unlock` appear in their symbol
tables if they don't otherwise use threads.
-rw-r--r--library/std/src/sys/unix/args.rs15
1 files changed, 7 insertions, 8 deletions
diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs
index d9e3c29f36b..a6480199e70 100644
--- a/library/std/src/sys/unix/args.rs
+++ b/library/std/src/sys/unix/args.rs
@@ -77,16 +77,10 @@ mod imp {
     use crate::ptr;
     use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
 
-    use crate::sys_common::mutex::StaticMutex;
-
     static ARGC: AtomicIsize = AtomicIsize::new(0);
     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) {
-        let _guard = LOCK.lock();
         ARGC.store(argc, Ordering::Relaxed);
         ARGV.store(argv as *mut _, Ordering::Relaxed);
     }
@@ -128,9 +122,14 @@ mod imp {
 
     fn clone() -> Vec<OsString> {
         unsafe {
-            let _guard = LOCK.lock();
-            let argc = ARGC.load(Ordering::Relaxed);
+            // 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.
             let argv = ARGV.load(Ordering::Relaxed);
+            let argc = if argv.is_null() {
+                0
+            } else {
+                ARGC.load(Ordering::Relaxed)
+            };
             (0..argc)
                 .map(|i| {
                     let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);