netmap_rs/
fallback.rs

1//! Fallback implementation for platforms without Netnap support
2
3use std::collections::VecDeque;
4use std::sync::{Arc, Mutex};
5
6use crate::error::Error;
7use crate::frame::Frame;
8
9#[derive(Clone)]
10struct SharedRing {
11    queue: Arc<Mutex<VecDeque<Vec<u8>>>>,
12    max_size: usize,
13}
14
15/// fallback implememntation for a Netmap TX ring
16pub struct FallbackTxRing(SharedRing);
17
18/// fallback implememntation for a Netmap RX ring
19pub struct FallbackRxRing(SharedRing);
20
21impl FallbackTxRing {
22    /// create new fallback TX ring
23    pub fn new(max_size: usize) -> Self {
24        Self(SharedRing {
25            queue: Arc::new(Mutex::new(VecDeque::new())),
26            max_size,
27        })
28    }
29
30    /// send a packet
31    pub fn send(&self, buf: &[u8]) -> Result<(), Error> {
32        let mut queue = self.0.queue.lock().unwrap();
33        if queue.len() >= self.0.max_size {
34            return Err(Error::WouldBlock);
35        }
36        queue.push_back(buf.to_vec());
37        Ok(())
38    }
39}
40
41impl FallbackRxRing {
42    /// create a new fallback RX ring
43    pub fn new(max_size: usize) -> Self {
44        Self(SharedRing {
45            queue: Arc::new(Mutex::new(VecDeque::new())),
46            max_size,
47        })
48    }
49
50    /// recieve a packet
51    pub fn recv(&self) -> Option<Frame<'static>> {
52        let mut queue = self.0.queue.lock().unwrap();
53        queue.pop_front().map(Frame::new_owned)
54    }
55}
56
57/// Creates a connected pair of fallback TX and RX rings.
58pub fn create_fallback_channel(max_size: usize) -> (FallbackTxRing, FallbackRxRing) {
59    let shared_ring = SharedRing {
60        queue: Arc::new(Mutex::new(VecDeque::new())),
61        max_size,
62    };
63    (FallbackTxRing(shared_ring.clone()), FallbackRxRing(shared_ring))
64}