twizzler/object/
object.rs1use std::marker::PhantomData;
2
3use twizzler_abi::object::ObjID;
4use twizzler_rt_abi::{
5 object::{MapFlags, ObjectHandle},
6 Result,
7};
8
9use super::{MutObject, RawObject, TxObject, TypedObject};
10use crate::{marker::BaseType, ptr::Ref, util::maybe_remap};
11
12#[derive(Debug)]
13pub struct Object<Base> {
14 handle: ObjectHandle,
15 _pd: PhantomData<*const Base>,
16}
17
18unsafe impl<Base> Sync for Object<Base> {}
19unsafe impl<Base> Send for Object<Base> {}
20
21impl<B> Clone for Object<B> {
22 fn clone(&self) -> Self {
23 Self {
24 handle: self.handle.clone(),
25 _pd: PhantomData,
26 }
27 }
28}
29
30impl<Base> Object<Base> {
31 pub fn into_tx(self) -> Result<TxObject<Base>> {
42 TxObject::new(self)
43 }
44
45 pub fn as_tx(&self) -> Result<TxObject<Base>> {
56 TxObject::new(self.clone())
57 }
58
59 pub fn with_tx<R>(&mut self, f: impl FnOnce(&mut TxObject<Base>) -> Result<R>) -> Result<R> {
69 let mut tx = self.as_tx()?;
70 let r = f(&mut tx)?;
71 let _ = self
72 .update()
73 .inspect_err(|e| tracing::warn!("failed to update {} on with_tx: {}", self.id(), e));
74 Ok(r)
75 }
76
77 pub unsafe fn as_mut(&self) -> Result<MutObject<Base>> {
83 let (handle, _) = maybe_remap(self.handle().clone(), core::ptr::null_mut::<()>());
84 Ok(unsafe { MutObject::from_handle_unchecked(handle) })
85 }
86
87 pub unsafe fn into_mut(self) -> Result<MutObject<Base>> {
93 let (handle, _) = maybe_remap(self.into_handle(), core::ptr::null_mut::<()>());
94 Ok(unsafe { MutObject::from_handle_unchecked(handle) })
95 }
96
97 pub unsafe fn from_handle_unchecked(handle: ObjectHandle) -> Self {
98 Self {
99 handle,
100 _pd: PhantomData,
101 }
102 }
103
104 pub fn from_handle(handle: ObjectHandle) -> Result<Self> {
105 unsafe { Ok(Self::from_handle_unchecked(handle)) }
107 }
108
109 pub fn into_handle(self) -> ObjectHandle {
110 self.handle
111 }
112
113 pub unsafe fn cast<U>(self) -> Object<U> {
114 Object {
115 handle: self.handle,
116 _pd: PhantomData,
117 }
118 }
119
120 pub fn map(id: ObjID, flags: MapFlags) -> Result<Self> {
128 let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
130 tracing::debug!("map: {} {:?} => {:?}", id, flags, handle.start());
131 Self::from_handle(handle)
132 }
133
134 pub unsafe fn map_unchecked(id: ObjID, flags: MapFlags) -> Result<Self> {
140 let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
141 unsafe { Ok(Self::from_handle_unchecked(handle)) }
142 }
143
144 pub fn id(&self) -> ObjID {
146 self.handle.id()
147 }
148
149 pub fn update(&mut self) -> Result<()> {
152 twizzler_rt_abi::object::twz_rt_update_handle(&mut self.handle)
153 }
154
155 pub unsafe fn sync(&mut self) -> Result<()> {
161 self.as_mut()?.sync()
162 }
163}
164
165impl<Base> RawObject for Object<Base> {
166 fn handle(&self) -> &ObjectHandle {
167 &self.handle
168 }
169}
170
171impl<Base: BaseType> TypedObject for Object<Base> {
172 type Base = Base;
173
174 fn base_ref(&self) -> Ref<'_, Self::Base> {
175 let base = self.base_ptr();
176 unsafe { Ref::from_raw_parts(base, self.handle()) }
177 }
178
179 #[inline]
180 fn base(&self) -> &Self::Base {
181 unsafe { self.base_ptr::<Self::Base>().as_ref().unwrap_unchecked() }
182 }
183}
184
185impl<T> AsRef<ObjectHandle> for Object<T> {
186 fn as_ref(&self) -> &ObjectHandle {
187 self.handle()
188 }
189}