core: Use a global lock instead of runtime lock for os::getenv, etc. #4726
This commit is contained in:
parent
36ad366519
commit
f6401bad24
@ -147,23 +147,25 @@ pub mod win32 {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Accessing environment variables is not generally threadsafe.
|
Accessing environment variables is not generally threadsafe.
|
||||||
This uses a per-runtime lock to serialize access.
|
Serialize access through a global lock.
|
||||||
FIXME #4726: It would probably be appropriate to make this a real global
|
|
||||||
*/
|
*/
|
||||||
fn with_env_lock<T>(f: &fn() -> T) -> T {
|
fn with_env_lock<T>(f: &fn() -> T) -> T {
|
||||||
use unstable::global::global_data_clone_create;
|
use unstable::finally::Finally;
|
||||||
use unstable::sync::{Exclusive, exclusive};
|
|
||||||
|
|
||||||
struct SharedValue(());
|
|
||||||
type ValueMutex = Exclusive<SharedValue>;
|
|
||||||
fn key(_: ValueMutex) { }
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let lock: ValueMutex = global_data_clone_create(key, || {
|
return do (|| {
|
||||||
~exclusive(SharedValue(()))
|
rust_take_env_lock();
|
||||||
});
|
f()
|
||||||
|
}).finally {
|
||||||
|
rust_drop_env_lock();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
lock.with_imm(|_| f() )
|
extern {
|
||||||
|
#[fast_ffi]
|
||||||
|
fn rust_take_env_lock();
|
||||||
|
#[fast_ffi]
|
||||||
|
fn rust_drop_env_lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 97ac7c087a0caf6b0f611b80e14f7fe3cb18bb27
|
Subproject commit 218ab86721eefd7b7e97fa6d9f95a80a1fa8686c
|
@ -13,6 +13,7 @@
|
|||||||
// that might come from the environment is loaded here, once, during
|
// that might come from the environment is loaded here, once, during
|
||||||
// init.
|
// init.
|
||||||
|
|
||||||
|
#include "sync/lock_and_signal.h"
|
||||||
#include "rust_env.h"
|
#include "rust_env.h"
|
||||||
|
|
||||||
// The environment variables that the runtime knows about
|
// The environment variables that the runtime knows about
|
||||||
@ -26,6 +27,18 @@
|
|||||||
#define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
|
#define RUST_DEBUG_MEM "RUST_DEBUG_MEM"
|
||||||
#define RUST_DEBUG_BORROW "RUST_DEBUG_BORROW"
|
#define RUST_DEBUG_BORROW "RUST_DEBUG_BORROW"
|
||||||
|
|
||||||
|
static lock_and_signal env_lock;
|
||||||
|
|
||||||
|
extern "C" CDECL void
|
||||||
|
rust_take_env_lock() {
|
||||||
|
env_lock.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" CDECL void
|
||||||
|
rust_drop_env_lock() {
|
||||||
|
env_lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
static int
|
static int
|
||||||
get_num_cpus() {
|
get_num_cpus() {
|
||||||
@ -119,6 +132,8 @@ copyenv(const char* name) {
|
|||||||
|
|
||||||
rust_env*
|
rust_env*
|
||||||
load_env(int argc, char **argv) {
|
load_env(int argc, char **argv) {
|
||||||
|
scoped_lock with(env_lock);
|
||||||
|
|
||||||
rust_env *env = (rust_env*)malloc(sizeof(rust_env));
|
rust_env *env = (rust_env*)malloc(sizeof(rust_env));
|
||||||
|
|
||||||
env->num_sched_threads = (size_t)get_num_threads();
|
env->num_sched_threads = (size_t)get_num_threads();
|
||||||
@ -141,3 +156,4 @@ free_env(rust_env *env) {
|
|||||||
free(env->rust_seed);
|
free(env->rust_seed);
|
||||||
free(env);
|
free(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,4 +235,7 @@ rust_begin_unwind
|
|||||||
rust_take_task_borrow_list
|
rust_take_task_borrow_list
|
||||||
rust_set_task_borrow_list
|
rust_set_task_borrow_list
|
||||||
rust_valgrind_stack_register
|
rust_valgrind_stack_register
|
||||||
rust_valgrind_stack_deregister
|
rust_valgrind_stack_deregister
|
||||||
|
rust_take_env_lock
|
||||||
|
rust_drop_env_lock
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user