Skip to main content

ruvix_types/
handle.rs

1//! Generic handle type for kernel objects.
2//!
3//! All kernel objects are accessed through handles which contain a unique
4//! identifier and generation counter for use-after-free detection.
5
6/// A generic handle to a kernel object.
7///
8/// Handles are unforgeable kernel-managed tokens that identify resources.
9/// The generation counter prevents use-after-free attacks when handles
10/// are recycled after object destruction.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12#[repr(C)]
13pub struct Handle {
14    /// Unique identifier within the object pool.
15    pub id: u32,
16    /// Generation counter for stale handle detection.
17    /// Incremented each time the slot is reused.
18    pub generation: u32,
19}
20
21impl Handle {
22    /// Creates a new handle with the given id and generation.
23    #[inline]
24    #[must_use]
25    pub const fn new(id: u32, generation: u32) -> Self {
26        Self { id, generation }
27    }
28
29    /// Creates a null handle (invalid).
30    #[inline]
31    #[must_use]
32    pub const fn null() -> Self {
33        Self {
34            id: u32::MAX,
35            generation: 0,
36        }
37    }
38
39    /// Checks if this handle is null (invalid).
40    #[inline]
41    #[must_use]
42    pub const fn is_null(&self) -> bool {
43        self.id == u32::MAX
44    }
45
46    /// Returns the raw 64-bit representation of this handle.
47    #[inline]
48    #[must_use]
49    pub const fn to_raw(&self) -> u64 {
50        ((self.generation as u64) << 32) | (self.id as u64)
51    }
52
53    /// Creates a handle from a raw 64-bit representation.
54    #[inline]
55    #[must_use]
56    pub const fn from_raw(raw: u64) -> Self {
57        Self {
58            id: raw as u32,
59            generation: (raw >> 32) as u32,
60        }
61    }
62}
63
64impl Default for Handle {
65    fn default() -> Self {
66        Self::null()
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn test_handle_new() {
76        let h = Handle::new(42, 7);
77        assert_eq!(h.id, 42);
78        assert_eq!(h.generation, 7);
79    }
80
81    #[test]
82    fn test_handle_null() {
83        let h = Handle::null();
84        assert!(h.is_null());
85    }
86
87    #[test]
88    fn test_handle_roundtrip() {
89        let h = Handle::new(12345, 67890);
90        let raw = h.to_raw();
91        let h2 = Handle::from_raw(raw);
92        assert_eq!(h, h2);
93    }
94}