kernel_api/syscall/
handle.rs1use alloc::borrow::Cow;
2use alloc::sync::Arc;
3use core::mem::ManuallyDrop;
4use core::sync::atomic::{AtomicPtr, AtomicU32, Ordering};
5use hashbrown::HashMap;
6use log::debug;
7use crate::sync::{RwSpinlock, Spinlock};
8use crate::syscall;
9use crate::syscall::Error;
10use crate::syscall::server::ServerId;
11
12#[derive(Debug)]
13pub struct HandleMap(AtomicPtr<HandleMapInner>);
14
15impl Clone for HandleMap {
16 fn clone(&self) -> Self {
17 let ptr = self.0.load(Ordering::SeqCst).cast_const();
18 unsafe { Arc::increment_strong_count(ptr) };
19 Self(AtomicPtr::new(ptr.cast_mut()))
20 }
21}
22
23#[derive(Debug)]
24pub struct HandleMapInner {
25 map: Spinlock<HashMap<u32, Arc<Handle>>>,
26 next_fd: AtomicU32,
27}
28
29impl HandleMap {
30 fn deref(&self) -> &HandleMapInner {
31 let ptr = self.0.load(Ordering::SeqCst).cast_const();
32 unsafe { &*ptr }
33 }
34
35 pub fn new() -> Self {
36 let this = HandleMapInner {
37 map: Spinlock::new(HashMap::new()),
38 next_fd: AtomicU32::new(4),
39 };
40 let arc = Arc::new(this);
41 Self(AtomicPtr::new(Arc::into_raw(arc).cast_mut()))
42 }
43
44 pub fn push(&self, handle: Arc<Handle>) -> syscall::Result<u32> {
45 let this = self.deref();
46 loop {
47 if this.next_fd.load(Ordering::Relaxed) == u32::MAX { return Err(Error::Overflow); }
48 let fd = this.next_fd.fetch_add(1, Ordering::Relaxed);
49
50 match this.map.lock().try_insert(fd, handle.clone()) {
51 Ok(_) => break Ok(fd),
52 Err(_) => continue,
53 }
54 }
55 }
56
57 pub fn openat(&self, fd: u32, handle: Arc<Handle>) -> Result<u32, Error> {
58 let this = self.deref();
59 match this.map.lock().try_insert(fd, handle) {
60 Ok(_) => Ok(fd),
61 Err(_) => Err(Error::NameInUse),
62 }
63 }
64
65 pub fn get(&self, val: u32) -> Result<Arc<Handle>, Error> {
66 let this = self.deref();
67 this.map.lock().get(&val).cloned().ok_or(Error::InvalidHandle)
68 }
69
70 pub fn pop(&self, val: u32) -> Result<Arc<Handle>, Error> {
71 let this = self.deref();
72 this.map.lock().remove(&val).ok_or(Error::InvalidHandle)
73 }
74
75 pub unsafe fn swap(&self, other: HandleMap, ordering: Ordering) -> HandleMap {
76 let other = ManuallyDrop::new(other);
77 let other = other.0.load(ordering);
78 let old = self.0.swap(other, ordering);
79 HandleMap(AtomicPtr::new(old))
80 }
81}
82
83#[derive(Debug)]
84pub struct Handle {
85 #[doc(hidden)]
86 pub __protocols: RwSpinlock<ManuallyDrop<HashMap<u128, (ServerId, isize)>>>,
87 endpoint: Arc<str>,
88}
89
90impl Handle {
91 pub fn new(server_id: ServerId, internal_id: isize, protocols: &[u128], endpoint: impl Into<Arc<str>>) -> Arc<Handle> {
92 Arc::new(Handle {
93 __protocols: RwSpinlock::new(ManuallyDrop::new(
94 HashMap::from_iter(protocols.iter().copied().zip(core::iter::repeat((server_id, internal_id))))
95 )),
96 endpoint: endpoint.into(),
97 })
98 }
99
100 pub fn id(&self, protocol: u128) -> Result<(ServerId, isize), Error> {
101 self.__protocols.read().get(&protocol).copied().ok_or(Error::UnsupportedProtocol)
102 }
103
104 pub fn has_protocols(&self, protocols: &[u128]) -> bool {
105 debug!("check handle {self:#x?} for protocols {protocols:#x?}");
106 protocols.iter().all(|uid| self.__protocols.read().contains_key(uid))
107 }
108
109 pub fn merge(&self, other: &Self) -> Result<(), Error> {
110 let mut guard = self.__protocols.write();
111 if guard.keys().any(|uid| other.__protocols.read().contains_key(uid)) {
112 debug!("overlap of protocol");
113 return Err(Error::ProtocolOverlap);
114 }
115 guard.extend(other.__protocols.read().iter());
116 Ok(())
117 }
118
119 pub fn endpoint(&self) -> &Arc<str> {
120 &self.endpoint
121 }
122}
123
124impl Drop for Handle {
125 fn drop(&mut self) {
126 crate::bridge::handle::drop(self);
127 }
128}