diff --git a/src/lib.rs b/src/lib.rs index 2283261..12d25f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -190,7 +190,7 @@ impl ThreadLocal { /// Returns the element for the current thread, if it exists. pub fn get(&self) -> Option<&T> { - thread_id::try_get().and_then(|thread| self.get_inner(thread)) + self.get_inner(thread_id::get()) } /// Returns the element for the current thread, or creates it if it doesn't @@ -212,12 +212,11 @@ impl ThreadLocal { where F: FnOnce() -> Result, { - let thread = thread_id::try_get(); - if let Some(thread) = thread { - if let Some(val) = self.get_inner(thread) { - return Ok(val); - } + let thread = thread_id::get(); + if let Some(val) = self.get_inner(thread) { + return Ok(val); } + Ok(self.insert(create()?)) } diff --git a/src/thread_id.rs b/src/thread_id.rs index d04a45b..54bb84a 100644 --- a/src/thread_id.rs +++ b/src/thread_id.rs @@ -97,29 +97,26 @@ cfg_if::cfg_if! { } } - /// Attempts to get the current thread if `get` has previously been - /// called. - #[inline] - pub(crate) fn try_get() -> Option { - unsafe { - THREAD - } - } - /// Returns a thread ID for the current thread, allocating one if needed. #[inline] pub(crate) fn get() -> Thread { if let Some(thread) = unsafe { THREAD } { thread } else { - let new = Thread::new(THREAD_ID_MANAGER.lock().unwrap().alloc()); - unsafe { - THREAD = Some(new); - } - THREAD_GUARD.with(|_| {}); - new + get_slow() } } + + /// Out-of-line slow path for allocating a thread ID. + #[cold] + fn get_slow() -> Thread { + let new = Thread::new(THREAD_ID_MANAGER.lock().unwrap().alloc()); + unsafe { + THREAD = Some(new); + } + THREAD_GUARD.with(|_| {}); + new + } } else { use std::cell::Cell; @@ -140,13 +137,6 @@ cfg_if::cfg_if! { } } - /// Attempts to get the current thread if `get` has previously been - /// called. - #[inline] - pub(crate) fn try_get() -> Option { - THREAD.with(|thread| thread.get()) - } - /// Returns a thread ID for the current thread, allocating one if needed. #[inline] pub(crate) fn get() -> Thread { @@ -154,13 +144,19 @@ cfg_if::cfg_if! { if let Some(thread) = thread.get() { thread } else { - let new = Thread::new(THREAD_ID_MANAGER.lock().unwrap().alloc()); - thread.set(Some(new)); - THREAD_GUARD.with(|_| {}); - new + get_slow(thread) } }) } + + /// Out-of-line slow path for allocating a thread ID. + #[cold] + fn get_slow(thread: &Cell>) -> Thread { + let new = Thread::new(THREAD_ID_MANAGER.lock().unwrap().alloc()); + thread.set(Some(new)); + THREAD_GUARD.with(|_| {}); + new + } } }