pub struct SharedThread<T> { /* private fields */ }Expand description
A wrapper around std::thread::JoinHandle that allows for multiple waiters.
The high-level differences between SharedThread and JoinHandle are:
jointakes&selfrather than&mut self.joinreturns&Trather thanT. For taking ownership ofT, seeinto_output.SharedThreadalso providesjoin_timeout,join_deadline, andtry_join.- Rather than converting panics in into
std::thread::Result, which usually requires the caller to.unwrap()every.join(),SharedThreadpropagates panics automatically.
§Example
use shared_thread::SharedThread;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
// Use this flag to tell our shared thread when to stop.
static EXIT_FLAG: AtomicBool = AtomicBool::new(false);
// Start a background thread that we'll share with several waiting threads.
let shared_thread = SharedThread::spawn(|| {
// Pretend this is some expensive, useful background work...
while (!EXIT_FLAG.load(Relaxed)) {}
42
});
// It's up to you how to share the SharedThread object with other threads. In this sense it's
// like any other object you might need to share, like say a HashMap or a File. The common
// options are to put it in an Arc, or to let "scoped" threads borrow it directly. Let's use
// scoped threads.
std::thread::scope(|scope| {
// Spawn three waiter threads that each wait on the shared thread.
let waiter1 = scope.spawn(|| shared_thread.join());
let waiter2 = scope.spawn(|| shared_thread.join());
let waiter3 = scope.spawn(|| shared_thread.join());
// In this example, the shared thread is going to keep looping until we set the EXIT_FLAG.
// In the meantime, .is_finished() returns false, and .try_join() returns None.
assert!(!shared_thread.is_finished());
assert_eq!(shared_thread.try_join(), None);
// Ask the shared thread to stop looping.
EXIT_FLAG.store(true, Relaxed);
// Now all the calls to .join() above will return quickly, and each of the waiter threads
// will get a reference to the shared thread's output, &42.
assert_eq!(*waiter1.join().unwrap(), 42);
assert_eq!(*waiter2.join().unwrap(), 42);
assert_eq!(*waiter3.join().unwrap(), 42);
// Now that the shared thread has finished, .is_finished() returns true, and .try_join()
// returns Some(&42).
assert!(shared_thread.is_finished());
assert_eq!(*shared_thread.try_join().unwrap(), 42);
});
// We can take ownership of the output by consuming the SharedThread object. As with any
// non-Copy type in Rust, this requires that the SharedThread is not borrowed.
assert_eq!(shared_thread.into_output(), 42);Implementations§
Sourcepub fn join(&self) -> &T
pub fn join(&self) -> &T
Wait for the shared thread to finish, then return &T. This blocks the current thread.
§Panics
This function panics if the shared thread panicked. The original panic is propagated
directly with resume_unwind
the first time. Subsequent calls panic with a generic message.
Sourcepub fn join_timeout(&self, timeout: Duration) -> Option<&T>
pub fn join_timeout(&self, timeout: Duration) -> Option<&T>
Wait with a timeout for the shared thread to finish. If it finishes in time (or it already
finished), return Some(&T), otherwise return None. This blocks the current thread.
§Panics
This function panics if the shared thread panicked. The original panic is propagated
directly with resume_unwind
the first time it’s observed. Subsequent calls panic with a generic message.
Sourcepub fn join_deadline(&self, deadline: Instant) -> Option<&T>
pub fn join_deadline(&self, deadline: Instant) -> Option<&T>
Wait with a deadline for the shared thread to finish. If it finishes in time (or it already
finished), return Some(&T), otherwise return None. This blocks the current thread.
§Panics
This function panics if the shared thread panicked. The original panic is propagated
directly with resume_unwind
the first time it’s observed. Subsequent calls panic with a generic message.
Sourcepub fn try_join(&self) -> Option<&T>
pub fn try_join(&self) -> Option<&T>
Return Some(&T) if the shared thread has already finished, otherwise None. This always
returns quickly.
§Panics
This function panics if the shared thread panicked. The original panic is propagated
directly with resume_unwind
the first time it’s observed. Subsequent calls panic with a generic message.
Sourcepub fn into_output(self) -> T
pub fn into_output(self) -> T
Wait for the shared thread to finish, then return T. This blocks the current. This
requires ownership of the SharedThread and consumes it.
§Panics
This function panics if the shared thread panicked. The original panic is propagated
directly with resume_unwind
the first time it’s observed. Subsequent calls panic with a generic message.
Sourcepub fn is_finished(&self) -> bool
pub fn is_finished(&self) -> bool
Return true if the shared thread has finished, false otherwise.
This function never blocks. If it returns true, try_join,
join_timeout, and join_deadline are
guaranteed not to return None, and all join functions are guaranteed to return quickly.