bpf_api/collections/
queue.rs

1use crate::error::Error;
2use crate::platform::{Map, MapType};
3
4#[derive(Copy, Clone, Default)]
5struct Void {}
6
7/// A queue that exposes an idiomatic Rust interface to an underlying BPF queue.
8pub struct Queue<V: Copy + Default> {
9    map: Map<Void, V>,
10}
11
12impl<V: Copy + Default> Queue<V> {
13    /// Creates a new BPF queue with `entries` elements. A queue works as
14    /// a FIFO container: `push()` inserts an element to the back and `pop()`
15    /// consumes an element from the front.
16    ///
17    /// # Arguments
18    ///
19    /// * `entries` - The maximum number of elements in the queue.
20    ///
21    /// # Example
22    /// ```
23    /// use bpf_api::collections::Queue;
24    ///
25    /// let queue = Queue::<u32>::with_capacity(10).expect("Failed to create queue");
26    /// ```
27    pub fn with_capacity(entries: u32) -> Result<Self, Error> {
28        Ok(Self {
29            map: Map::with_capacity(MapType::Queue, entries)?,
30        })
31    }
32
33    /// Retrieves and removes the next element in the queue, if it exists.
34    ///
35    /// # Example
36    /// ```
37    /// use bpf_api::collections::Queue;
38    ///
39    /// let queue = Queue::<u32>::with_capacity(10).expect("Failed to create queue");
40    /// assert!(matches!(queue.pop(), Err(_)));
41    /// ```
42    pub fn pop(&self) -> Result<V, Error> {
43        self.map.get_and_del(&Void::default())
44    }
45
46    /// Retrieves next element in the queue, if it exists. This does _not_ remove
47    /// the element.
48    ///
49    /// # Example
50    /// ```
51    /// use bpf_api::collections::Queue;
52    ///
53    /// let queue = Queue::<u32>::with_capacity(10).expect("Failed to create queue");
54    /// assert!(matches!(queue.front(), Err(_)));
55    /// ```
56    pub fn front(&self) -> Result<V, Error> {
57        self.map.get(&Void::default())
58    }
59
60    /// Push a new element to the back of the queue.
61    ///
62    /// # Example
63    /// ```
64    /// use bpf_api::collections::Queue;
65    ///
66    /// let queue = Queue::<u32>::with_capacity(10).expect("Failed to create queue");
67    /// assert!(matches!(queue.push(100), Ok(_)));
68    /// assert!(matches!(queue.front(), Ok(100)));
69    /// assert!(matches!(queue.pop(), Ok(100)));
70    /// assert!(matches!(queue.pop(), Err(_)));
71    /// ```
72    pub fn push(&self, val: V) -> Result<(), Error> {
73        self.map.set(&Void::default(), &val)
74    }
75
76    /// Retrieve the BPF identifier for this map. This is the underlying file
77    /// descriptor that's used in eBPF programs.
78    ///
79    /// # Example
80    /// ```
81    /// use bpf_api::collections::Queue;
82    ///
83    /// let queue = Queue::<u32>::with_capacity(10).expect("Failed to create queue");
84    /// queue.get_identifier();
85    /// ```
86    pub fn get_identifier(&self) -> u32 {
87        self.map.get_identifier()
88    }
89}