You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.1 KiB

use super::*;
use crate::error::*;
use crate::object::*;
use alloc::collections::BTreeMap;
use alloc::sync::Arc;
use spin::Mutex;
// ANCHOR: process
/// 进程对象
pub struct Process {
base: KObjectBase,
inner: Mutex<ProcessInner>,
}
impl_kobject!(Process);
struct ProcessInner {
handles: BTreeMap<HandleValue, Handle>,
}
pub type HandleValue = u32;
impl Process {
/// 创建一个新的进程对象
pub fn new() -> Arc<Self> {
Arc::new(Process {
base: KObjectBase::default(),
inner: Mutex::new(ProcessInner {
handles: BTreeMap::default(),
}),
})
}
// ANCHOR_END: process
// ANCHOR: add_remove_handle
/// 添加一个新的对象句柄
pub fn add_handle(&self, handle: Handle) -> HandleValue {
let mut inner = self.inner.lock();
let value = (0 as HandleValue..)
.find(|idx| !inner.handles.contains_key(idx))
.unwrap();
inner.handles.insert(value, handle);
value
}
/// 删除一个对象句柄
pub fn remove_handle(&self, handle_value: HandleValue) {
self.inner.lock().handles.remove(&handle_value);
}
// ANCHOR_END: add_remove_handle
// ANCHOR: get_object_with_rights
/// 根据句柄值查找内核对象,并检查权限
pub fn get_object_with_rights<T: KernelObject>(
&self,
handle_value: HandleValue,
desired_rights: Rights,
) -> ZxResult<Arc<T>> {
let handle = self
.inner
.lock()
.handles
.get(&handle_value)
.ok_or(ZxError::BAD_HANDLE)?
.clone();
// check type before rights
let object = handle
.object
.downcast_arc::<T>()
.map_err(|_| ZxError::WRONG_TYPE)?;
if !handle.rights.contains(desired_rights) {
return Err(ZxError::ACCESS_DENIED);
}
Ok(object)
}
// ANCHOR_END: get_object_with_rights
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::format;
#[test]
fn new_proc() {
let proc = Process::new();
assert_eq!(proc.type_name(), "Process");
assert_eq!(proc.name(), "");
proc.set_name("proc1");
assert_eq!(proc.name(), "proc1");
assert_eq!(
format!("{:?}", proc),
format!("Process({}, \"proc1\")", proc.id())
);
let obj: Arc<dyn KernelObject> = proc;
assert_eq!(obj.type_name(), "Process");
assert_eq!(obj.name(), "proc1");
obj.set_name("proc2");
assert_eq!(obj.name(), "proc2");
assert_eq!(
format!("{:?}", obj),
format!("Process({}, \"proc2\")", obj.id())
);
}
fn proc_handle() {
let proc = Process::new();
let handle = Handle::new(proc.clone(), Rights::DEFAULT_PROCESS);
let handle_value = proc.add_handle(handle);
let object1: Arc<Process> = proc
.get_object_with_rights(handle_value, Rights::DEFAULT_PROCESS)
.expect("failed to get object");
assert!(Arc::ptr_eq(&object1, &proc));
proc.remove_handle(handle_value);
}
}