twizzler/object/
mutable.rs

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