pub struct HandleTable {
inner: Arc<RwLock<HandleTableInner>>,
}Expand description
Handle table for managing kernel objects with support for sharing between tasks.
This structure uses interior mutability via Arc<RwLock<...>> to enable
sharing between parent and child tasks when using CLONE_FILES flag.
The Clone implementation creates a shallow copy (Arc clone) that shares
the same underlying data. Use deep_clone() for an independent copy.
Fields§
§inner: Arc<RwLock<HandleTableInner>>Implementations§
Source§impl HandleTable
impl HandleTable
Sourcepub const MAX_HANDLES: usize = 1_024usize
pub const MAX_HANDLES: usize = 1_024usize
Maximum number of handles per table (POSIX standard limit for fd)
Sourcepub fn deep_clone(&self) -> Self
pub fn deep_clone(&self) -> Self
Create a deep clone of this handle table (independent copy).
This method creates a completely independent copy of the handle table, including all handles and metadata. Use this when you need separate handle tables for parent and child tasks (non-CLONE_FILES behavior).
Sourcepub fn insert(&self, obj: KernelObject) -> Result<Handle, &'static str>
pub fn insert(&self, obj: KernelObject) -> Result<Handle, &'static str>
O(1) allocation with automatic metadata inference
Sourcepub fn insert_with_metadata(
&self,
obj: KernelObject,
metadata: HandleMetadata,
) -> Result<Handle, &'static str>
pub fn insert_with_metadata( &self, obj: KernelObject, metadata: HandleMetadata, ) -> Result<Handle, &'static str>
O(1) allocation with explicit metadata
Sourcefn infer_metadata_from_object(object: &KernelObject) -> HandleMetadata
fn infer_metadata_from_object(object: &KernelObject) -> HandleMetadata
Infer metadata from KernelObject type and usage context
This function provides reasonable defaults for handle roles based on the KernelObject type. Applications can override this by using insert_with_metadata() to specify exact roles.
Sourcepub fn with_object<F, R>(&self, handle: Handle, f: F) -> Option<R>where
F: FnOnce(&KernelObject) -> R,
pub fn with_object<F, R>(&self, handle: Handle, f: F) -> Option<R>where
F: FnOnce(&KernelObject) -> R,
O(1) access - executes a closure with a reference to the KernelObject
Since the internal data is protected by RwLock, we cannot return a direct reference. Instead, use this method to access the object within a closure.
Sourcepub fn get(&self, handle: Handle) -> Option<KernelObject>
pub fn get(&self, handle: Handle) -> Option<KernelObject>
O(1) access - returns an Arc-level clone of the KernelObject if it exists
This method returns an Arc-level clone of the KernelObject. Unlike the Clone trait which may have side effects (e.g., incrementing Pipe reader/writer counts), this performs a simple Arc reference count increment without modifying object state.
For cases where you need dup() semantics (creating a new logical file descriptor
with proper reference counting), use clone_for_dup() instead.
Sourcepub fn clone_for_dup(&self, handle: Handle) -> Option<KernelObject>
pub fn clone_for_dup(&self, handle: Handle) -> Option<KernelObject>
O(1) access - returns a full clone with dup() semantics
This method uses the KernelObject’s Clone trait which may invoke custom_clone() for objects like Pipes. This is appropriate when duplicating a file descriptor (dup/dup2 syscalls) where the new descriptor should be tracked separately.
Sourcepub fn remove(&self, handle: Handle) -> Option<KernelObject>
pub fn remove(&self, handle: Handle) -> Option<KernelObject>
O(1) removal
Sourcepub fn update_metadata(
&self,
handle: Handle,
new_metadata: HandleMetadata,
) -> Result<(), &'static str>
pub fn update_metadata( &self, handle: Handle, new_metadata: HandleMetadata, ) -> Result<(), &'static str>
Update metadata for an existing handle
Sourcepub fn open_count(&self) -> usize
pub fn open_count(&self) -> usize
Get the number of open handles
Sourcepub fn active_handles(&self) -> Vec<Handle>
pub fn active_handles(&self) -> Vec<Handle>
Get all active handles
Sourcepub fn is_sole_owner(&self) -> bool
pub fn is_sole_owner(&self) -> bool
Check if this is the sole owner of the underlying handle table.
Returns true if no other HandleTable shares the same inner data
(i.e., the Arc strong reference count is 1).
This is used to decide whether close_all should run during task exit:
when the handle table is shared via CLONE_FILES (threads), only the
last task holding the table should close all handles.
Sourcepub fn is_valid_handle(&self, handle: Handle) -> bool
pub fn is_valid_handle(&self, handle: Handle) -> bool
Check if a handle is valid
Sourcepub fn get_metadata(&self, handle: Handle) -> Option<HandleMetadata>
pub fn get_metadata(&self, handle: Handle) -> Option<HandleMetadata>
Get metadata for a handle - returns a clone since we can’t return a reference
Sourcepub fn with_metadata<F, R>(&self, handle: Handle, f: F) -> Option<R>where
F: FnOnce(&HandleMetadata) -> R,
pub fn with_metadata<F, R>(&self, handle: Handle, f: F) -> Option<R>where
F: FnOnce(&HandleMetadata) -> R,
Execute a closure with access to metadata
Sourcepub fn for_each_with_metadata<F>(&self, f: F)
pub fn for_each_with_metadata<F>(&self, f: F)
Iterate over handles with their objects and metadata, executing a closure for each
Sourcepub fn get_object_info(&self, handle: Handle) -> Option<KernelObjectInfo>
pub fn get_object_info(&self, handle: Handle) -> Option<KernelObjectInfo>
Get detailed information about a KernelObject for user space introspection
Trait Implementations§
Source§impl Clone for HandleTable
Handle metadata for managing special semantics and ABI conversion
impl Clone for HandleTable
Handle metadata for managing special semantics and ABI conversion
This metadata describes HOW a handle is being used, not WHAT the underlying KernelObject is. This enables proper ABI conversion, security policies, and resource management.
§Examples of Role-based Usage
// Same file object used in different roles
let config_file = file_obj.clone();
let log_file = file_obj.clone();
// Handle for reading configuration
let config_handle = task.handle_table.insert_with_metadata(
KernelObject::File(config_file),
HandleMetadata {
handle_type: HandleType::ConfigFile,
access_mode: AccessMode::ReadOnly,
special_semantics: Some(SpecialSemantics::CloseOnExec),
}
)?;
// Handle for writing logs
let log_handle = task.handle_table.insert_with_metadata(
KernelObject::File(log_file),
HandleMetadata {
handle_type: HandleType::LogOutput,
access_mode: AccessMode::WriteOnly,
special_semantics: Some(SpecialSemantics::Append),
}
)?;Clone implementation creates a shallow copy (Arc clone).
This means the cloned HandleTable shares the same underlying data.
Use deep_clone() to create an independent copy.
Auto Trait Implementations§
impl Freeze for HandleTable
impl !RefUnwindSafe for HandleTable
impl Send for HandleTable
impl Sync for HandleTable
impl Unpin for HandleTable
impl !UnwindSafe for HandleTable
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)