use cell::UnsafeCell;
use fmt;
use io;
+use str;
+use ffi::{CStr, CString};
use sync::{Mutex, Condvar, Arc};
use sys::thread as imp;
use sys_common::thread_info;
let their_packet = my_packet.clone();
let main = move || {
- if let Some(name) = their_thread.name() {
+ if let Some(name) = their_thread.cname() {
imp::Thread::set_name(name);
}
unsafe {
/// The internal representation of a `Thread` handle
struct Inner {
- name: Option<String>,
+ name: Option<CString>, // Guaranteed to be UTF-8
lock: Mutex<bool>, // true when there is a buffered unpark
cvar: Condvar,
}
impl Thread {
// Used only internally to construct a thread object without spawning
fn new(name: Option<String>) -> Thread {
+ let cname = name.map(|n| CString::new(n).unwrap_or_else(|_| {
+ panic!("thread name may not contain interior null bytes")
+ }));
Thread {
inner: Arc::new(Inner {
- name: name,
+ name: cname,
lock: Mutex::new(false),
cvar: Condvar::new(),
})
/// Gets the thread's name.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn name(&self) -> Option<&str> {
+ self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) } )
+ }
+
+ fn cname(&self) -> Option<&CStr> {
self.inner.name.as_ref().map(|s| &**s)
}
}
}).unwrap().join().unwrap();
}
+ #[test]
+ #[should_panic]
+ fn test_invalid_named_thread() {
+ let _ = Builder::new().name("ada l\0velace".to_string()).spawn(|| {});
+ }
+
#[test]
fn test_run_basic() {
let (tx, rx) = channel();