From 061b56bd5ca2d3a49bebdd6a174995e1b3ec6a5b Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 13:47:39 +0200 Subject: [PATCH 01/16] Add a link to `park` in the `park_timeout` doc. Part of #29378 --- src/libstd/thread/mod.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 8e7eaa77cd7..dbc8562ea39 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -585,9 +585,9 @@ pub fn park() { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to `park()` except that the -/// thread will be blocked for roughly no longer than `ms`. This method -/// should not be used for precise timing due to anomalies such as +/// The semantics of this function are equivalent to [`park()`][[park] except +/// that the thread will be blocked for roughly no longer than `dur`. This +/// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// @@ -595,6 +595,7 @@ pub fn park() { /// /// [thread]: index.html /// [park_timeout]: fn.park_timeout.html +/// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { @@ -604,9 +605,9 @@ pub fn park_timeout_ms(ms: u32) { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to `park()` except that the -/// thread will be blocked for roughly no longer than `dur`. This method -/// should not be used for precise timing due to anomalies such as +/// The semantics of this function are equivalent to [`park()`][[park] except +/// that the thread will be blocked for roughly no longer than `dur`. This +/// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `dur` long. /// @@ -635,6 +636,8 @@ pub fn park_timeout_ms(ms: u32) { /// park_timeout(timeout); /// } /// ``` +/// +/// [park]: fn.park.html #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { let thread = current(); From c158962169e3cf0686cb70652282bcdf20772926 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 13:50:23 +0200 Subject: [PATCH 02/16] Add link to the module doc in `park_timeout`. Part of #29378 --- src/libstd/thread/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index dbc8562ea39..1857f81a339 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -611,7 +611,7 @@ pub fn park_timeout_ms(ms: u32) { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `dur` long. /// -/// See the module doc for more detail. +/// See the [module doc][thread] for more detail. /// /// # Platform behavior /// @@ -637,6 +637,7 @@ pub fn park_timeout_ms(ms: u32) { /// } /// ``` /// +/// [thread]: index.html /// [park]: fn.park.html #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { From d9628f9389319c1075d4a54a0a490226539cea81 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 13:54:06 +0200 Subject: [PATCH 03/16] Add `park` info to `unpark`. - Adds an explanantion of what `park` does in the `unpark` documentation. - Adds a link to the module doc. --- src/libstd/thread/mod.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 1857f81a339..bdf7b1134bf 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -768,7 +768,11 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// - /// See the module doc for more detail. + /// Every thread is equipped with some basic low-level blocking support, via + /// the [`park()`][park] function and the `unpark` method. These can be + /// used as a more CPU-efficient implementation of a spinlock. + /// + /// See the [module doc][thread] for more detail. /// /// # Examples /// @@ -784,6 +788,9 @@ impl Thread { /// /// handler.join().unwrap(); /// ``` + /// + /// [thread]: index.html + /// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] pub fn unpark(&self) { let mut guard = self.inner.lock.lock().unwrap(); From 5573c4709cba7b3d5dc15c47239d1b1f32af4753 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 16:01:47 +0200 Subject: [PATCH 04/16] Better example for `thread::unpark`. Part of #29378 --- src/libstd/thread/mod.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index bdf7b1134bf..94a2c91858e 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -769,7 +769,7 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// /// Every thread is equipped with some basic low-level blocking support, via - /// the [`park()`][park] function and the `unpark` method. These can be + /// the [`park()`][park] function and the `unpark()` method. These can be /// used as a more CPU-efficient implementation of a spinlock. /// /// See the [module doc][thread] for more detail. @@ -779,14 +779,21 @@ impl Thread { /// ``` /// use std::thread; /// - /// let handler = thread::Builder::new() + /// let parked_thread = thread::Builder::new() /// .spawn(|| { - /// let thread = thread::current(); - /// thread.unpark(); + /// println!("Parking thread"); + /// thread::park(); + /// println!("Thread unparked"); /// }) /// .unwrap(); /// - /// handler.join().unwrap(); + /// // Let some time pass for the thread to be spawned. + /// thread::sleep(Duration::from_millis(10)); + /// + /// println!("Unpark the thread"); + /// parked_thread.thread().unpark(); + /// + /// parked_thread.join().unwrap(); /// ``` /// /// [thread]: index.html From c0d475ad7b44c153b4999709ff08a9275160ea1c Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 16:22:13 +0200 Subject: [PATCH 05/16] fix typo --- src/libstd/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 94a2c91858e..9c15857edf6 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -585,7 +585,7 @@ pub fn park() { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][[park] except +/// The semantics of this function are equivalent to [`park()`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -605,7 +605,7 @@ pub fn park_timeout_ms(ms: u32) { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][[park] except +/// The semantics of this function are equivalent to [`park()`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum From fa0cdaa63f575c81c7cc87239f7dfcc677362c78 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 18:55:20 +0200 Subject: [PATCH 06/16] Inline `thread::park` documentation. Part of #29378 - Moves the module documentation into `park`. - Add the same example as the one from `unpark` to `park`. --- src/libstd/thread/mod.rs | 120 +++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 9c15857edf6..5373bf273d4 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -96,41 +96,6 @@ //! The [`thread::current`] function is available even for threads not spawned //! by the APIs of this module. //! -//! ## Blocking support: park and unpark -//! -//! Every thread is equipped with some basic low-level blocking support, via the -//! [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`] -//! method. [`park`] blocks the current thread, which can then be resumed from -//! another thread by calling the [`unpark`] method on the blocked thread's handle. -//! -//! Conceptually, each [`Thread`] handle has an associated token, which is -//! initially not present: -//! -//! * The [`thread::park`][`park`] function blocks the current thread unless or until -//! the token is available for its thread handle, at which point it atomically -//! consumes the token. It may also return *spuriously*, without consuming the -//! token. [`thread::park_timeout`] does the same, but allows specifying a -//! maximum time to block the thread for. -//! -//! * The [`unpark`] method on a [`Thread`] atomically makes the token available -//! if it wasn't already. -//! -//! In other words, each [`Thread`] acts a bit like a semaphore with initial count -//! 0, except that the semaphore is *saturating* (the count cannot go above 1), -//! and can return spuriously. -//! -//! The API is typically used by acquiring a handle to the current thread, -//! placing that handle in a shared data structure so that other threads can -//! find it, and then `park`ing. When some desired condition is met, another -//! thread calls [`unpark`] on the handle. -//! -//! The motivation for this design is twofold: -//! -//! * It avoids the need to allocate mutexes and condvars when building new -//! synchronization primitives; the threads already provide basic blocking/signaling. -//! -//! * It can be implemented very efficiently on many platforms. -//! //! ## Thread-local storage //! //! This module also provides an implementation of thread-local storage for Rust @@ -547,23 +512,71 @@ pub fn sleep(dur: Duration) { /// Blocks unless or until the current thread's token is made available. /// -/// Every thread is equipped with some basic low-level blocking support, via -/// the `park()` function and the [`unpark`][unpark] method. These can be -/// used as a more CPU-efficient implementation of a spinlock. -/// -/// [unpark]: struct.Thread.html#method.unpark -/// -/// The API is typically used by acquiring a handle to the current thread, -/// placing that handle in a shared data structure so that other threads can -/// find it, and then parking (in a loop with a check for the token actually -/// being acquired). -/// /// A call to `park` does not guarantee that the thread will remain parked /// forever, and callers should be prepared for this possibility. /// -/// See the [module documentation][thread] for more detail. +/// # park and unpark /// -/// [thread]: index.html +/// Every thread is equipped with some basic low-level blocking support, via the +/// [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`] +/// method. [`park`] blocks the current thread, which can then be resumed from +/// another thread by calling the [`unpark`] method on the blocked thread's +/// handle. +/// +/// Conceptually, each [`Thread`] handle has an associated token, which is +/// initially not present: +/// +/// * The [`thread::park`][`park`] function blocks the current thread unless or +/// until the token is available for its thread handle, at which point it +/// atomically consumes the token. It may also return *spuriously*, without +/// consuming the token. [`thread::park_timeout`] does the same, but allows +/// specifying a maximum time to block the thread for. +/// +/// * The [`unpark`] method on a [`Thread`] atomically makes the token available +/// if it wasn't already. +/// +/// In other words, each [`Thread`] acts a bit like a spinlock that can be +/// locked and unlocked using `park` and `unpark`. +/// +/// The API is typically used by acquiring a handle to the current thread, +/// placing that handle in a shared data structure so that other threads can +/// find it, and then `park`ing. When some desired condition is met, another +/// thread calls [`unpark`] on the handle. +/// +/// The motivation for this design is twofold: +/// +/// * It avoids the need to allocate mutexes and condvars when building new +/// synchronization primitives; the threads already provide basic +/// blocking/signaling. +/// +/// * It can be implemented very efficiently on many platforms. +/// +/// # Examples +/// +/// ``` +/// use std::thread; +/// +/// let parked_thread = thread::Builder::new() +/// .spawn(|| { +/// println!("Parking thread"); +/// thread::park(); +/// println!("Thread unparked"); +/// }) +/// .unwrap(); +/// +/// // Let some time pass for the thread to be spawned. +/// thread::sleep(Duration::from_millis(10)); +/// +/// println!("Unpark the thread"); +/// parked_thread.thread().unpark(); +/// +/// parked_thread.join().unwrap(); +/// ``` +/// +/// [`Thread`]: ../../std/thread/struct.Thread.html +/// [`park`]: ../../std/thread/fn.park.html +/// [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark +/// [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html // // The implementation currently uses the trivial strategy of a Mutex+Condvar // with wakeup flag, which does not actually allow spurious wakeups. In the @@ -591,11 +604,10 @@ pub fn park() { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// -/// See the [module documentation][thread] for more detail. +/// See the [park documentation][park] for more detail. /// -/// [thread]: index.html /// [park_timeout]: fn.park_timeout.html -/// [park]: fn.park.html +/// [park]: ../../std/thread/fn.park.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { @@ -611,7 +623,7 @@ pub fn park_timeout_ms(ms: u32) { /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `dur` long. /// -/// See the [module doc][thread] for more detail. +/// See the [park dococumentation][park] for more details. /// /// # Platform behavior /// @@ -637,7 +649,6 @@ pub fn park_timeout_ms(ms: u32) { /// } /// ``` /// -/// [thread]: index.html /// [park]: fn.park.html #[stable(feature = "park_timeout", since = "1.4.0")] pub fn park_timeout(dur: Duration) { @@ -772,7 +783,7 @@ impl Thread { /// the [`park()`][park] function and the `unpark()` method. These can be /// used as a more CPU-efficient implementation of a spinlock. /// - /// See the [module doc][thread] for more detail. + /// See the [park documentation][park] for more details. /// /// # Examples /// @@ -796,7 +807,6 @@ impl Thread { /// parked_thread.join().unwrap(); /// ``` /// - /// [thread]: index.html /// [park]: fn.park.html #[stable(feature = "rust1", since = "1.0.0")] pub fn unpark(&self) { From 03c9510525c986715af1f1f98c2bc06248c747e8 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Sun, 7 May 2017 21:43:46 +0200 Subject: [PATCH 07/16] Fix typos in `thread::park` documentation. --- src/libstd/thread/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 5373bf273d4..4d931682676 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -518,7 +518,7 @@ pub fn sleep(dur: Duration) { /// # park and unpark /// /// Every thread is equipped with some basic low-level blocking support, via the -/// [`thread::park`][`park`] function and [`thread::Thread::unpark()`][`unpark`] +/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`] /// method. [`park`] blocks the current thread, which can then be resumed from /// another thread by calling the [`unpark`] method on the blocked thread's /// handle. @@ -555,6 +555,7 @@ pub fn sleep(dur: Duration) { /// /// ``` /// use std::thread; +/// use std::time::Duration; /// /// let parked_thread = thread::Builder::new() /// .spawn(|| { @@ -598,7 +599,7 @@ pub fn park() { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][park] except +/// The semantics of this function are equivalent to [`park`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -617,7 +618,7 @@ pub fn park_timeout_ms(ms: u32) { /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park()`][park] except +/// The semantics of this function are equivalent to [`park`][park] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum @@ -780,7 +781,7 @@ impl Thread { /// Atomically makes the handle's token available if it is not already. /// /// Every thread is equipped with some basic low-level blocking support, via - /// the [`park()`][park] function and the `unpark()` method. These can be + /// the [`park`][park] function and the `unpark()` method. These can be /// used as a more CPU-efficient implementation of a spinlock. /// /// See the [park documentation][park] for more details. @@ -789,6 +790,7 @@ impl Thread { /// /// ``` /// use std::thread; + /// use std::time::Duration; /// /// let parked_thread = thread::Builder::new() /// .spawn(|| { From c655348f26a179193f5d6d1a3a2fbe000a046699 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Tue, 9 May 2017 13:20:04 +0200 Subject: [PATCH 08/16] Add more examples to `thread::spawn` Part of #29378 --- src/libstd/thread/mod.rs | 57 +++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 4cbcfdbc2d7..c1e894510b9 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -315,6 +315,8 @@ impl Builder { /// thread finishes). The join handle can be used to block on /// termination of the child thread, including recovering its panics. /// + /// For a more complete documentation see [`thread::spawn`][`spawn`]. + /// /// # Errors /// /// Unlike the [`spawn`] free function, this method yields an @@ -392,14 +394,10 @@ impl Builder { /// Panics if the OS fails to create a thread; use [`Builder::spawn`] /// to recover from such errors. /// -/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html -/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join -/// [`Err`]: ../../std/result/enum.Result.html#variant.Err -/// [`panic`]: ../../std/macro.panic.html -/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn -/// /// # Examples /// +/// Simple thread creation. +/// /// ``` /// use std::thread; /// @@ -409,6 +407,53 @@ impl Builder { /// /// handler.join().unwrap(); /// ``` +/// +/// As mentionned in the module documentation, threads are usualy made to +/// communicate using [`channel`s][`channels`], here is how it usually looks. +/// +/// This example also shows how to use `move`, in order to give ownership +/// of values to a thread. +/// +/// ``` +/// use std::thread; +/// use std::sync::mpsc::channel; +/// +/// let (tx, rx) = channel(); +/// +/// let sender = thread::spawn(move || { +/// tx.send("Hello, thread".to_owned()); +/// }); +/// +/// let receiver = thread::spawn(move || { +/// println!("{}", rx.recv().unwrap()); +/// }); +/// +/// sender.join(); +/// receiver.join(); +/// ``` +/// +/// A thread can also return a value through its [`JoinHandle`], you can use +/// this to make asynchronous computations (futures might be more appropriate +/// though). +/// +/// ``` +/// use std::thread; +/// +/// let computation = thread::spawn(|| { +/// // Some expensive computation. +/// 42 +/// }); +/// +/// let result = computation.join().unwrap(); +/// println!("{}", v); +/// ``` +/// +/// [`channels`]: ../../std/sync/mpsc/index.html +/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html +/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join +/// [`Err`]: ../../std/result/enum.Result.html#variant.Err +/// [`panic`]: ../../std/macro.panic.html +/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn #[stable(feature = "rust1", since = "1.0.0")] pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static From 9db31206f597444258a46220f39fde13a76453e2 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Tue, 9 May 2017 13:27:22 +0200 Subject: [PATCH 09/16] Add a link to `thread::Builder` in `thread::spawn` --- src/libstd/thread/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index c1e894510b9..19adf3e3c3f 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -389,6 +389,10 @@ impl Builder { /// panics, [`join`] will return an [`Err`] containing the argument given to /// [`panic`]. /// +/// This will create a thread using default parameters of [`Builder`], if you +/// want to specify the stack size or the name of the thread, use this API +/// instead. +/// /// # Panics /// /// Panics if the OS fails to create a thread; use [`Builder::spawn`] @@ -454,6 +458,7 @@ impl Builder { /// [`Err`]: ../../std/result/enum.Result.html#variant.Err /// [`panic`]: ../../std/macro.panic.html /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn +/// [`Builder`]: ../../std/thread/struct.Builder.html #[stable(feature = "rust1", since = "1.0.0")] pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static From 656efcd3ab029491fd0bd01f3b596516884cabe1 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Tue, 9 May 2017 16:57:03 +0200 Subject: [PATCH 10/16] Address review comments --- src/libstd/thread/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 19adf3e3c3f..dd8892d6660 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -400,7 +400,7 @@ impl Builder { /// /// # Examples /// -/// Simple thread creation. +/// Creating a thread. /// /// ``` /// use std::thread; @@ -413,7 +413,7 @@ impl Builder { /// ``` /// /// As mentionned in the module documentation, threads are usualy made to -/// communicate using [`channel`s][`channels`], here is how it usually looks. +/// communicate using [`channels`], here is how it usually looks. /// /// This example also shows how to use `move`, in order to give ownership /// of values to a thread. From 23382e614a6e6a2eaf3ac4c476ae48594de8538a Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 06:38:26 -0400 Subject: [PATCH 11/16] Add more ways to create a PathBuf to docs The best way to do this wasn't in the documentation, and the ways that were there needed some extra text to elaborate. Fixes #40159 --- src/libstd/path.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 9d66430bc93..f4b9a8972e3 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -51,10 +51,17 @@ //! ``` //! use std::path::PathBuf; //! +//! // This way works... //! let mut path = PathBuf::from("c:\\"); +//! //! path.push("windows"); //! path.push("system32"); +//! //! path.set_extension("dll"); +//! +//! // ... but push is best used if you don't know everything up +//! // front. If you do, this way is better: +//! let path: PathBuf = ["c:\\", "windows", "system32.dll"].iter().collect(); //! ``` //! //! [`Component`]: ../../std/path/enum.Component.html @@ -63,6 +70,7 @@ //! [`Path`]: ../../std/path/struct.Path.html //! [`push`]: ../../std/path/struct.PathBuf.html#method.push //! [`String`]: ../../std/string/struct.String.html +//! //! [`str`]: ../../std/primitive.str.html //! [`OsString`]: ../../std/ffi/struct.OsString.html //! [`OsStr`]: ../../std/ffi/struct.OsStr.html @@ -1036,14 +1044,40 @@ impl<'a> cmp::Ord for Components<'a> { /// /// # Examples /// +/// You can use [`push`] to build up a `PathBuf` from +/// components: +/// /// ``` /// use std::path::PathBuf; /// -/// let mut path = PathBuf::from("c:\\"); +/// let mut path = PathBuf::new(); +/// +/// path.push(r"C:\"); /// path.push("windows"); /// path.push("system32"); +/// /// path.set_extension("dll"); /// ``` +/// +/// However, [`push`] is best used for dynamic situations. This is a better way +/// to do this when you know all of the components ahead of time: +/// +/// ``` +/// use std::path::PathBuf; +/// +/// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect(); +/// ``` +/// +/// We can still do better than this! Since these are all strings, we can use +/// `From::from`: +/// +/// ``` +/// use std::path::PathBuf; +/// +/// let path = PathBuf::from(r"C:\windows\system32.dll"); +/// ``` +/// +/// Which method works best depends on what kind of situation you're in. #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct PathBuf { From 2f6744c5fc086fcedd6515240fce15ed641f2846 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Tue, 25 Apr 2017 11:24:06 -0400 Subject: [PATCH 12/16] Improve docs on Arc and Send/Sync This is something I always forget, so let's actually explain in the docs. --- src/liballoc/arc.rs | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 6d85183faf7..27ecefe043b 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -54,16 +54,33 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// exception. If you need to mutate through an `Arc`, use [`Mutex`][mutex], /// [`RwLock`][rwlock], or one of the [`Atomic`][atomic] types. /// -/// `Arc` uses atomic operations for reference counting, so `Arc`s can be -/// sent between threads. In other words, `Arc` implements [`Send`] -/// as long as `T` implements [`Send`] and [`Sync`][sync]. The disadvantage is -/// that atomic operations are more expensive than ordinary memory accesses. -/// If you are not sharing reference-counted values between threads, consider -/// using [`rc::Rc`][`Rc`] for lower overhead. [`Rc`] is a safe default, because -/// the compiler will catch any attempt to send an [`Rc`] between threads. -/// However, a library might choose `Arc` in order to give library consumers +/// ## Thread Safety +/// +/// Unlike [`Rc`], `Arc` uses atomic operations for its reference +/// counting This means that it is thread-safe. The disadvantage is that +/// atomic operations are more expensive than ordinary memory accesses. If you +/// are not sharing reference-counted values between threads, consider using +/// [`Rc`] for lower overhead. [`Rc`] is a safe default, because the +/// compiler will catch any attempt to send an [`Rc`] between threads. +/// However, a library might choose `Arc` in order to give library consumers /// more flexibility. /// +/// `Arc` will implement [`Send`] and [`Sync`] as long as the `T` implements +/// [`Send`] and [`Sync`]. Why can't you put a non-thread-safe type `T` in an +/// `Arc` to make it thread-safe? This may be a bit counter-intuitive at +/// first: after all, isn't the point of `Arc` thread safety? The key is +/// this: `Arc` makes it thread safe to have multiple ownership of the same +/// data, but it doesn't add thread safety to its data. Consider +/// `Arc>`. `RefCell` isn't [`Sync`], and if `Arc` was always +/// [`Send`], `Arc>` would be as well. But then we'd have a problem: +/// `RefCell` is not thread safe; it keeps track of the borrowing count using +/// non-atomic operations. +/// +/// In the end, this means that you may need to pair `Arc` with some sort of +/// `std::sync` type, usually `Mutex`. +/// +/// ## Breaking cycles with `Weak` +/// /// The [`downgrade`][downgrade] method can be used to create a non-owning /// [`Weak`][weak] pointer. A [`Weak`][weak] pointer can be [`upgrade`][upgrade]d /// to an `Arc`, but this will return [`None`] if the value has already been @@ -74,6 +91,8 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// strong `Arc` pointers from parent nodes to children, and [`Weak`][weak] /// pointers from children back to their parents. /// +/// ## `Deref` behavior +/// /// `Arc` automatically dereferences to `T` (via the [`Deref`][deref] trait), /// so you can call `T`'s methods on a value of type `Arc`. To avoid name /// clashes with `T`'s methods, the methods of `Arc` itself are [associated @@ -91,13 +110,13 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// /// [arc]: struct.Arc.html /// [weak]: struct.Weak.html -/// [`Rc`]: ../../std/rc/struct.Rc.html +/// [`Rc`]: ../../std/rc/struct.Rc.html /// [clone]: ../../std/clone/trait.Clone.html#tymethod.clone /// [mutex]: ../../std/sync/struct.Mutex.html /// [rwlock]: ../../std/sync/struct.RwLock.html /// [atomic]: ../../std/sync/atomic/index.html /// [`Send`]: ../../std/marker/trait.Send.html -/// [sync]: ../../std/marker/trait.Sync.html +/// [`Sync`]: ../../std/marker/trait.Sync.html /// [deref]: ../../std/ops/trait.Deref.html /// [downgrade]: struct.Arc.html#method.downgrade /// [upgrade]: struct.Weak.html#method.upgrade From afe74c3900aa00373a0d5edd2bd433870822c40a Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Tue, 9 May 2017 19:02:43 +0200 Subject: [PATCH 13/16] Fix link --- src/libstd/thread/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 4d931682676..9a7239d297c 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -594,21 +594,21 @@ pub fn park() { *guard = false; } -/// Use [park_timeout]. +/// Use [`park_timeout`]. /// /// Blocks unless or until the current thread's token is made available or /// the specified duration has been reached (may wake spuriously). /// -/// The semantics of this function are equivalent to [`park`][park] except +/// The semantics of this function are equivalent to [`park`] except /// that the thread will be blocked for roughly no longer than `dur`. This /// method should not be used for precise timing due to anomalies such as /// preemption or platform differences that may not cause the maximum /// amount of time waited to be precisely `ms` long. /// -/// See the [park documentation][park] for more detail. +/// See the [park documentation][`park`] for more detail. /// -/// [park_timeout]: fn.park_timeout.html -/// [park]: ../../std/thread/fn.park.html +/// [`park_timeout`]: fn.park_timeout.html +/// [`park`]: ../../std/thread/fn.park.html #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")] pub fn park_timeout_ms(ms: u32) { From 202086e48ff3ca955a52137d71ca8713f39cd5ff Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Tue, 9 May 2017 19:06:56 +0200 Subject: [PATCH 14/16] Fix warnings in examples --- src/libstd/thread/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index dd8892d6660..425cb0ada08 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -425,15 +425,15 @@ impl Builder { /// let (tx, rx) = channel(); /// /// let sender = thread::spawn(move || { -/// tx.send("Hello, thread".to_owned()); +/// let _ = tx.send("Hello, thread".to_owned()); /// }); /// /// let receiver = thread::spawn(move || { /// println!("{}", rx.recv().unwrap()); /// }); /// -/// sender.join(); -/// receiver.join(); +/// let _ = sender.join(); +/// let _ = receiver.join(); /// ``` /// /// A thread can also return a value through its [`JoinHandle`], you can use @@ -449,7 +449,7 @@ impl Builder { /// }); /// /// let result = computation.join().unwrap(); -/// println!("{}", v); +/// println!("{}", result); /// ``` /// /// [`channels`]: ../../std/sync/mpsc/index.html From fe7b6db39b6efa064ab795103342ca3d298dc943 Mon Sep 17 00:00:00 2001 From: Felix Raimundo Date: Wed, 10 May 2017 10:44:58 +0200 Subject: [PATCH 15/16] Fix typos in doc --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 425cb0ada08..e81300d6dc8 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -412,7 +412,7 @@ impl Builder { /// handler.join().unwrap(); /// ``` /// -/// As mentionned in the module documentation, threads are usualy made to +/// As mentioned in the module documentation, threads are usually made to /// communicate using [`channels`], here is how it usually looks. /// /// This example also shows how to use `move`, in order to give ownership From ec141c8c96c81decd8fd7227c40285bc9b994a16 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 10 May 2017 17:05:54 +0200 Subject: [PATCH 16/16] fix typo in Unique::empty doc --- src/libcore/ptr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a60abefc076..5f189d473be 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1005,7 +1005,7 @@ unsafe impl Sync for Unique { } #[unstable(feature = "unique", issue = "27730")] impl Unique { - /// Creates a new `Shared` that is dangling, but well-aligned. + /// Creates a new `Unique` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does.