twizzler/object/
object.rs1use std::marker::PhantomData;
2
3use twizzler_rt_abi::{
4 object::{MapFlags, ObjID, ObjectHandle},
5 Result,
6};
7
8use super::{MutObject, RawObject, TxObject, TypedObject};
9use crate::{marker::BaseType, ptr::Ref, util::maybe_remap};
10
11#[derive(Debug)]
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 unsafe fn open_unchecked(name: impl AsRef<str>, flags: MapFlags) -> Result<Self> {
149 let id = twizzler_rt_abi::fd::twz_rt_resolve_name(
150 twizzler_rt_abi::fd::NameResolver::Default,
151 name,
152 )?;
153 unsafe { Self::map_unchecked(id, flags) }
154 }
155
156 pub fn open(name: impl AsRef<str>, flags: MapFlags) -> Result<Self> {
158 let id = twizzler_rt_abi::fd::twz_rt_resolve_name(
159 twizzler_rt_abi::fd::NameResolver::Default,
160 name,
161 )?;
162 Self::map(id, flags)
163 }
164
165 pub fn id(&self) -> ObjID {
167 self.handle.id()
168 }
169
170 pub fn update(&mut self) -> Result<()> {
173 twizzler_rt_abi::object::twz_rt_update_handle(&mut self.handle)
174 }
175
176 pub unsafe fn sync(&mut self) -> Result<()> {
182 self.as_mut()?.sync()
183 }
184}
185
186impl<Base> RawObject for Object<Base> {
187 fn handle(&self) -> &ObjectHandle {
188 &self.handle
189 }
190}
191
192impl<Base: BaseType> TypedObject for Object<Base> {
193 type Base = Base;
194
195 fn base_ref(&self) -> Ref<'_, Self::Base> {
196 let base = self.base_ptr();
197 unsafe { Ref::from_raw_parts(base, self.handle()) }
198 }
199
200 #[inline]
201 fn base(&self) -> &Self::Base {
202 unsafe { self.base_ptr::<Self::Base>().as_ref().unwrap_unchecked() }
203 }
204}
205
206impl<T> AsRef<ObjectHandle> for Object<T> {
207 fn as_ref(&self) -> &ObjectHandle {
208 self.handle()
209 }
210}