use super::pool;
use super::pool::{Error, Pool};
use std::borrow::BorrowMut;
use std::process::{Child, Command, Stdio};
#[derive(Debug)]
pub struct Rotating<C> {
procs: Vec<Child>,
max_procs: usize,
command: C,
ind: usize,
}
impl<C: BorrowMut<Command>> Rotating<C> {
pub fn new(mut command: C, max_procs: usize) -> Self {
command.borrow_mut().stdin(Stdio::piped());
Self {
procs: Vec::with_capacity(max_procs),
max_procs,
command,
ind: 0,
}
}
fn spawn(&mut self) -> Result<Child, Error> {
self.command.borrow_mut().spawn().map_err(Error::Spawn)
}
}
impl<C: BorrowMut<Command>> Pool for Rotating<C> {
fn get(&mut self) -> Result<&mut Child, Error> {
if self.max_procs == 0 {
let proc = self.spawn()?;
self.procs.push(proc);
Ok(self.procs.last_mut().unwrap())
} else {
if self.procs.len() < self.max_procs {
let proc = self.spawn()?;
self.procs.push(proc);
}
let child = &mut self.procs[self.ind];
self.ind += 1;
self.ind %= self.max_procs;
Ok(child)
}
}
fn join(&mut self) -> Result<(), Error> {
while let Some(proc) = self.procs.pop() {
pool::wait_proc(proc)?;
}
Ok(())
}
}
impl<C> Drop for Rotating<C> {
fn drop(&mut self) {
for proc in &mut self.procs {
let _ = proc.kill();
}
for proc in &mut self.procs {
let _ = proc.wait();
}
}
}