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 unstable::finally::Finally;
|
||||||
use tls = rt::thread_local_storage;
|
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.
|
/// Initialize the TLS key. Other ops will fail if this isn't executed first.
|
||||||
#[fixed_stack_segment]
|
#[fixed_stack_segment]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn init_tls_key() {
|
pub fn init_tls_key() {
|
||||||
unsafe {
|
unsafe {
|
||||||
rust_initialize_rt_tls_key();
|
rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
|
||||||
extern {
|
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]
|
||||||
#[inline(never)]
|
#[cfg(not(test))]
|
||||||
fn maybe_tls_key() -> Option<tls::Key> {
|
pub fn maybe_tls_key() -> Option<tls::Key> {
|
||||||
unsafe {
|
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
|
// NB: This is a little racy because, while the key is
|
||||||
// initalized under a mutex and it's assumed to be initalized
|
// initalized under a mutex and it's assumed to be initalized
|
||||||
// in the Scheduler ctor by any thread that needs to use it,
|
// 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
|
// another thread. I think this is fine since the only action
|
||||||
// they could take if it was initialized would be to check the
|
// they could take if it was initialized would be to check the
|
||||||
// thread-local value and see that it's not set.
|
// thread-local value and see that it's not set.
|
||||||
if key != -1 {
|
if RT_TLS_KEY != -1 {
|
||||||
return Some(key);
|
return Some(RT_TLS_KEY);
|
||||||
} else {
|
} else {
|
||||||
return None;
|
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
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pthread_key_t rt_key = -1;
|
typedef pthread_key_t tls_key;
|
||||||
#else
|
#else
|
||||||
DWORD rt_key = -1;
|
typedef DWORD tls_key;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" void*
|
|
||||||
rust_get_rt_tls_key() {
|
|
||||||
return &rt_key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the TLS key used by the new scheduler
|
// Initialize the TLS key used by the new scheduler
|
||||||
extern "C" CDECL void
|
extern "C" CDECL void
|
||||||
rust_initialize_rt_tls_key() {
|
rust_initialize_rt_tls_key(tls_key *key) {
|
||||||
|
|
||||||
static lock_and_signal init_lock;
|
static lock_and_signal init_lock;
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
@ -469,10 +464,10 @@ rust_initialize_rt_tls_key() {
|
|||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
assert(!pthread_key_create(&rt_key, NULL));
|
assert(!pthread_key_create(key, NULL));
|
||||||
#else
|
#else
|
||||||
rt_key = TlsAlloc();
|
*key = TlsAlloc();
|
||||||
assert(rt_key != TLS_OUT_OF_INDEXES);
|
assert(*key != TLS_OUT_OF_INDEXES);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
@ -143,7 +143,6 @@ linenoiseHistoryLoad
|
|||||||
rust_raw_thread_start
|
rust_raw_thread_start
|
||||||
rust_raw_thread_join
|
rust_raw_thread_join
|
||||||
rust_raw_thread_delete
|
rust_raw_thread_delete
|
||||||
rust_get_rt_tls_key
|
|
||||||
swap_registers
|
swap_registers
|
||||||
rust_readdir
|
rust_readdir
|
||||||
rust_opendir
|
rust_opendir
|
||||||
|
Loading…
Reference in New Issue
Block a user