From fbb95689d692ba456309927793a28da85d2bf4d1 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Sat, 13 Oct 2018 14:34:31 +0200 Subject: adds unsafe `thread::Builder::spawn_unchecked` function moves code for `thread::Builder::spawn` into new public unsafe function `spawn_unchecked` and transforms `spawn` into a safe wrapper. --- src/libstd/thread/mod.rs | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index c8d54a63946..28e69a1d065 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -386,6 +386,13 @@ impl Builder { #[stable(feature = "rust1", since = "1.0.0")] pub fn spawn(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static + { + unsafe { self.spawn_unchecked(f) } + } + + /// TODO: Doc + pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result> where + F: FnOnce() -> T, F: Send + 'a, T: Send + 'a { let Builder { name, stack_size } = self; @@ -402,16 +409,15 @@ impl Builder { if let Some(name) = their_thread.cname() { imp::Thread::set_name(name); } - unsafe { - thread_info::set(imp::guard::current(), their_thread); - #[cfg(feature = "backtrace")] - let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| { - ::sys_common::backtrace::__rust_begin_short_backtrace(f) - })); - #[cfg(not(feature = "backtrace"))] - let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f)); - *their_packet.get() = Some(try_result); - } + + thread_info::set(imp::guard::current(), their_thread); + #[cfg(feature = "backtrace")] + let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| { + ::sys_common::backtrace::__rust_begin_short_backtrace(f) + })); + #[cfg(not(feature = "backtrace"))] + let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f)); + *their_packet.get() = Some(try_result); }; Ok(JoinHandle(JoinInner { @@ -420,7 +426,7 @@ impl Builder { }, thread: my_thread, packet: Packet(my_packet), - })) + })) } } -- cgit 1.4.1-3-g733a5 From 719a59586add4a4782c2e2a85e5d5fb97749d8e5 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Sat, 13 Oct 2018 17:28:47 +0200 Subject: Update mod.rs removes unnecessary `unsafe`, adds `unstable` attribute --- src/libstd/thread/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 28e69a1d065..e05a5dc458b 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -391,6 +391,7 @@ impl Builder { } /// TODO: Doc + #[unstable(feature = "thread_spawn_unchecked", issue = "0")] pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send + 'a, T: Send + 'a { @@ -421,9 +422,7 @@ impl Builder { }; Ok(JoinHandle(JoinInner { - native: unsafe { - Some(imp::Thread::new(stack_size, Box::new(main))?) - }, + native: Some(imp::Thread::new(stack_size, Box::new(main))?), thread: my_thread, packet: Packet(my_packet), })) -- cgit 1.4.1-3-g733a5 From a52b474b525ded83ebbf9b96db4d7d225497587c Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Sat, 13 Oct 2018 18:24:47 +0200 Subject: Update mod.rs removes trailing whitespaces, replaces TODO with FIXME --- src/libstd/thread/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index e05a5dc458b..e1dad9e1311 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -389,8 +389,8 @@ impl Builder { { unsafe { self.spawn_unchecked(f) } } - - /// TODO: Doc + + /// FIXME: Doc #[unstable(feature = "thread_spawn_unchecked", issue = "0")] pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send + 'a, T: Send + 'a @@ -425,7 +425,7 @@ impl Builder { native: Some(imp::Thread::new(stack_size, Box::new(main))?), thread: my_thread, packet: Packet(my_packet), - })) + })) } } -- cgit 1.4.1-3-g733a5 From bf9dc98655a9d42571815798992e2534af3296f8 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Sun, 14 Oct 2018 14:28:01 +0200 Subject: remove unnecessary lifetime bounds generic lifetime bound `'a` can be inferred. --- src/libstd/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index e1dad9e1311..2f63963c823 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -392,8 +392,8 @@ impl Builder { /// FIXME: Doc #[unstable(feature = "thread_spawn_unchecked", issue = "0")] - pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result> where - F: FnOnce() -> T, F: Send + 'a, T: Send + 'a + pub unsafe fn spawn_unchecked(self, f: F) -> io::Result> where + F: FnOnce() -> T, F: Send, T: Send { let Builder { name, stack_size } = self; -- cgit 1.4.1-3-g733a5 From 986549e9f565091ec4bb70cf456029a572da8046 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Mon, 15 Oct 2018 12:48:24 +0200 Subject: adds doc for `Builder::spawn_unchecked` --- src/libstd/thread/mod.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 2f63963c823..73251d40599 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -390,7 +390,66 @@ impl Builder { unsafe { self.spawn_unchecked(f) } } - /// FIXME: Doc + /// Spawns a new thread without any lifetime restrictions by taking ownership + /// of the `Builder`, and returns an [`io::Result`] to its [`JoinHandle`]. + /// + /// The spawned thread may outlive the caller (unless the caller thread + /// is the main thread; the whole process is terminated when the main + /// thread finishes). The join handle can be used to block on + /// termination of the child thread, including recovering its panics. + /// + /// This method is identical to [`thread::Builder::spawn`][`Builder::spawn`], + /// except for the relaxed lifetime bounds, which render it unsafe. + /// For a more complete documentation see [`thread::spawn`][`spawn`]. + /// + /// # Errors + /// + /// Unlike the [`spawn`] free function, this method yields an + /// [`io::Result`] to capture any failure to create the thread at + /// the OS level. + /// + /// # Panics + /// + /// Panics if a thread name was set and it contained null bytes. + /// + /// # Safety + /// + /// The caller has to ensure that no references in the supplied thread closure + /// or its return type can outlive the spawned thread's lifetime. This can be + /// guaranteed in two ways: + /// + /// - ensure that [`join`][`JoinHandle::join`] is called before any referenced + /// data is dropped + /// - use only types with `'static` lifetime bounds, i.e. those with no or only + /// `'static` references (both [`thread::Builder::spawn`][`Builder::spawn`] + /// and [`thread::spawn`][`spawn`] enforce this property statically) + /// + /// # Examples + /// + /// ``` + /// use std::thread; + /// + /// let builder = thread::Builder::new(); + /// + /// let x = 1; + /// let thread_x = &x; + /// + /// let handler = unsafe { + /// builder.spawn_unchecked(move || { + /// println!("x = {}", *thread_x); + /// }).unwrap(); + /// } + /// + /// // caller has to ensure `join()` is called, otherwise + /// // it is possible to access freed memory if `x` gets + /// // dropped before the thread closure is executed! + /// handler.join.unwrap(); + /// ``` + /// + /// [`spawn`]: ../../std/thread/fn.spawn.html + /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn + /// [`io::Result`]: ../../std/io/type.Result.html + /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html #[unstable(feature = "thread_spawn_unchecked", issue = "0")] pub unsafe fn spawn_unchecked(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send, T: Send -- cgit 1.4.1-3-g733a5 From 9d7a83862b77e36aa165bf843a03f85adcd271bf Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Mon, 15 Oct 2018 13:22:39 +0200 Subject: fixes misplaced semicolon --- src/libstd/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 73251d40599..afc659ccf3a 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -437,8 +437,8 @@ impl Builder { /// let handler = unsafe { /// builder.spawn_unchecked(move || { /// println!("x = {}", *thread_x); - /// }).unwrap(); - /// } + /// }).unwrap() + /// }; /// /// // caller has to ensure `join()` is called, otherwise /// // it is possible to access freed memory if `x` gets -- cgit 1.4.1-3-g733a5 From ee5703cbbc6579fde6c717a6b27d58588294d6e1 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Mon, 15 Oct 2018 13:47:27 +0200 Subject: adds missing method call parentheses --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index afc659ccf3a..770044439a5 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -443,7 +443,7 @@ impl Builder { /// // caller has to ensure `join()` is called, otherwise /// // it is possible to access freed memory if `x` gets /// // dropped before the thread closure is executed! - /// handler.join.unwrap(); + /// handler.join().unwrap(); /// ``` /// /// [`spawn`]: ../../std/thread/fn.spawn.html -- cgit 1.4.1-3-g733a5 From ebb9d289db4f547798a1700175fd7de979051c39 Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Mon, 15 Oct 2018 14:14:17 +0200 Subject: adds feature gate to doc-test (example) --- src/libstd/thread/mod.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 770044439a5..8df9bee0eb4 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -427,6 +427,7 @@ impl Builder { /// # Examples /// /// ``` + /// #![feature(thread_spawn_unchecked)] /// use std::thread; /// /// let builder = thread::Builder::new(); -- cgit 1.4.1-3-g733a5 From 7849aeddb9de12cd7dadc3953cb581695717130b Mon Sep 17 00:00:00 2001 From: oliver-giersch Date: Tue, 16 Oct 2018 22:42:14 +0200 Subject: adds tracking issue number --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd/thread') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index dc2d12bf2c4..e5a28c27cf0 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -451,7 +451,7 @@ impl Builder { /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn /// [`io::Result`]: ../../std/io/type.Result.html /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html - #[unstable(feature = "thread_spawn_unchecked", issue = "0")] + #[unstable(feature = "thread_spawn_unchecked", issue = "55132")] pub unsafe fn spawn_unchecked(self, f: F) -> io::Result> where F: FnOnce() -> T, F: Send, T: Send { -- cgit 1.4.1-3-g733a5