Change:
Trying the following example on playpen (notice the inside the thread name) Playpen output: Both on stable and nightly.
Patch:
It can be closed, right?
Yep
I was leaving it open because I did not know if it was going to be beta nominated or not.

Discussion:
use alloc::boxed::FnBox; use cmp; #[cfg(not(any(target_env = "newlib", target_os = "solaris")))] <del> use ffi::CString; </del> <ins> use ffi::CStr; </ins> use io; use libc; use mem;

#[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))] <del> pub fn set_name(name: &str) { </del> <ins> pub fn set_name(name: &CStr) { </ins> const PR_SET_NAME: libc::c_int = 15; <del> let cname = CString::new(name).unwrap_or_else(|_| { panic!("thread name may not contain interior null bytes") }); </del> // pthread wrapper only appeared in glibc 2.12, so we use syscall // directly. unsafe { <del> libc::prctl(PR_SET_NAME, cname.as_ptr() as libc::c_ulong, 0, 0, 0); </del> <ins> libc::prctl(PR_SET_NAME, name.as_ptr() as libc::c_ulong, 0, 0, 0); </ins> } }

target_os = "dragonfly", target_os = "bitrig", target_os = "openbsd"))] <del> pub fn set_name(name: &str) { let cname = CString::new(name).unwrap(); </del> <ins> pub fn set_name(name: &CStr) { </ins> unsafe { <del> libc::pthread_set_name_np(libc::pthread_self(), cname.as_ptr()); </del> <ins> libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr()); </ins> } } #[cfg(any(target_os = "macos", target_os = "ios"))] <del> pub fn set_name(name: &str) { let cname = CString::new(name).unwrap(); </del> <ins> pub fn set_name(name: &CStr) { </ins> unsafe { <del> libc::pthread_setname_np(cname.as_ptr()); </del> <ins> libc::pthread_setname_np(name.as_ptr()); </ins> } } #[cfg(target_os = "netbsd")] <del> pub fn set_name(name: &str) { </del> <ins> pub fn set_name(name: &CStr) { use ffi::CString; </ins> let cname = CString::new(&b"%s"[..]).unwrap(); <del> let carg = CString::new(name).unwrap(); </del> unsafe { libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(), <del> carg.as_ptr() as *mut libc::c_void); </del> <ins> name.as_ptr() as *mut libc::c_void); </ins> } } #[cfg(any(target_env = "newlib", target_os = "solaris"))] <del> pub fn set_name(_name: &str) { </del> <ins> pub fn set_name(_name: &CStr) { </ins> // Newlib and Illumos has no way to set a thread name. }

} } <del> pub fn set_name(_name: &str) { </del> <ins> pub fn set_name(_name: &CStr) { </ins> // Windows threads are nameless // The names in MSVC debugger are obtained using a "magic" exception, // which requires a use of MS C++ extensions.

use cell::UnsafeCell; use fmt; use io; <ins> use str; use ffi::{CStr, CString}; </ins> use sync::{Mutex, Condvar, Arc}; use sys::thread as imp; use sys_common::thread_info;

let their_packet = my_packet.clone(); let main = move || { <del> if let Some(name) = their_thread.name() { </del> <ins> if let Some(name) = their_thread.cname() { </ins> imp::Thread::set_name(name); } unsafe {

/// The internal representation of a `Thread` handle struct Inner { <del> name: Option<String>, </del> <ins> name: Option<CString>,      // Guaranteed to be UTF-8 </ins> 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 { <ins> let cname = name.map(|n| CString::new(n).unwrap_or_else(|_| { panic!("thread name may not contain interior null bytes") })); </ins> Thread { inner: Arc::new(Inner { <del> name: name, </del> <ins> name: cname, </ins> 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> { <ins> self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) } ) } fn cname(&self) -> Option<&CStr> { </ins> self.inner.name.as_ref().map(|s| &**s) } }

} #[test] <ins> #[should_panic] fn test_invalid_named_thread() { let _ = Builder::new().name("ada l0velace".to_string()).spawn(|| {}); } #[test] </ins> fn test_run_basic() { let (tx, rx) = channel(); thread::spawn(move|| {