Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
2.3 kB
0
Indexable
Never
use std::fmt::Display;
use std::sync::{Arc, mpsc, Mutex};
use std::sync::mpsc::Sender;
use std::thread;
use std::thread::JoinHandle;
use std::time::Duration;

struct Looper<T>
{
    queue: Mutex<Sender<T>>,
    cleaner: Mutex<Box<dyn Fn() -> () + Send + 'static>>,
    handle: Option<JoinHandle<()>>,
}

impl <T>Drop for Looper<T> {
    fn drop(&mut self) {
        println!("chiamato il dropper!");
        let state = self.cleaner.lock().unwrap();
        (*state)();
        //(self.cleaner)();
        if let Some(handle) = self.handle.take() {
            std::mem::drop(&self.queue);
            handle.join().expect("TODO: panic message");
        }
    }
}

impl <T> Looper<T>
    where T: Display + Default + Send + Copy + 'static
{
    fn new<P,C>(processor: P, cleaner: C) -> Self
        where P: Fn(T) -> () + Send + 'static, C: Fn() -> () + Send + 'static,
    {
        // creo il canale
        let (tx, rx) = mpsc::channel();

        // deve lanciare un thread...
        let t1 = thread::spawn(move||{
            loop {
                match rx.recv() {
                    Ok(message) => { processor(message) },
                    Err(_) => {
                        println!("in errore");
                        break;
                    }
                }
            }
        });
        Looper {
            queue: Mutex::new(tx),
            cleaner: Mutex::new(Box::new(cleaner)),
            handle: Some(t1),
        }
    }

}

fn main() {

    let messagges = vec!["uno","due","tre","quattro","cinque"];
    let looper = Arc::new(Looper::new(|message: &str|{println!("Messaggio ricevuto: {}", message)}, ||{println!("Chiusura Looper")}));



    let looper2 = looper.clone();
    let res = std::thread::spawn(move || {
        thread::sleep(Duration::from_secs(2));
        std::mem::drop( looper2);
    });
    
    let looper1 = looper.clone();
    for message in messagges.clone() {
        let state = looper1.queue.lock().unwrap();
        state.send(message).unwrap();
        drop(state);
        println!("Messaggio spedito: {}", message);
        thread::sleep(Duration::from_secs(1));
    }

    res.join().unwrap();

    println!("FINE PROGRAMMA");
}