std: Convert the runtime TLS key to a Rust global to avoid FFI
This commit is contained in:
parent
a37bdde3f9
commit
8fc1d9db21
@ -23,14 +23,16 @@ use option::{Option, Some, None};
|
||||
use unstable::finally::Finally;
|
||||
use tls = rt::thread_local_storage;
|
||||
|
||||
static mut RT_TLS_KEY: tls::Key = -1;
|
||||
|
||||
/// Initialize the TLS key. Other ops will fail if this isn't executed first.
|
||||
#[fixed_stack_segment]
|
||||
#[inline(never)]
|
||||
pub fn init_tls_key() {
|
||||
unsafe {
|
||||
rust_initialize_rt_tls_key();
|
||||
rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
|
||||
extern {
|
||||
fn rust_initialize_rt_tls_key();
|
||||
fn rust_initialize_rt_tls_key(key: *mut tls::Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,15 +153,10 @@ fn tls_key() -> tls::Key {
|
||||
}
|
||||
}
|
||||
|
||||
#[fixed_stack_segment]
|
||||
#[inline(never)]
|
||||
fn maybe_tls_key() -> Option<tls::Key> {
|
||||
#[inline]
|
||||
#[cfg(not(test))]
|
||||
pub fn maybe_tls_key() -> Option<tls::Key> {
|
||||
unsafe {
|
||||
let key: *mut c_void = rust_get_rt_tls_key();
|
||||
let key: &mut tls::Key = cast::transmute(key);
|
||||
let key = *key;
|
||||
// Check that the key has been initialized.
|
||||
|
||||
// NB: This is a little racy because, while the key is
|
||||
// initalized under a mutex and it's assumed to be initalized
|
||||
// in the Scheduler ctor by any thread that needs to use it,
|
||||
@ -170,14 +167,19 @@ fn maybe_tls_key() -> Option<tls::Key> {
|
||||
// another thread. I think this is fine since the only action
|
||||
// they could take if it was initialized would be to check the
|
||||
// thread-local value and see that it's not set.
|
||||
if key != -1 {
|
||||
return Some(key);
|
||||
if RT_TLS_KEY != -1 {
|
||||
return Some(RT_TLS_KEY);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern {
|
||||
fn rust_get_rt_tls_key() -> *mut c_void;
|
||||
}
|
||||
// XXX: The boundary between the running runtime and the testing runtime
|
||||
// seems to be fuzzy at the moment, and trying to use two different keys
|
||||
// results in disaster. This should not be necessary.
|
||||
#[inline]
|
||||
#[cfg(test)]
|
||||
pub fn maybe_tls_key() -> Option<tls::Key> {
|
||||
unsafe { ::cast::transmute(::realstd::rt::local_ptr::maybe_tls_key()) }
|
||||
}
|
||||
|
@ -447,19 +447,14 @@ rust_readdir() {
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
pthread_key_t rt_key = -1;
|
||||
typedef pthread_key_t tls_key;
|
||||
#else
|
||||
DWORD rt_key = -1;
|
||||
typedef DWORD tls_key;
|
||||
#endif
|
||||
|
||||
extern "C" void*
|
||||
rust_get_rt_tls_key() {
|
||||
return &rt_key;
|
||||
}
|
||||
|
||||
// Initialize the TLS key used by the new scheduler
|
||||
extern "C" CDECL void
|
||||
rust_initialize_rt_tls_key() {
|
||||
rust_initialize_rt_tls_key(tls_key *key) {
|
||||
|
||||
static lock_and_signal init_lock;
|
||||
static bool initialized = false;
|
||||
@ -469,10 +464,10 @@ rust_initialize_rt_tls_key() {
|
||||
if (!initialized) {
|
||||
|
||||
#ifndef _WIN32
|
||||
assert(!pthread_key_create(&rt_key, NULL));
|
||||
assert(!pthread_key_create(key, NULL));
|
||||
#else
|
||||
rt_key = TlsAlloc();
|
||||
assert(rt_key != TLS_OUT_OF_INDEXES);
|
||||
*key = TlsAlloc();
|
||||
assert(*key != TLS_OUT_OF_INDEXES);
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
|
@ -143,7 +143,6 @@ linenoiseHistoryLoad
|
||||
rust_raw_thread_start
|
||||
rust_raw_thread_join
|
||||
rust_raw_thread_delete
|
||||
rust_get_rt_tls_key
|
||||
swap_registers
|
||||
rust_readdir
|
||||
rust_opendir
|
||||
|
Loading…
Reference in New Issue
Block a user