use std::thread; use std::sync::{Arc, Mutex}; use std::sync::mpsc::{channel, Sender, Receiver, SendError, RecvError}; use std::rc::*; use std::cell::RefCell; use std::rc::Rc; #[macro_export] macro_rules! create_pools { ($n:expr) => { { let mut pools = $crate::rotating_list::RotatingList::new(); for _ in 0..$n { let mut pool = $crate::pool::Pool::spawn(|x| { funcall(x); }); pool.join_on_drop = true; pools.push(pool); } pools } } } #[macro_export] macro_rules! send { ($i:expr, $($e:expr),+) => { $( $i.send($e).unwrap(); )+ } } pub struct Pool where T:std::marker::Send+ 'static { sender: Sender>, thread: Option>, pub join_on_drop: bool, } impl Pool { pub fn spawn(mut lam: F) -> Self { let (tx, rx): (Sender>, Receiver>) = channel(); let thread = Some(thread::spawn(move || { loop { let value = match rx.recv() { Ok(v) => v, Err(_) => break, }; if let Some(value) = value { lam(value); } else { break; } } })); Self { sender: tx, thread: thread, join_on_drop: false, } } pub fn join(&mut self) { if let Some(thread) = self.thread.take() { let _ = thread.join(); } } pub fn close(&mut self) -> Result<(), SendError>> { self.sender.send(None) } pub fn send(&mut self, value: T) -> Result<(), SendError>> { self.sender.send(Some(value)) } } impl Drop for Pool { fn drop(&mut self) { let _ = self.close(); if self.join_on_drop { self.join(); } } }