From 5bd834bdb4e2c1fe6666be8c8fad41526d72e3d1 Mon Sep 17 00:00:00 2001 From: "Stephen M. Coakley" Date: Wed, 7 Sep 2016 23:48:07 -0500 Subject: [PATCH] Add ThreadId for comparing threads --- src/libstd/thread/mod.rs | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index d8e021bb04ff..97a277e7bb49 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -165,6 +165,7 @@ use panic; use panicking; use str; use sync::{Mutex, Condvar, Arc}; +use sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use sys::thread as imp; use sys_common::thread_info; use sys_common::util; @@ -524,6 +525,35 @@ pub fn park_timeout(dur: Duration) { *guard = false; } +//////////////////////////////////////////////////////////////////////////////// +// ThreadId +//////////////////////////////////////////////////////////////////////////////// + +/// A unique identifier for a running thread. +/// +/// A `ThreadId` is an opaque object that has a unique value for each thread +/// that creates one. `ThreadId`s do not correspond to a thread's system- +/// designated identifier. +#[unstable(feature = "thread_id", issue = "21507")] +#[derive(Eq, PartialEq, Copy, Clone)] +pub struct ThreadId(usize); + +impl ThreadId { + /// Returns an identifier unique to the current calling thread. + #[unstable(feature = "thread_id", issue = "21507")] + pub fn current() -> ThreadId { + static THREAD_ID_COUNT: AtomicUsize = ATOMIC_USIZE_INIT; + #[thread_local] static mut THREAD_ID: ThreadId = ThreadId(0); + + unsafe { + if THREAD_ID.0 == 0 { + THREAD_ID.0 = 1 + THREAD_ID_COUNT.fetch_add(1, Ordering::SeqCst); + } + THREAD_ID + } + } +} + //////////////////////////////////////////////////////////////////////////////// // Thread //////////////////////////////////////////////////////////////////////////////// @@ -977,6 +1007,16 @@ mod tests { thread::sleep(Duration::from_millis(2)); } + #[test] + fn test_thread_id_equal() { + assert_eq!(ThreadId::current(), ThreadId::current()); + } + + #[test] + fn test_thread_id_not_equal() { + assert!(ThreadId::current() != spawn(|| ThreadId::current()).join()); + } + // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due // to the test harness apparently interfering with stderr configuration. }