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}