kernel/object/
mod.rs

1//! Kernel object management system
2//!
3//! This module provides a unified abstraction for all kernel-managed resources
4//! including files, pipes, devices, and other IPC mechanisms.
5
6pub mod capability;
7pub mod handle;
8pub mod introspection;
9
10use crate::fs::FileObject;
11use crate::ipc::StreamIpcOps;
12use crate::ipc::counter::{Counter, CounterObject};
13use crate::ipc::event::{EventChannelObject, EventSubscriptionObject};
14use crate::ipc::pipe::PipeObject;
15use crate::ipc::shared_memory::SharedMemoryObject;
16use alloc::sync::Arc;
17use capability::{CloneOps, ControlOps, MemoryMappingOps, Selectable, StreamOps};
18
19#[cfg(feature = "network")]
20use crate::network::SocketObject;
21
22/// Unified representation of all kernel-managed resources
23///
24/// Note: Debug is not implemented for KernelObject because it contains
25/// trait objects that may not implement Debug. Use introspection methods instead.
26pub enum KernelObject {
27    File(Arc<dyn FileObject>),
28    Pipe(Arc<dyn PipeObject>),
29    Counter(Arc<dyn CounterObject>),
30    EventChannel(Arc<EventChannelObject>),
31    EventSubscription(Arc<EventSubscriptionObject>),
32    #[cfg(feature = "network")]
33    Socket(Arc<dyn SocketObject>),
34    SharedMemory(Arc<dyn SharedMemoryObject>),
35    // Future variants will be added here:
36    // MessageQueue(Arc<dyn MessageQueueObject>),
37    // CharDevice(Arc<dyn CharDevice>),
38}
39
40impl KernelObject {
41    /// Create a KernelObject from a FileObject
42    pub fn from_file_object(file_object: Arc<dyn FileObject>) -> Self {
43        KernelObject::File(file_object)
44    }
45
46    /// Create a KernelObject from a PipeObject
47    pub fn from_pipe_object(pipe_object: Arc<dyn PipeObject>) -> Self {
48        KernelObject::Pipe(pipe_object)
49    }
50
51    /// Create a KernelObject from an EventChannelObject
52    pub fn from_event_channel_object(event_channel: Arc<EventChannelObject>) -> Self {
53        KernelObject::EventChannel(event_channel)
54    }
55
56    /// Create a KernelObject from an EventSubscriptionObject
57    pub fn from_event_subscription(event_subscription: Arc<EventSubscriptionObject>) -> Self {
58        KernelObject::EventSubscription(event_subscription)
59    }
60
61    /// Create a KernelObject from a SocketObject
62    #[cfg(feature = "network")]
63    pub fn from_socket_object(socket: Arc<dyn SocketObject>) -> Self {
64        KernelObject::Socket(socket)
65    }
66
67    /// Create a KernelObject from a SharedMemoryObject
68    pub fn from_shared_memory_object(shared_memory: Arc<dyn SharedMemoryObject>) -> Self {
69        KernelObject::SharedMemory(shared_memory)
70    }
71
72    /// Create a KernelObject from a Counter
73    pub fn from_counter(counter: Arc<Counter>) -> Self {
74        KernelObject::Counter(counter as Arc<dyn CounterObject>)
75    }
76
77    /// Try to get StreamOps capability
78    pub fn as_stream(&self) -> Option<&dyn StreamOps> {
79        match self {
80            KernelObject::File(file_object) => {
81                // FileObject automatically implements StreamOps
82                let stream_ops: &dyn StreamOps = file_object.as_ref();
83                Some(stream_ops)
84            }
85            KernelObject::Pipe(pipe_object) => {
86                // PipeObject automatically implements StreamOps
87                let stream_ops: &dyn StreamOps = pipe_object.as_ref();
88                Some(stream_ops)
89            }
90            KernelObject::Counter(counter) => {
91                // CounterObject implements StreamOps
92                let stream_ops: &dyn StreamOps = counter.as_ref();
93                Some(stream_ops)
94            }
95            #[cfg(feature = "network")]
96            KernelObject::Socket(socket) => {
97                // SocketObject implements StreamOps
98                let stream_ops: &dyn StreamOps = socket.as_ref();
99                Some(stream_ops)
100            }
101            KernelObject::EventChannel(_) => {
102                // Event channels don't provide stream operations
103                None
104            }
105            KernelObject::EventSubscription(_) => {
106                // Event subscriptions don't provide stream operations
107                None
108            }
109            KernelObject::SharedMemory(_) => {
110                // Shared memory doesn't provide stream operations
111                None
112            }
113        }
114    }
115
116    /// Try to get StreamIpcOps capability for IPC stream operations
117    pub fn as_stream_ipc(&self) -> Option<&dyn StreamIpcOps> {
118        match self {
119            KernelObject::File(_) => {
120                // Files don't provide IPC stream operations
121                None
122            }
123            KernelObject::Pipe(pipe_object) => {
124                // PipeObject implements StreamIpcOps
125                let stream_ipc_ops: &dyn StreamIpcOps = pipe_object.as_ref();
126                Some(stream_ipc_ops)
127            }
128            KernelObject::Counter(_) => {
129                // Counter doesn't provide IPC stream operations
130                None
131            }
132            #[cfg(feature = "network")]
133            KernelObject::Socket(socket) => {
134                // SocketObject implements StreamIpcOps
135                let stream_ipc_ops: &dyn StreamIpcOps = socket.as_ref();
136                Some(stream_ipc_ops)
137            }
138            KernelObject::EventChannel(_) => {
139                // Event channels don't provide stream IPC operations
140                None
141            }
142            KernelObject::EventSubscription(_) => {
143                // Event subscriptions don't provide stream IPC operations
144                None
145            }
146            KernelObject::SharedMemory(_) => {
147                // Shared memory doesn't provide stream IPC operations
148                None
149            }
150        }
151    }
152
153    /// Try to get FileObject that provides file-like operations and stream capabilities
154    pub fn as_file(&self) -> Option<&dyn FileObject> {
155        match self {
156            KernelObject::File(file_object) => {
157                // FileObject automatically implements StreamOps
158                let file_ops: &dyn FileObject = file_object.as_ref();
159                Some(file_ops)
160            }
161            KernelObject::Pipe(_) => {
162                // Pipes don't provide file operations
163                None
164            }
165            KernelObject::Counter(_) => {
166                // Counter doesn't provide file operations
167                None
168            }
169            #[cfg(feature = "network")]
170            KernelObject::Socket(_) => {
171                // Sockets don't provide file operations
172                None
173            }
174            KernelObject::EventChannel(_) => {
175                // Event channels don't provide file operations
176                None
177            }
178            KernelObject::EventSubscription(_) => {
179                // Event subscriptions don't provide file operations
180                None
181            }
182            KernelObject::SharedMemory(_) => {
183                // Shared memory doesn't provide file operations
184                None
185            }
186        }
187    }
188
189    /// Try to get PipeObject that provides pipe-specific operations
190    pub fn as_pipe(&self) -> Option<&dyn PipeObject> {
191        match self {
192            KernelObject::File(_) => {
193                // Files don't provide pipe operations
194                None
195            }
196            KernelObject::Pipe(pipe_object) => {
197                let pipe_ops: &dyn PipeObject = pipe_object.as_ref();
198                Some(pipe_ops)
199            }
200            KernelObject::Counter(_) => {
201                // Counter doesn't provide pipe operations
202                None
203            }
204            #[cfg(feature = "network")]
205            KernelObject::Socket(_) => {
206                // Sockets don't provide pipe operations
207                None
208            }
209            KernelObject::EventChannel(_) => {
210                // Event channels don't provide pipe operations
211                None
212            }
213            KernelObject::EventSubscription(_) => {
214                // Event subscriptions don't provide pipe operations
215                None
216            }
217            KernelObject::SharedMemory(_) => {
218                // Shared memory doesn't provide pipe operations
219                None
220            }
221        }
222    }
223
224    /// Try to get SocketObject that provides socket-specific operations
225    #[cfg(feature = "network")]
226    pub fn as_socket(&self) -> Option<&dyn SocketObject> {
227        match self {
228            KernelObject::Socket(socket) => {
229                let socket_ops: &dyn SocketObject = socket.as_ref();
230                Some(socket_ops)
231            }
232            _ => None,
233        }
234    }
235
236    /// Try to get SharedMemoryObject that provides shared memory operations
237    pub fn as_shared_memory(&self) -> Option<&dyn SharedMemoryObject> {
238        match self {
239            KernelObject::SharedMemory(shared_memory) => {
240                let shmem_ops: &dyn SharedMemoryObject = shared_memory.as_ref();
241                Some(shmem_ops)
242            }
243            _ => None,
244        }
245    }
246
247    /// Try to get CloneOps capability
248    pub fn as_cloneable(&self) -> Option<&dyn CloneOps> {
249        match self {
250            KernelObject::File(_) => {
251                None // Files do not implement CloneOps, use Arc::clone directly
252            }
253            KernelObject::Pipe(pipe_object) => {
254                // Check if PipeObject implements CloneOps
255                let cloneable: &dyn CloneOps = pipe_object.as_ref();
256                Some(cloneable)
257            }
258            KernelObject::Counter(counter) => {
259                // CounterObject implements CloneOps
260                let cloneable: &dyn CloneOps = counter.as_ref();
261                Some(cloneable)
262            }
263            #[cfg(feature = "network")]
264            KernelObject::Socket(_) => {
265                // Sockets don't implement CloneOps, use Arc::clone directly
266                None
267            }
268            KernelObject::EventChannel(event_channel) => {
269                // EventChannel implements CloneOps
270                let cloneable: &dyn CloneOps = event_channel.as_ref();
271                Some(cloneable)
272            }
273            KernelObject::EventSubscription(event_subscription) => {
274                // EventSubscription implements CloneOps
275                let cloneable: &dyn CloneOps = event_subscription.as_ref();
276                Some(cloneable)
277            }
278            KernelObject::SharedMemory(_) => {
279                // Shared memory doesn't implement CloneOps, use Arc::clone directly
280                None
281            }
282        }
283    }
284
285    /// Try to get ControlOps capability
286    pub fn as_control(&self) -> Option<&dyn ControlOps> {
287        match self {
288            KernelObject::File(file_object) => {
289                // FileObject automatically implements ControlOps
290                let control_ops: &dyn ControlOps = file_object.as_ref();
291                Some(control_ops)
292            }
293            KernelObject::Pipe(_) => {
294                // Pipes don't provide control operations
295                None
296            }
297            KernelObject::Counter(_) => {
298                // Counter doesn't provide control operations
299                None
300            }
301            #[cfg(feature = "network")]
302            KernelObject::Socket(socket) => {
303                // Try to get control operations through SocketObject trait
304                socket.as_control_ops()
305            }
306            KernelObject::EventChannel(_) => {
307                // Event channels don't provide control operations
308                None
309            }
310            KernelObject::EventSubscription(_) => {
311                // Event subscriptions don't provide control operations
312                None
313            }
314            KernelObject::SharedMemory(_) => {
315                // Shared memory doesn't provide control operations
316                None
317            }
318        }
319    }
320
321    /// Try to get MemoryMappingOps capability
322    pub fn as_memory_mappable(&self) -> Option<&dyn MemoryMappingOps> {
323        match self {
324            KernelObject::File(file_object) => {
325                // FileObject automatically implements MemoryMappingOps
326                let memory_mapping_ops: &dyn MemoryMappingOps = file_object.as_ref();
327                Some(memory_mapping_ops)
328            }
329            KernelObject::Pipe(_) => {
330                // Pipes don't provide memory mapping operations
331                None
332            }
333            KernelObject::Counter(_) => {
334                // Counter doesn't provide memory mapping operations
335                None
336            }
337            #[cfg(feature = "network")]
338            KernelObject::Socket(_) => {
339                // Sockets don't provide memory mapping operations
340                None
341            }
342            KernelObject::EventChannel(_) => {
343                // Event channels don't provide memory mapping operations
344                None
345            }
346            KernelObject::EventSubscription(_) => {
347                // Event subscriptions don't provide memory mapping operations
348                None
349            }
350            KernelObject::SharedMemory(shared_memory) => {
351                // SharedMemory implements MemoryMappingOps
352                let memory_mapping_ops: &dyn MemoryMappingOps = shared_memory.as_ref();
353                Some(memory_mapping_ops)
354            }
355        }
356    }
357
358    /// Try to get weak reference to MemoryMappingOps capability
359    pub fn as_memory_mappable_weak(&self) -> Option<alloc::sync::Weak<dyn MemoryMappingOps>> {
360        match self {
361            KernelObject::File(file_object) => {
362                // Create weak reference from the Arc<dyn FileObject>
363                // FileObject automatically implements MemoryMappingOps
364                let weak_file = Arc::downgrade(file_object);
365                Some(weak_file)
366            }
367            KernelObject::Pipe(_) => {
368                // Pipes don't provide memory mapping operations
369                None
370            }
371            KernelObject::Counter(_) => {
372                // Counter doesn't provide memory mapping operations
373                None
374            }
375            #[cfg(feature = "network")]
376            KernelObject::Socket(_) => {
377                // Sockets don't provide memory mapping operations
378                None
379            }
380            KernelObject::EventChannel(_) => {
381                // Event channels don't provide memory mapping operations
382                None
383            }
384            KernelObject::EventSubscription(_) => {
385                // Event subscriptions don't provide memory mapping operations
386                None
387            }
388            KernelObject::SharedMemory(shared_memory) => {
389                // Create weak reference from the Arc<dyn SharedMemoryObject>
390                // SharedMemoryObject implements MemoryMappingOps
391                let weak_shmem = Arc::downgrade(shared_memory);
392                Some(weak_shmem)
393            }
394        }
395    }
396
397    /// Try to get EventChannelObject
398    pub fn as_event_channel(&self) -> Option<&EventChannelObject> {
399        match self {
400            KernelObject::EventChannel(event_channel) => {
401                let event_channel_obj: &EventChannelObject = event_channel.as_ref();
402                Some(event_channel_obj)
403            }
404            _ => None,
405        }
406    }
407
408    /// Try to get EventSubscriptionObject
409    pub fn as_event_subscription(&self) -> Option<&EventSubscriptionObject> {
410        match self {
411            KernelObject::EventSubscription(event_subscription) => {
412                let event_subscription_obj: &EventSubscriptionObject = event_subscription.as_ref();
413                Some(event_subscription_obj)
414            }
415            _ => None,
416        }
417    }
418
419    /// Try to get CounterObject
420    pub fn as_counter(&self) -> Option<&dyn CounterObject> {
421        match self {
422            KernelObject::Counter(counter) => {
423                let counter_obj: &dyn CounterObject = counter.as_ref();
424                Some(counter_obj)
425            }
426            _ => None,
427        }
428    }
429
430    /// Try to get Selectable capability for pselect/select readiness
431    pub fn as_selectable(&self) -> Option<&dyn Selectable> {
432        match self {
433            KernelObject::File(file_object) => {
434                // FileObject requires Selectable; upcast trait object
435                let sel: &dyn Selectable = file_object.as_ref();
436                Some(sel)
437            }
438            KernelObject::Pipe(pipe_object) => pipe_object.as_selectable(),
439            KernelObject::Counter(counter) => {
440                // CounterObject implements Selectable
441                let sel: &dyn Selectable = counter.as_ref();
442                Some(sel)
443            }
444            #[cfg(feature = "network")]
445            KernelObject::Socket(socket) => socket.as_selectable(),
446            KernelObject::EventChannel(_) => None,
447            KernelObject::EventSubscription(_) => None,
448            KernelObject::SharedMemory(_) => None,
449        }
450    }
451
452    /// Clone the KernelObject at the Arc level only (no state changes).
453    ///
454    /// Unlike the `Clone` trait implementation which may use `custom_clone()` for
455    /// objects like Pipes (incrementing reader/writer counts), this method performs
456    /// a simple `Arc::clone()` that only increments the Arc reference count without
457    /// modifying the underlying object state.
458    ///
459    /// Use this when you need a copy of the KernelObject for temporary access
460    /// without intending to create a new logical file descriptor (dup semantics).
461    pub fn arc_clone(&self) -> Self {
462        match self {
463            KernelObject::File(file_object) => KernelObject::File(Arc::clone(file_object)),
464            KernelObject::Pipe(pipe_object) => KernelObject::Pipe(Arc::clone(pipe_object)),
465            KernelObject::Counter(counter) => KernelObject::Counter(Arc::clone(counter)),
466            #[cfg(feature = "network")]
467            KernelObject::Socket(socket) => KernelObject::Socket(Arc::clone(socket)),
468            KernelObject::EventChannel(event_channel) => {
469                KernelObject::EventChannel(Arc::clone(event_channel))
470            }
471            KernelObject::EventSubscription(event_subscription) => {
472                KernelObject::EventSubscription(Arc::clone(event_subscription))
473            }
474            KernelObject::SharedMemory(shared_memory) => {
475                KernelObject::SharedMemory(Arc::clone(shared_memory))
476            }
477        }
478    }
479}
480
481impl Clone for KernelObject {
482    fn clone(&self) -> Self {
483        // Try to use CloneOps capability first
484        if let Some(cloneable) = self.as_cloneable() {
485            cloneable.custom_clone()
486        } else {
487            // Default: Use Arc::clone for direct cloning
488            match self {
489                KernelObject::File(file_object) => KernelObject::File(Arc::clone(file_object)),
490                KernelObject::Pipe(pipe_object) => KernelObject::Pipe(Arc::clone(pipe_object)),
491                KernelObject::Counter(counter) => KernelObject::Counter(Arc::clone(counter)),
492                #[cfg(feature = "network")]
493                KernelObject::Socket(socket) => KernelObject::Socket(Arc::clone(socket)),
494                KernelObject::EventChannel(event_channel) => {
495                    KernelObject::EventChannel(Arc::clone(event_channel))
496                }
497                KernelObject::EventSubscription(event_subscription) => {
498                    KernelObject::EventSubscription(Arc::clone(event_subscription))
499                }
500                KernelObject::SharedMemory(shared_memory) => {
501                    KernelObject::SharedMemory(Arc::clone(shared_memory))
502                }
503            }
504        }
505    }
506}
507
508#[cfg(test)]
509mod tests;