twizzler/object/
builder.rs1use std::{marker::PhantomData, mem::MaybeUninit};
2
3use twizzler_abi::{
4 object::{ObjID, Protections},
5 syscall::{
6 BackingType, CreateTieSpec, LifetimeType, ObjectCreate, ObjectCreateFlags, ObjectSource,
7 },
8};
9use twizzler_rt_abi::{bindings::CREATE_KIND_NEW, object::MapFlags};
10
11use super::{Object, TxObject};
12use crate::{
13 marker::{BaseType, StoreCopy},
14 Result,
15};
16
17#[derive(Clone)]
19pub struct ObjectBuilder<Base: BaseType> {
20 spec: ObjectCreate,
21 src_objs: Vec<ObjectSource>,
22 ties: Vec<CreateTieSpec>,
23 name: Option<String>,
24 _pd: PhantomData<Base>,
25}
26
27impl<Base: BaseType> ObjectBuilder<Base> {
28 pub fn new(spec: ObjectCreate) -> Self {
30 Self {
31 spec,
32 _pd: PhantomData,
33 name: None,
34 src_objs: Vec::new(),
35 ties: Vec::new(),
36 }
37 }
38
39 pub fn persist(mut self) -> Self {
41 self.spec.lt = LifetimeType::Persistent;
42 self
43 }
44
45 pub fn cast<U: BaseType>(self) -> ObjectBuilder<U> {
47 ObjectBuilder::<U>::new(self.spec)
48 }
49
50 pub fn add_src(mut self, obj_src: ObjectSource) -> Self {
52 self.src_objs.push(obj_src);
53 self
54 }
55
56 pub fn add_tie(mut self, tie: CreateTieSpec) -> Self {
58 self.ties.push(tie);
59 self
60 }
61
62 pub fn named(mut self, name: impl ToString) -> Self {
63 self.name = Some(name.to_string());
64 self
65 }
66}
67
68fn bind_name(id: ObjID, name: &str) -> Result<()> {
69 let create = twizzler_rt_abi::bindings::create_options {
70 id: id.raw(),
71 kind: CREATE_KIND_NEW,
72 };
73 let fd = twizzler_rt_abi::fd::twz_rt_fd_open(name, create, 0)?;
74 twizzler_rt_abi::fd::twz_rt_fd_close(fd);
75 Ok(())
76}
77
78impl<Base: BaseType + StoreCopy> ObjectBuilder<Base> {
79 pub fn build(&self, base: Base) -> Result<Object<Base>> {
87 self.build_inplace(|tx| tx.write(base))
88 }
89}
90
91impl<Base: BaseType> ObjectBuilder<Base> {
92 pub fn build_inplace<F>(&self, ctor: F) -> Result<Object<Base>>
103 where
104 F: FnOnce(TxObject<MaybeUninit<Base>>) -> Result<TxObject<Base>>,
105 {
106 let id = twizzler_abi::syscall::sys_object_create(
107 self.spec,
108 self.src_objs.as_slice(),
109 self.ties.as_slice(),
110 )?;
111 let mut flags = MapFlags::READ | MapFlags::WRITE;
112 if self.spec.lt == LifetimeType::Persistent {
113 flags.insert(MapFlags::PERSIST);
114 if let Some(ref name) = self.name {
115 bind_name(id, name)?;
116 }
117 } else {
118 if let Some(ref name) = self.name {
119 tracing::warn!(
120 "tried to name volatile object at creation time: {} {}",
121 id,
122 name
123 );
124 }
125 }
126 let mu_object = unsafe { Object::<MaybeUninit<Base>>::map_unchecked(id, flags) }?;
127 let object = ctor(mu_object.into_tx()?)?;
128 object.into_object()
129 }
130
131 pub unsafe fn build_ctor<F>(&self, ctor: F) -> Result<Object<Base>>
153 where
154 F: FnOnce(&mut TxObject<MaybeUninit<Base>>),
155 {
156 self.build_inplace(|mut tx| {
157 ctor(&mut tx);
158 Ok(tx.assume_init())
159 })
160 }
161}
162
163impl<Base: BaseType> Default for ObjectBuilder<Base> {
164 fn default() -> Self {
165 Self::new(ObjectCreate::new(
166 BackingType::Normal,
167 LifetimeType::Volatile,
168 None,
169 ObjectCreateFlags::empty(),
170 Protections::all(),
171 ))
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::ObjectBuilder;
178 use crate::{marker::BaseType, object::TypedObject, ptr::InvPtr};
179
180 #[test]
181 fn builder_simple() {
182 let builder = ObjectBuilder::default();
183 let obj = builder.build(42u32).unwrap();
184 let base = obj.base();
185 assert_eq!(*base, 42);
186 }
187
188 struct Foo {
189 ptr: InvPtr<u32>,
190 }
191 impl BaseType for Foo {}
192
193 #[test]
194 fn builder_complex() {
195 let builder = ObjectBuilder::default();
196 let obj_1 = builder.build(42u32).unwrap();
197 let base = obj_1.base_ref();
198 assert_eq!(*base, 42);
199
200 let builder = ObjectBuilder::<Foo>::default();
201 let obj = builder
202 .build_inplace(|tx| {
203 let foo = Foo {
204 ptr: InvPtr::new(&tx, base)?,
205 };
206 tx.write(foo)
207 })
208 .unwrap();
209 let base_foo = obj.base();
210 let r = unsafe { base_foo.ptr.resolve() };
211 assert_eq!(*r, 42);
212 }
213}