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