]> git.proxmox.com Git - rustc.git/blame - src/libstd/thread/mod.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / libstd / thread / mod.rs
CommitLineData
1a4d82fc
JJ
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11//! Native threads
12//!
13//! ## The threading model
14//!
15//! An executing Rust program consists of a collection of native OS threads,
16//! each with their own stack and local state.
17//!
18//! Communication between threads can be done through
19//! [channels](../../std/sync/mpsc/index.html), Rust's message-passing
20//! types, along with [other forms of thread
21//! synchronization](../../std/sync/index.html) and shared-memory data
22//! structures. In particular, types that are guaranteed to be
23//! threadsafe are easily shared between threads using the
24//! atomically-reference-counted container,
25//! [`Arc`](../../std/sync/struct.Arc.html).
26//!
27//! Fatal logic errors in Rust cause *thread panic*, during which
28//! a thread will unwind the stack, running destructors and freeing
29//! owned resources. Thread panic is unrecoverable from within
30//! the panicking thread (i.e. there is no 'try/catch' in Rust), but
c34b1796
AL
31//! the panic may optionally be detected from a different thread. If
32//! the main thread panics, the application will exit with a non-zero
1a4d82fc
JJ
33//! exit code.
34//!
35//! When the main thread of a Rust program terminates, the entire program shuts
36//! down, even if other threads are still running. However, this module provides
37//! convenient facilities for automatically waiting for the termination of a
c34b1796 38//! child thread (i.e., join).
1a4d82fc
JJ
39//!
40//! ## The `Thread` type
41//!
c34b1796 42//! Threads are represented via the `Thread` type, which you can
1a4d82fc
JJ
43//! get in one of two ways:
44//!
c34b1796 45//! * By spawning a new thread, e.g. using the `thread::spawn` function.
85aaf69f 46//! * By requesting the current thread, using the `thread::current` function.
1a4d82fc
JJ
47//!
48//! Threads can be named, and provide some built-in support for low-level
c34b1796 49//! synchronization (described below).
1a4d82fc 50//!
85aaf69f 51//! The `thread::current()` function is available even for threads not spawned
1a4d82fc
JJ
52//! by the APIs of this module.
53//!
54//! ## Spawning a thread
55//!
85aaf69f 56//! A new thread can be spawned using the `thread::spawn` function:
1a4d82fc
JJ
57//!
58//! ```rust
85aaf69f 59//! use std::thread;
1a4d82fc 60//!
85aaf69f 61//! thread::spawn(move || {
c34b1796 62//! // some work here
1a4d82fc
JJ
63//! });
64//! ```
65//!
85aaf69f 66//! In this example, the spawned thread is "detached" from the current
c34b1796
AL
67//! thread. This means that it can outlive its parent (the thread that spawned
68//! it), unless this parent is the main thread.
1a4d82fc 69//!
9346a6ac
AL
70//! The parent thread can also wait on the completion of the child
71//! thread; a call to `spawn` produces a `JoinHandle`, which provides
72//! a `join` method for waiting:
73//!
74//! ```rust
75//! use std::thread;
76//!
77//! let child = thread::spawn(move || {
78//! // some work here
79//! });
80//! // some work here
81//! let res = child.join();
82//! ```
83//!
84//! The `join` method returns a `Result` containing `Ok` of the final
85//! value produced by the child thread, or `Err` of the value given to
86//! a call to `panic!` if the child panicked.
87//!
1a4d82fc
JJ
88//! ## Configuring threads
89//!
90//! A new thread can be configured before it is spawned via the `Builder` type,
bd371182 91//! which currently allows you to set the name and stack size for the child thread:
1a4d82fc
JJ
92//!
93//! ```rust
9346a6ac 94//! # #![allow(unused_must_use)]
1a4d82fc
JJ
95//! use std::thread;
96//!
97//! thread::Builder::new().name("child1".to_string()).spawn(move || {
c34b1796 98//! println!("Hello, world!");
1a4d82fc
JJ
99//! });
100//! ```
101//!
102//! ## Blocking support: park and unpark
103//!
104//! Every thread is equipped with some basic low-level blocking support, via the
105//! `park` and `unpark` functions.
106//!
107//! Conceptually, each `Thread` handle has an associated token, which is
108//! initially not present:
109//!
85aaf69f 110//! * The `thread::park()` function blocks the current thread unless or until
c34b1796 111//! the token is available for its thread handle, at which point it atomically
1a4d82fc 112//! consumes the token. It may also return *spuriously*, without consuming the
85aaf69f
SL
113//! token. `thread::park_timeout()` does the same, but allows specifying a
114//! maximum time to block the thread for.
1a4d82fc
JJ
115//!
116//! * The `unpark()` method on a `Thread` atomically makes the token available
117//! if it wasn't already.
118//!
119//! In other words, each `Thread` acts a bit like a semaphore with initial count
120//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
121//! and can return spuriously.
122//!
123//! The API is typically used by acquiring a handle to the current thread,
124//! placing that handle in a shared data structure so that other threads can
125//! find it, and then `park`ing. When some desired condition is met, another
126//! thread calls `unpark` on the handle.
127//!
128//! The motivation for this design is twofold:
129//!
130//! * It avoids the need to allocate mutexes and condvars when building new
131//! synchronization primitives; the threads already provide basic blocking/signaling.
132//!
c34b1796
AL
133//! * It can be implemented very efficiently on many platforms.
134//!
135//! ## Thread-local storage
136//!
137//! This module also provides an implementation of thread local storage for Rust
138//! programs. Thread local storage is a method of storing data into a global
139//! variable which each thread in the program will have its own copy of.
140//! Threads do not share this data, so accesses do not need to be synchronized.
141//!
142//! At a high level, this module provides two variants of storage:
143//!
144//! * Owned thread-local storage. This is a type of thread local key which
145//! owns the value that it contains, and will destroy the value when the
146//! thread exits. This variant is created with the `thread_local!` macro and
147//! can contain any value which is `'static` (no borrowed pointers).
148//!
149//! * Scoped thread-local storage. This type of key is used to store a reference
150//! to a value into local storage temporarily for the scope of a function
151//! call. There are no restrictions on what types of values can be placed
152//! into this key.
153//!
154//! Both forms of thread local storage provide an accessor function, `with`,
155//! which will yield a shared reference to the value to the specified
156//! closure. Thread-local keys only allow shared access to values as there is no
157//! way to guarantee uniqueness if a mutable borrow was allowed. Most values
158//! will want to make use of some form of **interior mutability** through the
159//! `Cell` or `RefCell` types.
1a4d82fc 160
85aaf69f
SL
161#![stable(feature = "rust1", since = "1.0.0")]
162
163use prelude::v1::*;
1a4d82fc 164
d9579d0f 165use alloc::boxed::FnBox;
1a4d82fc 166use any::Any;
1a4d82fc 167use cell::UnsafeCell;
85aaf69f
SL
168use fmt;
169use io;
170use marker::PhantomData;
1a4d82fc 171use rt::{self, unwind};
85aaf69f 172use sync::{Mutex, Condvar, Arc};
c34b1796
AL
173use sys::thread as imp;
174use sys_common::{stack, thread_info};
85aaf69f 175use time::Duration;
1a4d82fc 176
c34b1796
AL
177////////////////////////////////////////////////////////////////////////////////
178// Thread-local storage
179////////////////////////////////////////////////////////////////////////////////
180
9346a6ac
AL
181#[macro_use] mod local;
182#[macro_use] mod scoped_tls;
183
184#[stable(feature = "rust1", since = "1.0.0")]
185pub use self::local::{LocalKey, LocalKeyState};
186
187#[unstable(feature = "scoped_tls",
188 reason = "scoped TLS has yet to have wide enough use to fully \
189 consider stabilizing its interface")]
190pub use self::scoped_tls::ScopedKey;
c34b1796 191
62682a34
SL
192#[doc(hidden)] pub use self::local::__KeyInner as __LocalKeyInner;
193#[doc(hidden)] pub use self::scoped_tls::__KeyInner as __ScopedKeyInner;
c34b1796
AL
194
195////////////////////////////////////////////////////////////////////////////////
196// Builder
197////////////////////////////////////////////////////////////////////////////////
1a4d82fc
JJ
198
199/// Thread configuration. Provides detailed control over the properties
200/// and behavior of new threads.
85aaf69f 201#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
202pub struct Builder {
203 // A name for the thread-to-be, for identification in panic messages
204 name: Option<String>,
205 // The size of the stack for the spawned thread
c34b1796 206 stack_size: Option<usize>,
1a4d82fc
JJ
207}
208
209impl Builder {
9346a6ac 210 /// Generates the base configuration for spawning a thread, from which
1a4d82fc 211 /// configuration methods can be chained.
85aaf69f 212 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
213 pub fn new() -> Builder {
214 Builder {
215 name: None,
216 stack_size: None,
1a4d82fc
JJ
217 }
218 }
219
9346a6ac 220 /// Names the thread-to-be. Currently the name is used for identification
1a4d82fc 221 /// only in panic messages.
85aaf69f 222 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
223 pub fn name(mut self, name: String) -> Builder {
224 self.name = Some(name);
225 self
226 }
227
9346a6ac 228 /// Sets the size of the stack for the new thread.
85aaf69f 229 #[stable(feature = "rust1", since = "1.0.0")]
c34b1796 230 pub fn stack_size(mut self, size: usize) -> Builder {
1a4d82fc
JJ
231 self.stack_size = Some(size);
232 self
233 }
234
9346a6ac 235 /// Spawns a new thread, and returns a join handle for it.
1a4d82fc 236 ///
85aaf69f
SL
237 /// The child thread may outlive the parent (unless the parent thread
238 /// is the main thread; the whole process is terminated when the main
bd371182 239 /// thread finishes). The join handle can be used to block on
85aaf69f
SL
240 /// termination of the child thread, including recovering its panics.
241 ///
242 /// # Errors
243 ///
244 /// Unlike the `spawn` free function, this method yields an
245 /// `io::Result` to capture any failure to create the thread at
246 /// the OS level.
247 #[stable(feature = "rust1", since = "1.0.0")]
9346a6ac
AL
248 pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
249 F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
85aaf69f 250 {
d9579d0f
AL
251 unsafe {
252 self.spawn_inner(Box::new(f)).map(JoinHandle)
253 }
1a4d82fc
JJ
254 }
255
9346a6ac
AL
256 /// Spawns a new child thread that must be joined within a given
257 /// scope, and returns a `JoinGuard`.
1a4d82fc 258 ///
85aaf69f
SL
259 /// The join guard can be used to explicitly join the child thread (via
260 /// `join`), returning `Result<T>`, or it will implicitly join the child
261 /// upon being dropped. Because the child thread may refer to data on the
262 /// current thread's stack (hence the "scoped" name), it cannot be detached;
263 /// it *must* be joined before the relevant stack frame is popped. See the
c1a9b12d 264 /// documentation on `thread::scoped` for additional details.
85aaf69f
SL
265 ///
266 /// # Errors
267 ///
268 /// Unlike the `scoped` free function, this method yields an
269 /// `io::Result` to capture any failure to create the thread at
270 /// the OS level.
9346a6ac
AL
271 #[unstable(feature = "scoped",
272 reason = "memory unsafe if destructor is avoided, see #24292")]
62682a34
SL
273 #[deprecated(since = "1.2.0",
274 reason = "this unsafe API is unlikely to ever be stabilized \
275 in this form")]
85aaf69f 276 pub fn scoped<'a, T, F>(self, f: F) -> io::Result<JoinGuard<'a, T>> where
1a4d82fc
JJ
277 T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
278 {
d9579d0f
AL
279 unsafe {
280 self.spawn_inner(Box::new(f)).map(|inner| {
281 JoinGuard { inner: inner, _marker: PhantomData }
282 })
283 }
1a4d82fc
JJ
284 }
285
d9579d0f
AL
286 // NB: this function is unsafe as the lifetime parameter of the code to run
287 // in the new thread is not tied into the return value, and the return
288 // value must not outlast that lifetime.
289 unsafe fn spawn_inner<'a, T: Send>(self, f: Box<FnBox() -> T + Send + 'a>)
290 -> io::Result<JoinInner<T>> {
c34b1796 291 let Builder { name, stack_size } = self;
1a4d82fc
JJ
292
293 let stack_size = stack_size.unwrap_or(rt::min_stack());
85aaf69f 294
1a4d82fc
JJ
295 let my_thread = Thread::new(name);
296 let their_thread = my_thread.clone();
297
d9579d0f
AL
298 let my_packet = Arc::new(UnsafeCell::new(None));
299 let their_packet = my_packet.clone();
85aaf69f 300
1a4d82fc
JJ
301 // Spawning a new OS thread guarantees that __morestack will never get
302 // triggered, but we must manually set up the actual stack bounds once
303 // this function starts executing. This raises the lower limit by a bit
304 // because by the time that this function is executing we've already
305 // consumed at least a little bit of stack (we don't know the exact byte
306 // address at which our stack started).
85aaf69f 307 let main = move || {
1a4d82fc 308 let something_around_the_top_of_the_stack = 1;
c34b1796
AL
309 let addr = &something_around_the_top_of_the_stack as *const i32;
310 let my_stack_top = addr as usize;
1a4d82fc 311 let my_stack_bottom = my_stack_top - stack_size + 1024;
d9579d0f
AL
312 stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
313
314 if let Some(name) = their_thread.name() {
315 imp::Thread::set_name(name);
85aaf69f 316 }
d9579d0f 317 thread_info::set(imp::guard::current(), their_thread);
1a4d82fc 318
d9579d0f 319 let mut output = None;
1a4d82fc
JJ
320 let try_result = {
321 let ptr = &mut output;
d9579d0f 322 unwind::try(move || *ptr = Some(f()))
1a4d82fc 323 };
d9579d0f
AL
324 *their_packet.get() = Some(try_result.map(|()| {
325 output.unwrap()
326 }));
1a4d82fc
JJ
327 };
328
85aaf69f 329 Ok(JoinInner {
d9579d0f 330 native: Some(try!(imp::Thread::new(stack_size, Box::new(main)))),
85aaf69f 331 thread: my_thread,
d9579d0f 332 packet: Packet(my_packet),
85aaf69f 333 })
1a4d82fc
JJ
334 }
335}
336
c34b1796
AL
337////////////////////////////////////////////////////////////////////////////////
338// Free functions
339////////////////////////////////////////////////////////////////////////////////
340
9346a6ac 341/// Spawns a new thread, returning a `JoinHandle` for it.
85aaf69f 342///
c34b1796
AL
343/// The join handle will implicitly *detach* the child thread upon being
344/// dropped. In this case, the child thread may outlive the parent (unless
345/// the parent thread is the main thread; the whole process is terminated when
346/// the main thread finishes.) Additionally, the join handle provides a `join`
347/// method that can be used to join the child thread. If the child thread
348/// panics, `join` will return an `Err` containing the argument given to
349/// `panic`.
85aaf69f
SL
350///
351/// # Panics
352///
9346a6ac 353/// Panics if the OS fails to create a thread; use `Builder::spawn`
85aaf69f
SL
354/// to recover from such errors.
355#[stable(feature = "rust1", since = "1.0.0")]
9346a6ac
AL
356pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
357 F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
358{
85aaf69f
SL
359 Builder::new().spawn(f).unwrap()
360}
361
9346a6ac 362/// Spawns a new *scoped* thread, returning a `JoinGuard` for it.
85aaf69f 363///
c1a9b12d
SL
364/// The `spawn` method does not allow the child and parent threads to
365/// share any stack data, since that is not safe in general. However,
366/// `scoped` makes it possible to share the parent's stack by forcing
367/// a join before any relevant stack frames are popped:
368///
369/// ```rust
370/// #![feature(scoped)]
371///
372/// use std::thread;
373///
374/// let guard = thread::scoped(move || {
375/// // some work here
376/// });
377///
378/// // do some other work in the meantime
379/// let output = guard.join();
380/// ```
381///
382/// The `scoped` function doesn't return a `Thread` directly; instead, it
383/// returns a *join guard*. The join guard can be used to explicitly join
384/// the child thread (via `join`), returning `Result<T>`, or it will
385/// implicitly join the child upon being dropped. Because the child thread
386/// may refer to data on the current thread's stack (hence the "scoped"
387/// name), it cannot be detached; it *must* be joined before the relevant
388/// stack frame is popped.
85aaf69f
SL
389///
390/// # Panics
391///
9346a6ac 392/// Panics if the OS fails to create a thread; use `Builder::scoped`
85aaf69f 393/// to recover from such errors.
9346a6ac
AL
394#[unstable(feature = "scoped",
395 reason = "memory unsafe if destructor is avoided, see #24292")]
62682a34
SL
396#[deprecated(since = "1.2.0",
397 reason = "this unsafe API is unlikely to ever be stabilized \
398 in this form")]
399#[allow(deprecated)]
85aaf69f
SL
400pub fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T> where
401 T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
402{
403 Builder::new().scoped(f).unwrap()
404}
405
406/// Gets a handle to the thread that invokes it.
407#[stable(feature = "rust1", since = "1.0.0")]
408pub fn current() -> Thread {
d9579d0f
AL
409 thread_info::current_thread().expect("use of std::thread::current() is not \
410 possible after the thread's local \
411 data has been destroyed")
85aaf69f
SL
412}
413
9346a6ac 414/// Cooperatively gives up a timeslice to the OS scheduler.
85aaf69f
SL
415#[stable(feature = "rust1", since = "1.0.0")]
416pub fn yield_now() {
d9579d0f 417 imp::Thread::yield_now()
85aaf69f
SL
418}
419
420/// Determines whether the current thread is unwinding because of panic.
421#[inline]
422#[stable(feature = "rust1", since = "1.0.0")]
423pub fn panicking() -> bool {
424 unwind::panicking()
425}
426
9346a6ac 427/// Invokes a closure, capturing the cause of panic if one occurs.
c34b1796 428///
c1a9b12d
SL
429/// This function will return `Ok` with the closure's result if the closure
430/// does not panic, and will return `Err(cause)` if the closure panics. The
431/// `cause` returned is the object with which panic was originally invoked.
c34b1796
AL
432///
433/// It is currently undefined behavior to unwind from Rust code into foreign
434/// code, so this function is particularly useful when Rust is called from
435/// another language (normally C). This can run arbitrary Rust code, capturing a
436/// panic and allowing a graceful handling of the error.
437///
438/// It is **not** recommended to use this function for a general try/catch
439/// mechanism. The `Result` type is more appropriate to use for functions that
440/// can fail on a regular basis.
441///
442/// The closure provided is required to adhere to the `'static` bound to ensure
443/// that it cannot reference data in the parent stack frame, mitigating problems
444/// with exception safety. Furthermore, a `Send` bound is also required,
445/// providing the same safety guarantees as `thread::spawn` (ensuring the
446/// closure is properly isolated from the parent).
447///
448/// # Examples
449///
450/// ```
c1a9b12d
SL
451/// #![feature(catch_panic)]
452///
c34b1796
AL
453/// use std::thread;
454///
455/// let result = thread::catch_panic(|| {
456/// println!("hello!");
457/// });
458/// assert!(result.is_ok());
459///
460/// let result = thread::catch_panic(|| {
461/// panic!("oh no!");
462/// });
463/// assert!(result.is_err());
464/// ```
465#[unstable(feature = "catch_panic", reason = "recent API addition")]
466pub fn catch_panic<F, R>(f: F) -> Result<R>
467 where F: FnOnce() -> R + Send + 'static
468{
469 let mut result = None;
470 unsafe {
471 let result = &mut result;
472 try!(::rt::unwind::try(move || *result = Some(f())))
473 }
474 Ok(result.unwrap())
475}
476
9346a6ac 477/// Puts the current thread to sleep for the specified amount of time.
c34b1796
AL
478///
479/// The thread may sleep longer than the duration specified due to scheduling
480/// specifics or platform-dependent functionality. Note that on unix platforms
481/// this function will not return early due to a signal being received or a
482/// spurious wakeup.
483#[stable(feature = "rust1", since = "1.0.0")]
484pub fn sleep_ms(ms: u32) {
d9579d0f
AL
485 sleep(Duration::from_millis(ms as u64))
486}
487
488/// Puts the current thread to sleep for the specified amount of time.
489///
490/// The thread may sleep longer than the duration specified due to scheduling
491/// specifics or platform-dependent functionality.
492///
493/// # Platform behavior
494///
495/// On Unix platforms this function will not return early due to a
496/// signal being received or a spurious wakeup. Platforms which do not support
497/// nanosecond precision for sleeping will have `dur` rounded up to the nearest
498/// granularity of time they can sleep for.
499#[unstable(feature = "thread_sleep", reason = "waiting on Duration")]
500pub fn sleep(dur: Duration) {
501 imp::Thread::sleep(dur)
c34b1796
AL
502}
503
c1a9b12d
SL
504/// Blocks unless or until the current thread's token is made available.
505///
506/// Every thread is equipped with some basic low-level blocking support, via
507/// the `park()` function and the [`unpark()`][unpark] method. These can be
508/// used as a more CPU-efficient implementation of a spinlock.
509///
510/// [unpark]: struct.Thread.html#method.unpark
511///
512/// The API is typically used by acquiring a handle to the current thread,
513/// placing that handle in a shared data structure so that other threads can
514/// find it, and then parking (in a loop with a check for the token actually
515/// being acquired).
516///
517/// A call to `park` does not guarantee that the thread will remain parked
518/// forever, and callers should be prepared for this possibility.
519///
520/// See the [module documentation][thread] for more detail.
85aaf69f 521///
c1a9b12d 522/// [thread]: index.html
85aaf69f
SL
523//
524// The implementation currently uses the trivial strategy of a Mutex+Condvar
525// with wakeup flag, which does not actually allow spurious wakeups. In the
526// future, this will be implemented in a more efficient way, perhaps along the lines of
527// http://cr.openjdk.java.net/~stefank/6989984.1/raw_files/new/src/os/linux/vm/os_linux.cpp
528// or futuxes, and in either case may allow spurious wakeups.
529#[stable(feature = "rust1", since = "1.0.0")]
530pub fn park() {
531 let thread = current();
532 let mut guard = thread.inner.lock.lock().unwrap();
533 while !*guard {
534 guard = thread.inner.cvar.wait(guard).unwrap();
535 }
536 *guard = false;
537}
538
9346a6ac 539/// Blocks unless or until the current thread's token is made available or
85aaf69f
SL
540/// the specified duration has been reached (may wake spuriously).
541///
542/// The semantics of this function are equivalent to `park()` except that the
d9579d0f 543/// thread will be blocked for roughly no longer than *ms*. This method
85aaf69f
SL
544/// should not be used for precise timing due to anomalies such as
545/// preemption or platform differences that may not cause the maximum
d9579d0f 546/// amount of time waited to be precisely *ms* long.
85aaf69f
SL
547///
548/// See the module doc for more detail.
c34b1796
AL
549#[stable(feature = "rust1", since = "1.0.0")]
550pub fn park_timeout_ms(ms: u32) {
d9579d0f
AL
551 park_timeout(Duration::from_millis(ms as u64))
552}
553
554/// Blocks unless or until the current thread's token is made available or
555/// the specified duration has been reached (may wake spuriously).
556///
557/// The semantics of this function are equivalent to `park()` except that the
558/// thread will be blocked for roughly no longer than *dur*. This method
559/// should not be used for precise timing due to anomalies such as
560/// preemption or platform differences that may not cause the maximum
561/// amount of time waited to be precisely *dur* long.
562///
563/// See the module doc for more detail.
564///
565/// # Platform behavior
566///
567/// Platforms which do not support nanosecond precision for sleeping will have
568/// `dur` rounded up to the nearest granularity of time they can sleep for.
569#[unstable(feature = "park_timeout", reason = "waiting on Duration")]
570pub fn park_timeout(dur: Duration) {
85aaf69f
SL
571 let thread = current();
572 let mut guard = thread.inner.lock.lock().unwrap();
573 if !*guard {
d9579d0f 574 let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
85aaf69f
SL
575 guard = g;
576 }
577 *guard = false;
578}
579
c34b1796
AL
580////////////////////////////////////////////////////////////////////////////////
581// Thread
582////////////////////////////////////////////////////////////////////////////////
583
85aaf69f 584/// The internal representation of a `Thread` handle
1a4d82fc
JJ
585struct Inner {
586 name: Option<String>,
587 lock: Mutex<bool>, // true when there is a buffered unpark
588 cvar: Condvar,
589}
590
1a4d82fc 591#[derive(Clone)]
85aaf69f 592#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
593/// A handle to a thread.
594pub struct Thread {
595 inner: Arc<Inner>,
596}
597
598impl Thread {
599 // Used only internally to construct a thread object without spawning
600 fn new(name: Option<String>) -> Thread {
601 Thread {
602 inner: Arc::new(Inner {
603 name: name,
604 lock: Mutex::new(false),
605 cvar: Condvar::new(),
606 })
607 }
608 }
609
1a4d82fc
JJ
610 /// Atomically makes the handle's token available if it is not already.
611 ///
612 /// See the module doc for more detail.
85aaf69f 613 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
614 pub fn unpark(&self) {
615 let mut guard = self.inner.lock.lock().unwrap();
616 if !*guard {
617 *guard = true;
618 self.inner.cvar.notify_one();
619 }
620 }
621
9346a6ac 622 /// Gets the thread's name.
85aaf69f 623 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 624 pub fn name(&self) -> Option<&str> {
85aaf69f
SL
625 self.inner.name.as_ref().map(|s| &**s)
626 }
627}
628
629#[stable(feature = "rust1", since = "1.0.0")]
630impl fmt::Debug for Thread {
631 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
632 fmt::Debug::fmt(&self.name(), f)
1a4d82fc
JJ
633 }
634}
635
636// a hack to get around privacy restrictions
637impl thread_info::NewThread for Thread {
638 fn new(name: Option<String>) -> Thread { Thread::new(name) }
639}
640
c34b1796
AL
641////////////////////////////////////////////////////////////////////////////////
642// JoinHandle and JoinGuard
643////////////////////////////////////////////////////////////////////////////////
644
1a4d82fc
JJ
645/// Indicates the manner in which a thread exited.
646///
647/// A thread that completes without panicking is considered to exit successfully.
85aaf69f
SL
648#[stable(feature = "rust1", since = "1.0.0")]
649pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
1a4d82fc 650
d9579d0f
AL
651// This packet is used to communicate the return value between the child thread
652// and the parent thread. Memory is shared through the `Arc` within and there's
653// no need for a mutex here because synchronization happens with `join()` (the
654// parent thread never reads this packet until the child has exited).
655//
656// This packet itself is then stored into a `JoinInner` which in turns is placed
657// in `JoinHandle` and `JoinGuard`. Due to the usage of `UnsafeCell` we need to
658// manually worry about impls like Send and Sync. The type `T` should
659// already always be Send (otherwise the thread could not have been created) and
660// this type is inherently Sync because no methods take &self. Regardless,
661// however, we add inheriting impls for Send/Sync to this type to ensure it's
662// Send/Sync and that future modifications will still appropriately classify it.
1a4d82fc
JJ
663struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
664
d9579d0f
AL
665unsafe impl<T: Send> Send for Packet<T> {}
666unsafe impl<T: Sync> Sync for Packet<T> {}
1a4d82fc 667
85aaf69f
SL
668/// Inner representation for JoinHandle and JoinGuard
669struct JoinInner<T> {
d9579d0f 670 native: Option<imp::Thread>,
85aaf69f
SL
671 thread: Thread,
672 packet: Packet<T>,
85aaf69f
SL
673}
674
675impl<T> JoinInner<T> {
676 fn join(&mut self) -> Result<T> {
d9579d0f 677 self.native.take().unwrap().join();
85aaf69f
SL
678 unsafe {
679 (*self.packet.0.get()).take().unwrap()
680 }
681 }
682}
683
684/// An owned permission to join on a thread (block on its termination).
685///
686/// Unlike a `JoinGuard`, a `JoinHandle` *detaches* the child thread
687/// when it is dropped, rather than automatically joining on drop.
688///
689/// Due to platform restrictions, it is not possible to `Clone` this
690/// handle: the ability to join a child thread is a uniquely-owned
691/// permission.
692#[stable(feature = "rust1", since = "1.0.0")]
9346a6ac 693pub struct JoinHandle<T>(JoinInner<T>);
85aaf69f 694
9346a6ac
AL
695impl<T> JoinHandle<T> {
696 /// Extracts a handle to the underlying thread
85aaf69f
SL
697 #[stable(feature = "rust1", since = "1.0.0")]
698 pub fn thread(&self) -> &Thread {
699 &self.0.thread
700 }
701
9346a6ac 702 /// Waits for the associated thread to finish.
85aaf69f
SL
703 ///
704 /// If the child thread panics, `Err` is returned with the parameter given
705 /// to `panic`.
706 #[stable(feature = "rust1", since = "1.0.0")]
9346a6ac 707 pub fn join(mut self) -> Result<T> {
85aaf69f
SL
708 self.0.join()
709 }
710}
711
1a4d82fc
JJ
712/// An RAII-style guard that will block until thread termination when dropped.
713///
714/// The type `T` is the return type for the thread's main function.
85aaf69f
SL
715///
716/// Joining on drop is necessary to ensure memory safety when stack
717/// data is shared between a parent and child thread.
718///
719/// Due to platform restrictions, it is not possible to `Clone` this
720/// handle: the ability to join a child thread is a uniquely-owned
721/// permission.
c34b1796 722#[must_use = "thread will be immediately joined if `JoinGuard` is not used"]
9346a6ac
AL
723#[unstable(feature = "scoped",
724 reason = "memory unsafe if destructor is avoided, see #24292")]
c34b1796 725pub struct JoinGuard<'a, T: Send + 'a> {
85aaf69f
SL
726 inner: JoinInner<T>,
727 _marker: PhantomData<&'a T>,
1a4d82fc
JJ
728}
729
85aaf69f 730#[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc
JJ
731unsafe impl<'a, T: Send + 'a> Sync for JoinGuard<'a, T> {}
732
733impl<'a, T: Send + 'a> JoinGuard<'a, T> {
9346a6ac 734 /// Extracts a handle to the thread this guard will join on.
85aaf69f 735 #[stable(feature = "rust1", since = "1.0.0")]
1a4d82fc 736 pub fn thread(&self) -> &Thread {
85aaf69f 737 &self.inner.thread
1a4d82fc
JJ
738 }
739
9346a6ac 740 /// Waits for the associated thread to finish, returning the result of the
c34b1796 741 /// thread's calculation.
1a4d82fc 742 ///
85aaf69f
SL
743 /// # Panics
744 ///
745 /// Panics on the child thread are propagated by panicking the parent.
746 #[stable(feature = "rust1", since = "1.0.0")]
747 pub fn join(mut self) -> T {
748 match self.inner.join() {
749 Ok(res) => res,
750 Err(_) => panic!("child thread {:?} panicked", self.thread()),
1a4d82fc
JJ
751 }
752 }
753}
754
9346a6ac
AL
755#[unstable(feature = "scoped",
756 reason = "memory unsafe if destructor is avoided, see #24292")]
1a4d82fc
JJ
757impl<'a, T: Send + 'a> Drop for JoinGuard<'a, T> {
758 fn drop(&mut self) {
d9579d0f
AL
759 if self.inner.native.is_some() && self.inner.join().is_err() {
760 panic!("child thread {:?} panicked", self.thread());
1a4d82fc
JJ
761 }
762 }
763}
764
d9579d0f
AL
765fn _assert_sync_and_send() {
766 fn _assert_both<T: Send + Sync>() {}
767 _assert_both::<JoinHandle<()>>();
768 _assert_both::<JoinGuard<()>>();
769 _assert_both::<Thread>();
770}
771
c34b1796
AL
772////////////////////////////////////////////////////////////////////////////////
773// Tests
774////////////////////////////////////////////////////////////////////////////////
775
1a4d82fc 776#[cfg(test)]
d9579d0f 777mod tests {
1a4d82fc
JJ
778 use prelude::v1::*;
779
780 use any::Any;
781 use sync::mpsc::{channel, Sender};
1a4d82fc 782 use result;
c34b1796 783 use super::{Builder};
85aaf69f 784 use thread;
1a4d82fc 785 use thunk::Thunk;
85aaf69f 786 use time::Duration;
c34b1796 787 use u32;
1a4d82fc
JJ
788
789 // !!! These tests are dangerous. If something is buggy, they will hang, !!!
790 // !!! instead of exiting cleanly. This might wedge the buildbots. !!!
791
792 #[test]
793 fn test_unnamed_thread() {
85aaf69f
SL
794 thread::spawn(move|| {
795 assert!(thread::current().name().is_none());
796 }).join().ok().unwrap();
1a4d82fc
JJ
797 }
798
799 #[test]
800 fn test_named_thread() {
801 Builder::new().name("ada lovelace".to_string()).scoped(move|| {
85aaf69f
SL
802 assert!(thread::current().name().unwrap() == "ada lovelace".to_string());
803 }).unwrap().join();
1a4d82fc
JJ
804 }
805
806 #[test]
807 fn test_run_basic() {
808 let (tx, rx) = channel();
85aaf69f 809 thread::spawn(move|| {
1a4d82fc
JJ
810 tx.send(()).unwrap();
811 });
812 rx.recv().unwrap();
813 }
814
815 #[test]
816 fn test_join_success() {
85aaf69f 817 assert!(thread::scoped(move|| -> String {
1a4d82fc 818 "Success!".to_string()
85aaf69f 819 }).join() == "Success!");
1a4d82fc
JJ
820 }
821
822 #[test]
823 fn test_join_panic() {
85aaf69f 824 match thread::spawn(move|| {
1a4d82fc
JJ
825 panic!()
826 }).join() {
827 result::Result::Err(_) => (),
828 result::Result::Ok(()) => panic!()
829 }
830 }
831
85aaf69f
SL
832 #[test]
833 fn test_scoped_success() {
834 let res = thread::scoped(move|| -> String {
835 "Success!".to_string()
836 }).join();
837 assert!(res == "Success!");
838 }
839
840 #[test]
c34b1796 841 #[should_panic]
85aaf69f
SL
842 fn test_scoped_panic() {
843 thread::scoped(|| panic!()).join();
844 }
845
846 #[test]
c34b1796 847 #[should_panic]
85aaf69f 848 fn test_scoped_implicit_panic() {
c34b1796 849 let _ = thread::scoped(|| panic!());
85aaf69f
SL
850 }
851
1a4d82fc
JJ
852 #[test]
853 fn test_spawn_sched() {
854 use clone::Clone;
855
856 let (tx, rx) = channel();
857
c34b1796 858 fn f(i: i32, tx: Sender<()>) {
1a4d82fc 859 let tx = tx.clone();
85aaf69f 860 thread::spawn(move|| {
1a4d82fc
JJ
861 if i == 0 {
862 tx.send(()).unwrap();
863 } else {
864 f(i - 1, tx);
865 }
866 });
867
868 }
869 f(10, tx);
870 rx.recv().unwrap();
871 }
872
873 #[test]
874 fn test_spawn_sched_childs_on_default_sched() {
875 let (tx, rx) = channel();
876
85aaf69f
SL
877 thread::spawn(move|| {
878 thread::spawn(move|| {
1a4d82fc
JJ
879 tx.send(()).unwrap();
880 });
881 });
882
883 rx.recv().unwrap();
884 }
885
85aaf69f 886 fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
c34b1796 887 let (tx, rx) = channel();
1a4d82fc 888
c34b1796
AL
889 let x: Box<_> = box 1;
890 let x_in_parent = (&*x) as *const i32 as usize;
1a4d82fc 891
c34b1796
AL
892 spawnfn(Box::new(move|| {
893 let x_in_child = (&*x) as *const i32 as usize;
1a4d82fc
JJ
894 tx.send(x_in_child).unwrap();
895 }));
896
897 let x_in_child = rx.recv().unwrap();
898 assert_eq!(x_in_parent, x_in_child);
899 }
900
901 #[test]
902 fn test_avoid_copying_the_body_spawn() {
903 avoid_copying_the_body(|v| {
c34b1796 904 thread::spawn(move || v());
1a4d82fc
JJ
905 });
906 }
907
908 #[test]
909 fn test_avoid_copying_the_body_thread_spawn() {
910 avoid_copying_the_body(|f| {
85aaf69f 911 thread::spawn(move|| {
c34b1796 912 f();
1a4d82fc
JJ
913 });
914 })
915 }
916
917 #[test]
918 fn test_avoid_copying_the_body_join() {
919 avoid_copying_the_body(|f| {
85aaf69f 920 let _ = thread::spawn(move|| {
c34b1796 921 f()
1a4d82fc
JJ
922 }).join();
923 })
924 }
925
926 #[test]
927 fn test_child_doesnt_ref_parent() {
bd371182
AL
928 // If the child refcounts the parent thread, this will stack overflow when
929 // climbing the thread tree to dereference each ancestor. (See #1789)
1a4d82fc
JJ
930 // (well, it would if the constant were 8000+ - I lowered it to be more
931 // valgrind-friendly. try this at home, instead..!)
c34b1796
AL
932 const GENERATIONS: u32 = 16;
933 fn child_no(x: u32) -> Thunk<'static> {
934 return Box::new(move|| {
1a4d82fc 935 if x < GENERATIONS {
c34b1796 936 thread::spawn(move|| child_no(x+1)());
1a4d82fc
JJ
937 }
938 });
939 }
c34b1796 940 thread::spawn(|| child_no(0)());
1a4d82fc
JJ
941 }
942
943 #[test]
944 fn test_simple_newsched_spawn() {
85aaf69f 945 thread::spawn(move || {});
1a4d82fc
JJ
946 }
947
948 #[test]
949 fn test_try_panic_message_static_str() {
85aaf69f 950 match thread::spawn(move|| {
1a4d82fc
JJ
951 panic!("static string");
952 }).join() {
953 Err(e) => {
954 type T = &'static str;
955 assert!(e.is::<T>());
c34b1796 956 assert_eq!(*e.downcast::<T>().unwrap(), "static string");
1a4d82fc
JJ
957 }
958 Ok(()) => panic!()
959 }
960 }
961
962 #[test]
963 fn test_try_panic_message_owned_str() {
85aaf69f 964 match thread::spawn(move|| {
1a4d82fc
JJ
965 panic!("owned string".to_string());
966 }).join() {
967 Err(e) => {
968 type T = String;
969 assert!(e.is::<T>());
c34b1796 970 assert_eq!(*e.downcast::<T>().unwrap(), "owned string".to_string());
1a4d82fc
JJ
971 }
972 Ok(()) => panic!()
973 }
974 }
975
976 #[test]
977 fn test_try_panic_message_any() {
85aaf69f 978 match thread::spawn(move|| {
1a4d82fc
JJ
979 panic!(box 413u16 as Box<Any + Send>);
980 }).join() {
981 Err(e) => {
982 type T = Box<Any + Send>;
983 assert!(e.is::<T>());
c34b1796 984 let any = e.downcast::<T>().unwrap();
1a4d82fc 985 assert!(any.is::<u16>());
c34b1796 986 assert_eq!(*any.downcast::<u16>().unwrap(), 413);
1a4d82fc
JJ
987 }
988 Ok(()) => panic!()
989 }
990 }
991
992 #[test]
993 fn test_try_panic_message_unit_struct() {
994 struct Juju;
995
85aaf69f 996 match thread::spawn(move|| {
1a4d82fc
JJ
997 panic!(Juju)
998 }).join() {
999 Err(ref e) if e.is::<Juju>() => {}
1000 Err(_) | Ok(()) => panic!()
1001 }
1002 }
1003
85aaf69f
SL
1004 #[test]
1005 fn test_park_timeout_unpark_before() {
1006 for _ in 0..10 {
1007 thread::current().unpark();
c34b1796 1008 thread::park_timeout_ms(u32::MAX);
85aaf69f
SL
1009 }
1010 }
1011
1012 #[test]
1013 fn test_park_timeout_unpark_not_called() {
1014 for _ in 0..10 {
c34b1796 1015 thread::park_timeout_ms(10);
85aaf69f
SL
1016 }
1017 }
1018
1019 #[test]
1020 fn test_park_timeout_unpark_called_other_thread() {
85aaf69f
SL
1021 for _ in 0..10 {
1022 let th = thread::current();
1023
1024 let _guard = thread::spawn(move || {
9346a6ac 1025 super::sleep_ms(50);
85aaf69f
SL
1026 th.unpark();
1027 });
1028
c34b1796 1029 thread::park_timeout_ms(u32::MAX);
85aaf69f
SL
1030 }
1031 }
1032
c34b1796
AL
1033 #[test]
1034 fn sleep_ms_smoke() {
1035 thread::sleep_ms(2);
1036 }
1037
bd371182 1038 // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due
1a4d82fc
JJ
1039 // to the test harness apparently interfering with stderr configuration.
1040}