HandleTable

Struct HandleTable 

Source
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

Source

pub const MAX_HANDLES: usize = 1_024usize

Maximum number of handles per table (POSIX standard limit for fd)

Source

pub fn new() -> Self

Create a new empty handle table.

Source

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).

Source

pub fn insert(&self, obj: KernelObject) -> Result<Handle, &'static str>

O(1) allocation with automatic metadata inference

Source

pub fn insert_with_metadata( &self, obj: KernelObject, metadata: HandleMetadata, ) -> Result<Handle, &'static str>

O(1) allocation with explicit metadata

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn remove(&self, handle: Handle) -> Option<KernelObject>

O(1) removal

Source

pub fn update_metadata( &self, handle: Handle, new_metadata: HandleMetadata, ) -> Result<(), &'static str>

Update metadata for an existing handle

Source

pub fn open_count(&self) -> usize

Get the number of open handles

Source

pub fn active_handles(&self) -> Vec<Handle>

Get all active handles

Source

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.

Source

pub fn close_all(&self)

Close all handles (for process termination)

Source

pub fn is_valid_handle(&self, handle: Handle) -> bool

Check if a handle is valid

Source

pub fn get_metadata(&self, handle: Handle) -> Option<HandleMetadata>

Get metadata for a handle - returns a clone since we can’t return a reference

Source

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

Source

pub fn for_each_with_metadata<F>(&self, f: F)
where F: FnMut(Handle, &KernelObject, &HandleMetadata),

Iterate over handles with their objects and metadata, executing a closure for each

Source

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

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.

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for HandleTable

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

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 T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.