fd/src/exec/job.rs

60 lines
2.0 KiB
Rust
Raw Normal View History

2018-09-30 22:56:32 +02:00
use super::CommandTemplate;
2020-02-22 10:39:03 +01:00
use crate::exit_codes::{merge_exitcodes, ExitCode};
use crate::walk::WorkerResult;
2017-10-14 18:04:11 +02:00
use std::path::PathBuf;
use std::sync::mpsc::Receiver;
2018-04-13 22:46:17 +02:00
use std::sync::{Arc, Mutex};
2017-10-14 18:04:11 +02:00
/// An event loop that listens for inputs from the `rx` receiver. Each received input will
/// generate a command with the supplied command template. The generated command will then
/// be executed, and this process will continue until the receiver's sender has closed.
2018-09-30 22:56:32 +02:00
pub fn job(
rx: Arc<Mutex<Receiver<WorkerResult>>>,
cmd: Arc<CommandTemplate>,
out_perm: Arc<Mutex<()>>,
2018-10-22 14:20:08 +02:00
show_filesystem_errors: bool,
) -> ExitCode {
let mut results: Vec<ExitCode> = Vec::new();
2017-10-14 18:04:11 +02:00
loop {
// Create a lock on the shared receiver for this thread.
let lock = rx.lock().unwrap();
2018-10-01 21:29:54 +02:00
// Obtain the next result from the receiver, else if the channel
2017-10-14 18:04:11 +02:00
// has closed, exit from the loop
2017-10-14 22:42:47 +02:00
let value: PathBuf = match lock.recv() {
2018-10-01 21:29:54 +02:00
Ok(WorkerResult::Entry(val)) => val,
Ok(WorkerResult::Error(err)) => {
2018-10-22 14:20:08 +02:00
if show_filesystem_errors {
print_error!("{}", err);
}
2018-10-01 21:29:54 +02:00
continue;
}
2017-10-14 20:04:04 +02:00
Err(_) => break,
2017-10-14 18:04:11 +02:00
};
// Drop the lock so that other threads can read from the receiver.
2017-10-14 18:04:11 +02:00
drop(lock);
2020-01-26 14:06:18 +01:00
// Generate a command, execute it and store its exit code.
results.push(cmd.generate_and_execute(&value, Arc::clone(&out_perm)))
2017-10-14 18:04:11 +02:00
}
// Returns error in case of any error.
merge_exitcodes(results)
2017-10-14 20:04:04 +02:00
}
pub fn batch(
rx: Receiver<WorkerResult>,
cmd: &CommandTemplate,
show_filesystem_errors: bool,
) -> ExitCode {
let paths = rx.iter().filter_map(|value| match value {
WorkerResult::Entry(val) => Some(val),
WorkerResult::Error(err) => {
if show_filesystem_errors {
print_error!("{}", err);
}
None
}
});
cmd.generate_and_execute_batch(paths)
}