1use std::sync::{
2 Arc, Mutex,
3 mpsc,
4 mpsc::Sender
5};
6
7use crate::{
8 Bottle,
9 Heater,
10 Ice, IceBox,
11};
12
13
14
15pub struct Melter {
19 heaters: Vec<Heater>,
20 ice_boxes: Sender<IceBox>
21}
22
23impl Melter {
24 pub fn new(count: usize) -> Melter {
30 assert!(count > 0, "ice_threads::Melter::new -> Heater count must be greater than 0!");
31
32 let mut heaters = Vec::with_capacity(count);
33
34 let (sender, receiver) = mpsc::channel();
35
36 let receiver = Arc::new(Mutex::new(receiver));
37 for _ in 0..count {
38 heaters.push(Heater::new(receiver.clone()));
39 }
40
41 Melter {
42 heaters,
43 ice_boxes: sender
44 }
45 }
46
47 #[must_use]
60 pub fn melt<I, W>(&self, ice: I) -> Bottle<W>
61 where
62 I: FnOnce() -> W + Send + 'static,
63 W: Send + 'static
64 {
65 let (sender, receiver) = mpsc::channel::<W>();
66 let ice_box = IceBox::Some(
67 Ice::new(move || {
68 sender.send(ice()).ok();
69 })
70 );
71
72 self.ice_boxes
73 .send(ice_box)
74 .expect("ice_threads::Melter::melt -> Failed to send Ice box to a Heater group");
75
76 Bottle::new(receiver)
77 }
78}
79
80impl Drop for Melter {
81 fn drop(&mut self) {
83 for _ in &self.heaters {
84 if self.ice_boxes.send(IceBox::None).is_err() {
85 break;
86 }
87 }
88
89 for heater in &mut self.heaters {
90 if let Some(core) = heater.take_core() {
91 core.join().ok();
92 }
93 }
94 }
95}