use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use socketcan::{CANFrame, CANSocket};
pub struct CANReader {
can_socket: Arc<Mutex<CANSocket>>,
clients: Arc<Mutex<Vec<mpsc::Sender<CANFrame>>>>,
}
impl CANReader {
pub fn new(socket: CANSocket) -> (CANReader, thread::JoinHandle<()>) {
let reader = CANReader {
can_socket: Arc::new(Mutex::new(socket)),
clients: Arc::new(Mutex::new(Vec::new())),
};
let can_socket = Arc::clone(&reader.can_socket); let clients = Arc::clone(&reader.clients);
let handle = thread::spawn(move || {
loop {
let frame = can_socket.lock().unwrap().read_frame().unwrap();
let mut dropped_clients = Vec::new();
for (i, client) in clients.lock().unwrap().iter().enumerate() {
client.send(frame.clone()).unwrap_or_else(|_| {
dropped_clients.push(i);
});
}
for i in dropped_clients {
clients.lock().unwrap().remove(i);
}
}
});
(reader, handle)
}
pub fn add_client(&self, channel: mpsc::Sender<CANFrame>) {
&self.clients.lock().unwrap().push(channel);
}
pub fn get_socket(&self) -> Arc<Mutex<CANSocket>> {
Arc::clone(&self.can_socket)
}
}