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
12pub 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}