hermit/
init_cell.rs

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