Below is the example from crossbeam deque documemtation.
use crossbeam_deque::{Injector, Stealer, Worker};
use std::iter;
fn find_task<T>(
local: &Worker<T>,
global: &Injector<T>,
stealers: &[Stealer<T>],
) -> Option<T> {
// Pop a task from the local queue, if not empty.
local.pop().or_else(|| {
// Otherwise, we need to look for a task elsewhere.
iter::repeat_with(|| {
// Try stealing a batch of tasks from the global queue.
global.steal_batch_and_pop(local)
// Or try stealing a task from one of the other threads.
.or_else(|| stealers.iter().map(|s| s.steal()).collect())
})
// Loop while no task was stolen and any steal operation needs to be retried.
.find(|s| !s.is_retry())
// Extract the stolen task, if there is one.
.and_then(|s| s.success())
})
}
My question is about this line:
.or_else(|| stealers.iter().map(|s| s.steal()).collect())
It collects jobs stolen from all stealers, but only handle the first one successful. If there are multiple Steal::Success
es, will some jobs get missed?
The collect
impl is as follows:
impl<T> FromIterator<Steal<T>> for Steal<T> {
/// Consumes items until a `Success` is found and returns it.
///
/// If no `Success` was found, but there was at least one `Retry`, then returns `Retry`.
/// Otherwise, `Empty` is returned.
fn from_iter<I>(iter: I) -> Steal<T>
where
I: IntoIterator<Item = Steal<T>>,
{
let mut retry = false;
for s in iter {
match &s {
Steal::Empty => {}
Steal::Success(_) => return s,
Steal::Retry => retry = true,
}
}
if retry {
Steal::Retry
} else {
Steal::Empty
}
}
}