thread-group 1.0.0

std::thread::ThreadGroup prototype
//! `std::thread::ThreadGroup` prototype
//!
//! # What issue does this crate address?
//!
//! Rust's stdlib has support for threads, but has no way to call `Thread::join`
//! on multiple threads. This means that if you want to join threads you need to
//! collect `JoinHandle`s in a vec, and then call `join` on each one
//! in a loop. While useful, it's not quite multiple threads acting like a
//! single unit. For example if a single thread panics, we won't find out until
//! the loop has reached the right join handle.
//!
//! ```panic
//! use std::thread;
//! use std::time::Duration;
//!
//! let mut threads = vec![];
//! for i in 0..5 {
//!     let handle = thread::spawn(move || match i {
//!         4 => panic!("oh no!"),
//!         _ => thread::sleep(Duration::from_secs(1)),
//!     });
//!     threads.push(handle);
//! }
//!
//! for (i, handle) in threads.into_iter().enumerate() {
//!     println!("joining thread #{}", i);
//!     handle
//!         .join()
//!         .unwrap_or_else(|_| panic!("thread #{} panicked", i));
//! }
//! ```
//!
//! Output:
//!
//! ```txt
//! joining thread #0
//! thread '<unnamed>' panicked at 'oh no!', examples\manual.rs:8:18
//! note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
//! joining thread #1
//! joining thread #2
//! joining thread #3
//! joining thread #4
//! thread 'main' panicked at 'thread #4 panicked', examples\manual.rs:18:33
//! ```
//!
//! # How does this crate solve that?
//!
//! 1. Each thread in the group has a panic handler installed
//! 2. If a thread panics, it triggers a state change on a Condvar
//! 3. We then find the thread handle related to the panic and retrieve the result
//! 4. If no panics occur we wait for all threads to finish in the condvar
//!
//! This simple mechanism allows us to short-circuit joins on panic. And if the
//! stdlib gains the ability to cancel threads, we can cancel work in other
//! threads when a panic occurs. This enables reasoning about a group of threads
//! as if it were a single thread.
//!
//! # Is all of this sound?
//!
//! I'm not an expert so I can't give you a conclusive answer. I've adapted the
//! crossbeam scope code for this to work, and to my knowledge didn't violate any
//! of its constraints. But it's hard to say for sure; we're transmuting closures
//! to do things to lifetimes, so it may very well not work as intended.

#![deny(missing_debug_implementations, nonstandard_style)]
#![warn(missing_docs, missing_doc_code_examples, unreachable_pub)]
#![warn(rust_2018_idioms, future_incompatible)]

pub use thread_group::*;

mod thread_group;
mod wait_group;