twizzler/object/
mutable.rs

1use std::{marker::PhantomData, ptr::addr_of, sync::atomic::AtomicU64};
2
3use twizzler_abi::{
4    object::{ObjID, MAX_SIZE},
5    syscall::{sys_map_ctrl, MapControlCmd, SyncFlags, SyncInfo},
6};
7use twizzler_rt_abi::{
8    error::TwzError,
9    object::{MapFlags, ObjectHandle},
10};
11
12use super::{Object, RawObject, TypedObject};
13use crate::{
14    marker::BaseType,
15    ptr::{Ref, RefMut},
16};
17
18pub struct MutObject<Base> {
19    handle: ObjectHandle,
20    _pd: PhantomData<*mut Base>,
21}
22
23unsafe impl<Base> Sync for MutObject<Base> {}
24unsafe impl<Base> Send for MutObject<Base> {}
25
26impl<B> Clone for MutObject<B> {
27    fn clone(&self) -> Self {
28        Self {
29            handle: self.handle.clone(),
30            _pd: PhantomData,
31        }
32    }
33}
34
35impl<Base> MutObject<Base> {
36    pub unsafe fn from_handle_unchecked(handle: ObjectHandle) -> Self {
37        Self {
38            handle,
39            _pd: PhantomData,
40        }
41    }
42
43    pub fn from_handle(handle: ObjectHandle) -> Result<Self, TwzError> {
44        // TODO: check base fingerprint
45        unsafe { Ok(Self::from_handle_unchecked(handle)) }
46    }
47
48    pub fn into_handle(self) -> ObjectHandle {
49        self.handle
50    }
51
52    pub unsafe fn cast<U>(self) -> MutObject<U> {
53        MutObject {
54            handle: self.handle,
55            _pd: PhantomData,
56        }
57    }
58
59    pub fn map(id: ObjID, flags: MapFlags) -> Result<Self, TwzError> {
60        // TODO: check base fingerprint
61        let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
62        tracing::debug!("map: {} {:?} => {:?}", id, flags, handle.start());
63        Self::from_handle(handle)
64    }
65
66    pub unsafe fn map_unchecked(id: ObjID, flags: MapFlags) -> Result<Self, TwzError> {
67        let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
68        unsafe { Ok(Self::from_handle_unchecked(handle)) }
69    }
70
71    pub fn id(&self) -> ObjID {
72        self.handle.id()
73    }
74
75    pub fn update(&mut self) -> crate::Result<()> {
76        sys_map_ctrl(self.handle.start(), MAX_SIZE, MapControlCmd::Update, 0)
77    }
78
79    pub fn base_mut(&mut self) -> RefMut<'_, Base> {
80        unsafe { RefMut::from_raw_parts(self.base_mut_ptr(), &self.handle) }
81    }
82
83    pub fn sync(&mut self) -> Result<(), TwzError> {
84        let flags = self.handle.map_flags();
85        tracing::trace!("sync on {:?} with flags {:?}", self.id(), flags);
86        if flags.contains(MapFlags::PERSIST) {
87            let release = AtomicU64::new(0);
88            let release_ptr = addr_of!(release);
89            let sync_info = SyncInfo {
90                release: release_ptr,
91                release_compare: 0,
92                release_set: 1,
93                durable: core::ptr::null(),
94                flags: SyncFlags::DURABLE | SyncFlags::ASYNC_DURABLE,
95            };
96            let sync_info_ptr = addr_of!(sync_info);
97            sys_map_ctrl(
98                self.handle.start(),
99                MAX_SIZE,
100                MapControlCmd::Sync(sync_info_ptr),
101                0,
102            )?;
103        }
104        Ok(())
105    }
106
107    pub fn into_object(self) -> Object<Base> {
108        unsafe { Object::from_handle_unchecked(self.into_handle()) }
109    }
110
111    pub fn as_object(&self) -> Object<Base> {
112        unsafe { Object::from_handle_unchecked(self.handle().clone()) }
113    }
114}
115
116impl<Base> RawObject for MutObject<Base> {
117    fn handle(&self) -> &ObjectHandle {
118        &self.handle
119    }
120}
121
122impl<Base: BaseType> TypedObject for MutObject<Base> {
123    type Base = Base;
124
125    fn base_ref(&self) -> Ref<'_, Self::Base> {
126        let base = self.base_ptr();
127        unsafe { Ref::from_raw_parts(base, self.handle()) }
128    }
129
130    #[inline]
131    fn base(&self) -> &Self::Base {
132        unsafe { self.base_ptr::<Self::Base>().as_ref().unwrap_unchecked() }
133    }
134}
135
136impl<T> AsRef<ObjectHandle> for MutObject<T> {
137    fn as_ref(&self) -> &ObjectHandle {
138        self.handle()
139    }
140}
141
142impl<B> From<MutObject<B>> for Object<B> {
143    fn from(mut_obj: MutObject<B>) -> Self {
144        unsafe { Object::from_handle_unchecked(mut_obj.into_handle()) }
145    }
146}