hermit/
init_cell.rs

1#![cfg_attr(
2	all(
3		not(feature = "tcp"),
4		not(feature = "udp"),
5		not(feature = "vsock"),
6		not(feature = "fuse")
7	),
8	expect(dead_code)
9)]
10
11use hermit_sync::{OnceCell, SpinMutex};
12
13/// A cell for iteratively initializing a `OnceCell`.
14///
15/// This should be used as a stop-gap measure only.
16pub struct InitCell<T> {
17	init: SpinMutex<Option<T>>,
18	once: OnceCell<T>,
19}
20
21impl<T> InitCell<T> {
22	pub const fn new(val: T) -> Self {
23		Self {
24			init: SpinMutex::new(Some(val)),
25			once: OnceCell::new(),
26		}
27	}
28
29	pub fn with(&self, f: impl FnOnce(Option<&mut T>)) {
30		let mut guard = self.init.lock();
31		f((*guard).as_mut());
32	}
33
34	pub fn get(&self) -> Option<&T> {
35		self.once.get()
36	}
37
38	pub fn finalize(&self) -> &T {
39		self.once.get_or_init(|| self.init.lock().take().unwrap())
40	}
41}