libstd: remove some mutable statics in sys::unix

This commit is contained in:
Andy Russell 2020-07-03 14:13:22 -04:00
parent f844ea1e56
commit 792f2dedd7
No known key found for this signature in database
GPG key ID: BE2221033EDBC374
3 changed files with 33 additions and 26 deletions

View file

@ -78,19 +78,20 @@ mod imp {
use crate::marker::PhantomData; use crate::marker::PhantomData;
use crate::os::unix::prelude::*; use crate::os::unix::prelude::*;
use crate::ptr; use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
use crate::sys_common::mutex::Mutex; use crate::sys_common::mutex::Mutex;
static mut ARGC: isize = 0; static ARGC: AtomicIsize = AtomicIsize::new(0);
static mut ARGV: *const *const u8 = ptr::null(); static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
// We never call `ENV_LOCK.init()`, so it is UB to attempt to // We never call `ENV_LOCK.init()`, so it is UB to attempt to
// acquire this mutex reentrantly! // acquire this mutex reentrantly!
static LOCK: Mutex = Mutex::new(); static LOCK: Mutex = Mutex::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(); let _guard = LOCK.lock();
ARGC = argc; ARGC.store(argc, Ordering::Relaxed);
ARGV = argv; ARGV.store(argv as *mut _, Ordering::Relaxed);
} }
#[inline(always)] #[inline(always)]
@ -126,8 +127,8 @@ mod imp {
pub unsafe fn cleanup() { pub unsafe fn cleanup() {
let _guard = LOCK.lock(); let _guard = LOCK.lock();
ARGC = 0; ARGC.store(0, Ordering::Relaxed);
ARGV = ptr::null(); ARGV.store(ptr::null_mut(), Ordering::Relaxed);
} }
pub fn args() -> Args { pub fn args() -> Args {
@ -137,9 +138,11 @@ mod imp {
fn clone() -> Vec<OsString> { fn clone() -> Vec<OsString> {
unsafe { unsafe {
let _guard = LOCK.lock(); let _guard = LOCK.lock();
(0..ARGC) let argc = ARGC.load(Ordering::Relaxed);
let argv = ARGV.load(Ordering::Relaxed);
(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);
OsStringExt::from_vec(cstr.to_bytes().to_vec()) OsStringExt::from_vec(cstr.to_bytes().to_vec())
}) })
.collect() .collect()

View file

@ -48,6 +48,7 @@ mod imp {
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE}; use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV}; use libc::{MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE, SIGSEGV};
use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
use crate::sys::unix::os::page_size; use crate::sys::unix::os::page_size;
use crate::sys_common::thread_info; use crate::sys_common::thread_info;
@ -113,8 +114,8 @@ mod imp {
} }
} }
static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut(); static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());
static mut NEED_ALTSTACK: bool = false; static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);
pub unsafe fn init() { pub unsafe fn init() {
let mut action: sigaction = mem::zeroed(); let mut action: sigaction = mem::zeroed();
@ -125,17 +126,17 @@ mod imp {
action.sa_flags = SA_SIGINFO | SA_ONSTACK; action.sa_flags = SA_SIGINFO | SA_ONSTACK;
action.sa_sigaction = signal_handler as sighandler_t; action.sa_sigaction = signal_handler as sighandler_t;
sigaction(signal, &action, ptr::null_mut()); sigaction(signal, &action, ptr::null_mut());
NEED_ALTSTACK = true; NEED_ALTSTACK.store(true, Ordering::Relaxed);
} }
} }
let handler = make_handler(); let handler = make_handler();
MAIN_ALTSTACK = handler._data; MAIN_ALTSTACK.store(handler._data, Ordering::Relaxed);
mem::forget(handler); mem::forget(handler);
} }
pub unsafe fn cleanup() { pub unsafe fn cleanup() {
Handler { _data: MAIN_ALTSTACK }; Handler { _data: MAIN_ALTSTACK.load(Ordering::Relaxed) };
} }
unsafe fn get_stackp() -> *mut libc::c_void { unsafe fn get_stackp() -> *mut libc::c_void {
@ -176,7 +177,7 @@ mod imp {
} }
pub unsafe fn make_handler() -> Handler { pub unsafe fn make_handler() -> Handler {
if !NEED_ALTSTACK { if !NEED_ALTSTACK.load(Ordering::Relaxed) {
return Handler::null(); return Handler::null();
} }
let mut stack = mem::zeroed(); let mut stack = mem::zeroed();

View file

@ -246,10 +246,11 @@ pub mod guard {
use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE}; use libc::{MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
use crate::ops::Range; use crate::ops::Range;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sys::os; use crate::sys::os;
// This is initialized in init() and only read from after // This is initialized in init() and only read from after
static mut PAGE_SIZE: usize = 0; static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
pub type Guard = Range<usize>; pub type Guard = Range<usize>;
@ -275,7 +276,7 @@ pub mod guard {
let stackaddr = if libc::pthread_main_np() == 1 { let stackaddr = if libc::pthread_main_np() == 1 {
// main thread // main thread
current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE.load(Ordering::Relaxed)
} else { } else {
// new thread // new thread
current_stack.ss_sp as usize - current_stack.ss_size current_stack.ss_sp as usize - current_stack.ss_size
@ -310,7 +311,8 @@ pub mod guard {
// Precondition: PAGE_SIZE is initialized. // Precondition: PAGE_SIZE is initialized.
unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> { unsafe fn get_stack_start_aligned() -> Option<*mut libc::c_void> {
assert!(PAGE_SIZE != 0); let page_size = PAGE_SIZE.load(Ordering::Relaxed);
assert!(page_size != 0);
let stackaddr = get_stack_start()?; let stackaddr = get_stack_start()?;
// Ensure stackaddr is page aligned! A parent process might // Ensure stackaddr is page aligned! A parent process might
@ -319,16 +321,17 @@ pub mod guard {
// stackaddr < stackaddr + stacksize, so if stackaddr is not // stackaddr < stackaddr + stacksize, so if stackaddr is not
// page-aligned, calculate the fix such that stackaddr < // page-aligned, calculate the fix such that stackaddr <
// new_page_aligned_stackaddr < stackaddr + stacksize // new_page_aligned_stackaddr < stackaddr + stacksize
let remainder = (stackaddr as usize) % PAGE_SIZE; let remainder = (stackaddr as usize) % page_size;
Some(if remainder == 0 { Some(if remainder == 0 {
stackaddr stackaddr
} else { } else {
((stackaddr as usize) + PAGE_SIZE - remainder) as *mut libc::c_void ((stackaddr as usize) + page_size - remainder) as *mut libc::c_void
}) })
} }
pub unsafe fn init() -> Option<Guard> { pub unsafe fn init() -> Option<Guard> {
PAGE_SIZE = os::page_size(); let page_size = os::page_size();
PAGE_SIZE.store(page_size, Ordering::Relaxed);
let stackaddr = get_stack_start_aligned()?; let stackaddr = get_stack_start_aligned()?;
@ -344,7 +347,7 @@ pub mod guard {
// faulting, so our handler can report "stack overflow", and // faulting, so our handler can report "stack overflow", and
// trust that the kernel's own stack guard will work. // trust that the kernel's own stack guard will work.
let stackaddr = stackaddr as usize; let stackaddr = stackaddr as usize;
Some(stackaddr - PAGE_SIZE..stackaddr) Some(stackaddr - page_size..stackaddr)
} else { } else {
// Reallocate the last page of the stack. // Reallocate the last page of the stack.
// This ensures SIGBUS will be raised on // This ensures SIGBUS will be raised on
@ -356,7 +359,7 @@ pub mod guard {
// no permissions at all. See issue #50313. // no permissions at all. See issue #50313.
let result = mmap( let result = mmap(
stackaddr, stackaddr,
PAGE_SIZE, page_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED, MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-1, -1,
@ -366,7 +369,7 @@ pub mod guard {
panic!("failed to allocate a guard page"); panic!("failed to allocate a guard page");
} }
let result = mprotect(stackaddr, PAGE_SIZE, PROT_NONE); let result = mprotect(stackaddr, page_size, PROT_NONE);
if result != 0 { if result != 0 {
panic!("failed to protect the guard page"); panic!("failed to protect the guard page");
} }
@ -374,14 +377,14 @@ pub mod guard {
let guardaddr = stackaddr as usize; let guardaddr = stackaddr as usize;
let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 }; let offset = if cfg!(target_os = "freebsd") { 2 } else { 1 };
Some(guardaddr..guardaddr + offset * PAGE_SIZE) Some(guardaddr..guardaddr + offset * page_size)
} }
} }
#[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))] #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
pub unsafe fn current() -> Option<Guard> { pub unsafe fn current() -> Option<Guard> {
let stackaddr = get_stack_start()? as usize; let stackaddr = get_stack_start()? as usize;
Some(stackaddr - PAGE_SIZE..stackaddr) Some(stackaddr - PAGE_SIZE.load(Ordering::Relaxed)..stackaddr)
} }
#[cfg(any( #[cfg(any(
@ -413,7 +416,7 @@ pub mod guard {
ret = if cfg!(target_os = "freebsd") { ret = if cfg!(target_os = "freebsd") {
// FIXME does freebsd really fault *below* the guard addr? // FIXME does freebsd really fault *below* the guard addr?
let guardaddr = stackaddr - guardsize; let guardaddr = stackaddr - guardsize;
Some(guardaddr - PAGE_SIZE..guardaddr) Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr)
} else if cfg!(target_os = "netbsd") { } else if cfg!(target_os = "netbsd") {
Some(stackaddr - guardsize..stackaddr) Some(stackaddr - guardsize..stackaddr)
} else if cfg!(all(target_os = "linux", target_env = "gnu")) { } else if cfg!(all(target_os = "linux", target_env = "gnu")) {