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