diff --git a/src/libstd/sys/common/thread.rs b/src/libstd/sys/common/thread.rs index 16f4f01bf39fe..7f288e593a35b 100644 --- a/src/libstd/sys/common/thread.rs +++ b/src/libstd/sys/common/thread.rs @@ -14,11 +14,11 @@ use alloc::boxed::FnBox; use libc; use sys::stack_overflow; -pub unsafe fn start_thread(main: *mut libc::c_void) { +pub unsafe fn start_thread(main: *mut libc::c_void, id: u32) { // Next, set up our stack overflow handler which may get triggered if we run // out of stack. let _handler = stack_overflow::Handler::new(); // Finally, let's run some code. - Box::from_raw(main as *mut Box)() + Box::from_raw(main as *mut Box)(id) } diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index b7968e9344f3c..2358bdf67c77e 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -35,7 +35,7 @@ unsafe impl Send for Thread {} unsafe impl Sync for Thread {} impl Thread { - pub unsafe fn new<'a>(stack: usize, p: Box) + pub unsafe fn new<'a>(stack: usize, p: Box) -> io::Result { let p = box p; let mut native: libc::pthread_t = mem::zeroed(); @@ -71,7 +71,7 @@ impl Thread { }; extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void { - unsafe { start_thread(main); } + unsafe { start_thread(main, pthread_self() as u32); } ptr::null_mut() } } @@ -162,6 +162,10 @@ impl Thread { debug_assert_eq!(ret, 0); } } + + pub fn id(&self) -> u32 { + self.id as u32 + } } impl Drop for Thread { diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs index cf1b3ebddb97b..ec60759797d59 100644 --- a/src/libstd/sys/windows/thread.rs +++ b/src/libstd/sys/windows/thread.rs @@ -49,7 +49,7 @@ impl Thread { }; extern "system" fn thread_start(main: *mut libc::c_void) -> DWORD { - unsafe { start_thread(main); } + unsafe { start_thread(main, 42); } 0 } } @@ -78,6 +78,10 @@ impl Thread { c::Sleep(super::dur2timeout(dur)) } } + + pub fn id(&self) -> u32 { + 42 // TODO + } } pub mod guard { diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 9b8f63997b642..abe1bc98867b0 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -252,17 +252,18 @@ impl Builder { let stack_size = stack_size.unwrap_or(util::min_stack()); - let my_thread = Thread::new(name); - let their_thread = my_thread.clone(); + let mut my_thread = Thread::new(name); + let mut their_thread = my_thread.clone(); let my_packet : Arc>>> = Arc::new(UnsafeCell::new(None)); let their_packet = my_packet.clone(); - let main = move || { + let main = move |id: u32| { if let Some(name) = their_thread.name() { imp::Thread::set_name(name); } + their_thread.id = id; unsafe { thread_info::set(imp::guard::current(), their_thread); let mut output = None; @@ -276,10 +277,12 @@ impl Builder { } }; + let native = unsafe { + try!(imp::Thread::new(stack_size, Box::new(main))) + }; + my_thread.id = native.id(); Ok(JoinHandle(JoinInner { - native: unsafe { - Some(try!(imp::Thread::new(stack_size, Box::new(main)))) - }, + native: Some(native), thread: my_thread, packet: Packet(my_packet), })) @@ -502,6 +505,7 @@ struct Inner { /// A handle to a thread. pub struct Thread { inner: Arc, + id: u32, } impl Thread { @@ -512,7 +516,8 @@ impl Thread { name: name, lock: Mutex::new(false), cvar: Condvar::new(), - }) + }), + id: 0, } } @@ -533,12 +538,20 @@ impl Thread { pub fn name(&self) -> Option<&str> { self.inner.name.as_ref().map(|s| &**s) } + + /// Gets the thread's unique ID. + /// + /// This ID is unique across running threads, and a thread that has stopped + /// might see its ID reused. + pub fn id(&self) -> u32 { + self.id + } } #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Debug for Thread { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self.name(), f) + fmt::Debug::fmt(&self.name(), f) // print ID? } }