]> git.proxmox.com Git - rustc.git/blobdiff - src/libstd/thread/mod.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / libstd / thread / mod.rs
index 981ba1e36e9d5c531b7811365b6039443b0fb921..b3549dc12645aec854e0c0ec3d4d1b90ede910e9 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Native threads
+//! Native threads.
 //!
 //! ## The threading model
 //!
@@ -166,6 +166,8 @@ use any::Any;
 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;
@@ -267,7 +269,7 @@ impl Builder {
         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 {
@@ -285,7 +287,7 @@ impl Builder {
 
         Ok(JoinHandle(JoinInner {
             native: unsafe {
-                Some(try!(imp::Thread::new(stack_size, Box::new(main))))
+                Some(imp::Thread::new(stack_size, Box::new(main))?)
             },
             thread: my_thread,
             packet: Packet(my_packet),
@@ -339,40 +341,6 @@ pub fn panicking() -> bool {
     unwind::panicking()
 }
 
-/// Invokes a closure, capturing the cause of panic if one occurs.
-///
-/// This function will return `Ok` with the closure's result if the closure
-/// does not panic, and will return `Err(cause)` if the closure panics. The
-/// `cause` returned is the object with which panic was originally invoked.
-///
-/// It is currently undefined behavior to unwind from Rust code into foreign
-/// code, so this function is particularly useful when Rust is called from
-/// another language (normally C). This can run arbitrary Rust code, capturing a
-/// panic and allowing a graceful handling of the error.
-///
-/// It is **not** recommended to use this function for a general try/catch
-/// mechanism. The `Result` type is more appropriate to use for functions that
-/// can fail on a regular basis.
-///
-/// The closure provided is required to adhere to the `'static` bound to ensure
-/// that it cannot reference data in the parent stack frame, mitigating problems
-/// with exception safety. Furthermore, a `Send` bound is also required,
-/// providing the same safety guarantees as `thread::spawn` (ensuring the
-/// closure is properly isolated from the parent).
-#[unstable(feature = "catch_panic", reason = "recent API addition",
-           issue = "27719")]
-#[rustc_deprecated(since = "1.6.0", reason = "renamed to std::panic::recover")]
-pub fn catch_panic<F, R>(f: F) -> Result<R>
-    where F: FnOnce() -> R + Send + 'static
-{
-    let mut result = None;
-    unsafe {
-        let result = &mut result;
-        try!(unwind::try(move || *result = Some(f())))
-    }
-    Ok(result.unwrap())
-}
-
 /// Puts the current thread to sleep for the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
@@ -484,7 +452,7 @@ pub fn park_timeout(dur: Duration) {
 
 /// 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,
 }
@@ -499,9 +467,12 @@ pub struct Thread {
 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(),
             })
@@ -523,6 +494,10 @@ impl Thread {
     /// 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)
     }
 }
@@ -656,6 +631,12 @@ mod tests {
         }).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();