use super::pool;
use super::pool::{Error, Pool};
use std::borrow::BorrowMut;
use std::collections::VecDeque;
use std::process::{Child, Command, Stdio};
#[derive(Debug)]
pub struct Limiting<C> {
procs: VecDeque<Child>,
max_procs: usize,
command: C,
}
impl<C: BorrowMut<Command>> Limiting<C> {
pub fn new(mut command: C, max_procs: usize) -> Self {
command.borrow_mut().stdin(Stdio::piped());
Limiting {
procs: VecDeque::with_capacity(max_procs),
max_procs,
command,
}
}
}
impl<C: BorrowMut<Command>> Pool for Limiting<C> {
fn get(&mut self) -> Result<&mut Child, Error> {
if self.max_procs != 0 && self.procs.len() == self.max_procs {
pool::wait_proc(self.procs.pop_front().unwrap())?;
};
let proc = self.command.borrow_mut().spawn().map_err(Error::Spawn)?;
self.procs.push_back(proc);
Ok(self.procs.back_mut().unwrap()) }
fn join(&mut self) -> Result<(), Error> {
while let Some(proc) = self.procs.pop_back() {
pool::wait_proc(proc)?;
}
Ok(())
}
}
impl<C> Drop for Limiting<C> {
fn drop(&mut self) {
for proc in &mut self.procs {
let _ = proc.kill();
}
for proc in &mut self.procs {
let _ = proc.wait();
}
}
}