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
12pub struct Object<Base> {
13 handle: ObjectHandle,
14 _pd: PhantomData<*const Base>,
15}
16
17unsafe impl<Base> Sync for Object<Base> {}
18unsafe impl<Base> Send for Object<Base> {}
19
20impl<B> Clone for Object<B> {
21 fn clone(&self) -> Self {
22 Self {
23 handle: self.handle.clone(),
24 _pd: PhantomData,
25 }
26 }
27}
28
29impl<Base> Object<Base> {
30 pub fn into_tx(self) -> Result<TxObject<Base>> {
41 TxObject::new(self)
42 }
43
44 pub fn as_tx(&self) -> Result<TxObject<Base>> {
55 TxObject::new(self.clone())
56 }
57
58 pub fn with_tx<R>(&mut self, f: impl FnOnce(&mut TxObject<Base>) -> Result<R>) -> Result<R> {
68 let mut tx = self.as_tx()?;
69 let r = f(&mut tx)?;
70 let _ = self
71 .update()
72 .inspect_err(|e| tracing::warn!("failed to update {} on with_tx: {}", self.id(), e));
73 Ok(r)
74 }
75
76 pub unsafe fn as_mut(&self) -> Result<MutObject<Base>> {
82 let (handle, _) = maybe_remap(self.handle().clone(), core::ptr::null_mut::<()>());
83 Ok(unsafe { MutObject::from_handle_unchecked(handle) })
84 }
85
86 pub unsafe fn into_mut(self) -> Result<MutObject<Base>> {
92 let (handle, _) = maybe_remap(self.into_handle(), core::ptr::null_mut::<()>());
93 Ok(unsafe { MutObject::from_handle_unchecked(handle) })
94 }
95
96 pub unsafe fn from_handle_unchecked(handle: ObjectHandle) -> Self {
97 Self {
98 handle,
99 _pd: PhantomData,
100 }
101 }
102
103 pub fn from_handle(handle: ObjectHandle) -> Result<Self> {
104 unsafe { Ok(Self::from_handle_unchecked(handle)) }
106 }
107
108 pub fn into_handle(self) -> ObjectHandle {
109 self.handle
110 }
111
112 pub unsafe fn cast<U>(self) -> Object<U> {
113 Object {
114 handle: self.handle,
115 _pd: PhantomData,
116 }
117 }
118
119 pub fn map(id: ObjID, flags: MapFlags) -> Result<Self> {
127 let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
129 tracing::debug!("map: {} {:?} => {:?}", id, flags, handle.start());
130 Self::from_handle(handle)
131 }
132
133 pub unsafe fn map_unchecked(id: ObjID, flags: MapFlags) -> Result<Self> {
139 let handle = twizzler_rt_abi::object::twz_rt_map_object(id, flags)?;
140 unsafe { Ok(Self::from_handle_unchecked(handle)) }
141 }
142
143 pub fn id(&self) -> ObjID {
145 self.handle.id()
146 }
147
148 pub fn update(&mut self) -> Result<()> {
151 twizzler_rt_abi::object::twz_rt_update_handle(&mut self.handle)
152 }
153}
154
155impl<Base> RawObject for Object<Base> {
156 fn handle(&self) -> &ObjectHandle {
157 &self.handle
158 }
159}
160
161impl<Base: BaseType> TypedObject for Object<Base> {
162 type Base = Base;
163
164 fn base_ref(&self) -> Ref<'_, Self::Base> {
165 let base = self.base_ptr();
166 unsafe { Ref::from_raw_parts(base, self.handle()) }
167 }
168
169 #[inline]
170 fn base(&self) -> &Self::Base {
171 unsafe { self.base_ptr::<Self::Base>().as_ref().unwrap_unchecked() }
172 }
173}
174
175impl<T> AsRef<ObjectHandle> for Object<T> {
176 fn as_ref(&self) -> &ObjectHandle {
177 self.handle()
178 }
179}