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::os::unix::prelude::*;
use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
use crate::sys_common::mutex::Mutex;
static mut ARGC: isize = 0;
static mut ARGV: *const *const u8 = ptr::null();
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: Mutex = Mutex::new();
unsafe fn really_init(argc: isize, argv: *const *const u8) {
let _guard = LOCK.lock();
ARGC = argc;
ARGV = argv;
ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed);
}
#[inline(always)]
@ -126,8 +127,8 @@ mod imp {
pub unsafe fn cleanup() {
let _guard = LOCK.lock();
ARGC = 0;
ARGV = ptr::null();
ARGC.store(0, Ordering::Relaxed);
ARGV.store(ptr::null_mut(), Ordering::Relaxed);
}
pub fn args() -> Args {
@ -137,9 +138,11 @@ mod imp {
fn clone() -> Vec<OsString> {
unsafe {
let _guard = LOCK.lock();
(0..ARGC)
let argc = ARGC.load(Ordering::Relaxed);
let argv = ARGV.load(Ordering::Relaxed);
(0..argc)
.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())
})
.collect()

View file

@ -48,6 +48,7 @@ mod imp {
use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
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_common::thread_info;
@ -113,8 +114,8 @@ mod imp {
}
}
static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
static mut NEED_ALTSTACK: bool = false;
static MAIN_ALTSTACK: AtomicPtr<libc::c_void> = AtomicPtr::new(ptr::null_mut());
static NEED_ALTSTACK: AtomicBool = AtomicBool::new(false);
pub unsafe fn init() {
let mut action: sigaction = mem::zeroed();
@ -125,17 +126,17 @@ mod imp {
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
action.sa_sigaction = signal_handler as sighandler_t;
sigaction(signal, &action, ptr::null_mut());
NEED_ALTSTACK = true;
NEED_ALTSTACK.store(true, Ordering::Relaxed);
}
}
let handler = make_handler();
MAIN_ALTSTACK = handler._data;
MAIN_ALTSTACK.store(handler._data, Ordering::Relaxed);
mem::forget(handler);
}
pub unsafe fn cleanup() {
Handler { _data: MAIN_ALTSTACK };
Handler { _data: MAIN_ALTSTACK.load(Ordering::Relaxed) };
}
unsafe fn get_stackp() -> *mut libc::c_void {
@ -176,7 +177,7 @@ mod imp {
}
pub unsafe fn make_handler() -> Handler {
if !NEED_ALTSTACK {
if !NEED_ALTSTACK.load(Ordering::Relaxed) {
return Handler::null();
}
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 crate::ops::Range;
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sys::os;
// 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>;
@ -275,7 +276,7 @@ pub mod guard {
let stackaddr = if libc::pthread_main_np() == 1 {
// 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 {
// new thread
current_stack.ss_sp as usize - current_stack.ss_size
@ -310,7 +311,8 @@ pub mod guard {
// Precondition: PAGE_SIZE is initialized.
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()?;
// Ensure stackaddr is page aligned! A parent process might
@ -319,16 +321,17 @@ pub mod guard {
// stackaddr < stackaddr + stacksize, so if stackaddr is not
// page-aligned, calculate the fix such that stackaddr <
// new_page_aligned_stackaddr < stackaddr + stacksize
let remainder = (stackaddr as usize) % PAGE_SIZE;
let remainder = (stackaddr as usize) % page_size;
Some(if remainder == 0 {
stackaddr
} 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> {
PAGE_SIZE = os::page_size();
let page_size = os::page_size();
PAGE_SIZE.store(page_size, Ordering::Relaxed);
let stackaddr = get_stack_start_aligned()?;
@ -344,7 +347,7 @@ pub mod guard {
// faulting, so our handler can report "stack overflow", and
// trust that the kernel's own stack guard will work.
let stackaddr = stackaddr as usize;
Some(stackaddr - PAGE_SIZE..stackaddr)
Some(stackaddr - page_size..stackaddr)
} else {
// Reallocate the last page of the stack.
// This ensures SIGBUS will be raised on
@ -356,7 +359,7 @@ pub mod guard {
// no permissions at all. See issue #50313.
let result = mmap(
stackaddr,
PAGE_SIZE,
page_size,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON | MAP_FIXED,
-1,
@ -366,7 +369,7 @@ pub mod guard {
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 {
panic!("failed to protect the guard page");
}
@ -374,14 +377,14 @@ pub mod guard {
let guardaddr = stackaddr as usize;
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"))]
pub unsafe fn current() -> Option<Guard> {
let stackaddr = get_stack_start()? as usize;
Some(stackaddr - PAGE_SIZE..stackaddr)
Some(stackaddr - PAGE_SIZE.load(Ordering::Relaxed)..stackaddr)
}
#[cfg(any(
@ -413,7 +416,7 @@ pub mod guard {
ret = if cfg!(target_os = "freebsd") {
// FIXME does freebsd really fault *below* the guard addr?
let guardaddr = stackaddr - guardsize;
Some(guardaddr - PAGE_SIZE..guardaddr)
Some(guardaddr - PAGE_SIZE.load(Ordering::Relaxed)..guardaddr)
} else if cfg!(target_os = "netbsd") {
Some(stackaddr - guardsize..stackaddr)
} else if cfg!(all(target_os = "linux", target_env = "gnu")) {