twizzler/object/
mutable.rs1use 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 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 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}