// Copyright 2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![allow(dead_code)] // not used on all platforms use collections::BTreeMap; use ptr; use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; pub type Key = usize; type Dtor = unsafe extern fn(*mut u8); static NEXT_KEY: AtomicUsize = ATOMIC_USIZE_INIT; static mut KEYS: *mut BTreeMap> = ptr::null_mut(); #[thread_local] static mut LOCALS: *mut BTreeMap = ptr::null_mut(); unsafe fn keys() -> &'static mut BTreeMap> { if KEYS == ptr::null_mut() { KEYS = Box::into_raw(Box::new(BTreeMap::new())); } &mut *KEYS } unsafe fn locals() -> &'static mut BTreeMap { if LOCALS == ptr::null_mut() { LOCALS = Box::into_raw(Box::new(BTreeMap::new())); } &mut *LOCALS } #[inline] pub unsafe fn create(dtor: Option) -> Key { let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst); keys().insert(key, dtor); key } #[inline] pub unsafe fn get(key: Key) -> *mut u8 { if let Some(&entry) = locals().get(&key) { entry } else { ptr::null_mut() } } #[inline] pub unsafe fn set(key: Key, value: *mut u8) { locals().insert(key, value); } #[inline] pub unsafe fn destroy(key: Key) { keys().remove(&key); } #[inline] pub fn requires_synchronized_create() -> bool { false }