about summary refs log tree commit diff
path: root/src/libstd/thread
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2015-03-30 20:18:16 +0530
committerManish Goregaokar <manishsmail@gmail.com>2015-03-30 20:18:16 +0530
commit3b4547010011b948168d64eb8d05a5cfa7652765 (patch)
treed3e133c446a8aab157f145122223c7d2ab944dc1 /src/libstd/thread
parentdb50084cd9d83f7b342f481c2d03f78b50d99059 (diff)
parentd9252bde18360e5815f0d83a83efd597bc6bb5b7 (diff)
downloadrust-3b4547010011b948168d64eb8d05a5cfa7652765.tar.gz
rust-3b4547010011b948168d64eb8d05a5cfa7652765.zip
Rollup merge of #23855 - tshepang:doc-nit, r=Manishearth
Diffstat (limited to 'src/libstd/thread')
-rw-r--r--src/libstd/thread/mod.rs53
1 files changed, 51 insertions, 2 deletions
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 27b50fc9aaa..074030bd07b 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -434,6 +434,55 @@ pub fn panicking() -> bool {
     unwind::panicking()
 }
 
+/// Invoke a closure, capturing the cause of panic if one occurs.
+///
+/// This function will return `Ok(())` 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).
+///
+/// # Examples
+///
+/// ```
+/// # #![feature(catch_panic)]
+/// use std::thread;
+///
+/// let result = thread::catch_panic(|| {
+///     println!("hello!");
+/// });
+/// assert!(result.is_ok());
+///
+/// let result = thread::catch_panic(|| {
+///     panic!("oh no!");
+/// });
+/// assert!(result.is_err());
+/// ```
+#[unstable(feature = "catch_panic", reason = "recent API addition")]
+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!(::rt::unwind::try(move || *result = Some(f())))
+    }
+    Ok(result.unwrap())
+}
+
 /// Put the current thread to sleep for the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
@@ -821,13 +870,13 @@ mod test {
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_scoped_panic() {
         thread::scoped(|| panic!()).join();
     }
 
     #[test]
-    #[should_fail]
+    #[should_panic]
     fn test_scoped_implicit_panic() {
         let _ = thread::scoped(|| panic!());
     }