Skip to main content

kernel_api/syscall/
handle.rs

1use 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}