embedded_threadsafe/safecells/
shared.rs1use crate::{runtime, LazyCell};
4use core::{
5 cell::UnsafeCell,
6 fmt::{self, Debug, Formatter},
7};
8
9pub struct SharedCell<T> {
11 inner: UnsafeCell<T>,
13}
14impl<T> SharedCell<T> {
15 pub const fn new(value: T) -> Self {
17 Self { inner: UnsafeCell::new(value) }
18 }
19
20 pub fn scope<F, FR>(&self, scope: F) -> FR
22 where
23 F: FnOnce(&mut T) -> FR,
24 {
25 let mut scope = Some(scope);
27 let mut result: Option<FR> = None;
28 let mut call_scope = || {
29 let scope = scope.take().expect("missing scope function");
31 let result_ = unsafe { self.raw(scope) };
32 result = Some(result_);
33 };
34
35 unsafe { runtime::_runtime_threadsafe_e0LtH0x3(&mut call_scope) };
37 result.expect("implementation scope did not set result value")
38 }
39
40 pub unsafe fn raw<F, FR>(&self, scope: F) -> FR
46 where
47 F: FnOnce(&mut T) -> FR,
48 {
49 let inner_ptr = self.inner.get();
51 let value = inner_ptr.as_mut().expect("unexpected NULL pointer inside cell");
52 scope(value)
53 }
54}
55impl<T> SharedCell<LazyCell<T>> {
56 pub fn lazy_scope<F, FR>(&self, scope: F) -> FR
61 where
62 F: FnOnce(&mut T) -> FR,
63 {
64 self.scope(|lazy| lazy.scope_mut(scope))
65 }
66}
67impl<T> Debug for SharedCell<T>
68where
69 T: Debug,
70{
71 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
72 self.scope(|value| value.fmt(f))
73 }
74}
75unsafe impl<T> Sync for SharedCell<T>
76where
77 T: Send,
78{
79 }