|
1 | 1 | use crate::parallel::Reduce;
|
2 | 2 |
|
3 |
| -/// Runs `left` and then `right`, one after another, returning their output when both are done. |
4 | 3 | #[cfg(not(feature = "parallel"))]
|
5 |
| -pub fn join<O1, O2>(left: impl FnOnce() -> O1, right: impl FnOnce() -> O2) -> (O1, O2) { |
6 |
| - (left(), right()) |
| 4 | +mod not_parallel { |
| 5 | + /// Runs `left` and then `right`, one after another, returning their output when both are done. |
| 6 | + pub fn join<O1, O2>(left: impl FnOnce() -> O1, right: impl FnOnce() -> O2) -> (O1, O2) { |
| 7 | + (left(), right()) |
| 8 | + } |
| 9 | + |
| 10 | + /// A scope for spawning threads. |
| 11 | + pub struct Scope<'env> { |
| 12 | + _marker: std::marker::PhantomData<&'env mut &'env ()>, |
| 13 | + } |
| 14 | + |
| 15 | + #[allow(unsafe_code)] |
| 16 | + unsafe impl Sync for Scope<'_> {} |
| 17 | + |
| 18 | + impl<'env> Scope<'env> { |
| 19 | + pub fn spawn<'scope, F, T>(&'scope self, f: F) -> ScopedJoinHandle<'scope, T> |
| 20 | + where |
| 21 | + F: FnOnce(&Scope<'env>) -> T, |
| 22 | + F: Send + 'env, |
| 23 | + T: Send + 'env, |
| 24 | + { |
| 25 | + ScopedJoinHandle { |
| 26 | + result: f(self), |
| 27 | + _marker: Default::default(), |
| 28 | + } |
| 29 | + } |
| 30 | + } |
| 31 | + |
| 32 | + /// Runs `f` with a scope to be used for spawning threads that will not outlive the function call. |
| 33 | + /// Note that this implementation will run the spawned functions immediately. |
| 34 | + pub fn threads<'env, F, R>(f: F) -> std::thread::Result<R> |
| 35 | + where |
| 36 | + F: FnOnce(&Scope<'env>) -> R, |
| 37 | + { |
| 38 | + Ok(f(&Scope { |
| 39 | + _marker: Default::default(), |
| 40 | + })) |
| 41 | + } |
| 42 | + |
| 43 | + /// A handle that can be used to join its scoped thread. |
| 44 | + /// |
| 45 | + /// This struct is created by the [`Scope::spawn`] method and the |
| 46 | + /// [`ScopedThreadBuilder::spawn`] method. |
| 47 | + pub struct ScopedJoinHandle<'scope, T> { |
| 48 | + /// Holds the result of the inner closure. |
| 49 | + result: T, |
| 50 | + _marker: std::marker::PhantomData<&'scope mut &'scope ()>, |
| 51 | + } |
| 52 | + |
| 53 | + impl<T> ScopedJoinHandle<'_, T> { |
| 54 | + pub fn join(self) -> std::thread::Result<T> { |
| 55 | + Ok(self.result) |
| 56 | + } |
| 57 | + } |
7 | 58 | }
|
| 59 | +#[cfg(not(feature = "parallel"))] |
| 60 | +pub use not_parallel::{join, threads, Scope, ScopedJoinHandle}; |
8 | 61 |
|
9 | 62 | /// Read items from `input` and `consume` them in a single thread, producing an output to be collected by a `reducer`,
|
10 | 63 | /// whose task is to aggregate these outputs into the final result returned by this function.
|
|
0 commit comments