use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use crate::error::Error;
use crate::frame::Frame;
#[derive(Clone)]
struct SharedRing {
queue: Arc<Mutex<VecDeque<Vec<u8>>>>,
max_size: usize,
}
pub struct FallbackTxRing(SharedRing);
pub struct FallbackRxRing(SharedRing);
impl FallbackTxRing {
pub fn new(max_size: usize) -> Self {
Self(SharedRing {
queue: Arc::new(Mutex::new(VecDeque::new())),
max_size,
})
}
pub fn send(&self, buf: &[u8]) -> Result<(), Error> {
let mut queue = self.0.queue.lock().unwrap();
if queue.len() >= self.0.max_size {
return Err(Error::WouldBlock);
}
queue.push_back(buf.to_vec());
Ok(())
}
}
impl FallbackRxRing {
pub fn new(max_size: usize) -> Self {
Self(SharedRing {
queue: Arc::new(Mutex::new(VecDeque::new())),
max_size,
})
}
pub fn recv(&self) -> Option<Frame<'static>> {
let mut queue = self.0.queue.lock().unwrap();
queue.pop_front().map(Frame::new_owned)
}
}
pub fn create_fallback_channel(max_size: usize) -> (FallbackTxRing, FallbackRxRing) {
let shared_ring = SharedRing {
queue: Arc::new(Mutex::new(VecDeque::new())),
max_size,
};
(FallbackTxRing(shared_ring.clone()), FallbackRxRing(shared_ring))
}