embedded_tls/
split.rs

1use atomic_polyfill::{AtomicBool, Ordering};
2
3pub trait SplitState: Clone {
4    fn same(&self, other: &Self) -> bool;
5    fn is_open(&self) -> bool;
6    fn set_open(&self, open: bool);
7}
8
9pub trait SplitStateContainer {
10    type State: SplitState;
11
12    fn state(self) -> Self::State;
13}
14
15pub struct SplitConnectionState {
16    is_open: AtomicBool,
17}
18
19impl Default for SplitConnectionState {
20    #[inline]
21    fn default() -> Self {
22        Self {
23            is_open: AtomicBool::new(true),
24        }
25    }
26}
27
28impl<'a> SplitStateContainer for &'a mut SplitConnectionState {
29    type State = &'a SplitConnectionState;
30
31    fn state(self) -> Self::State {
32        &*self
33    }
34}
35
36impl SplitState for &SplitConnectionState {
37    fn is_open(&self) -> bool {
38        self.is_open.load(Ordering::Acquire)
39    }
40
41    fn set_open(&self, open: bool) {
42        self.is_open.store(open, Ordering::Release);
43    }
44
45    fn same(&self, other: &Self) -> bool {
46        core::ptr::eq(*self, *other)
47    }
48}
49
50#[cfg(feature = "std")]
51pub use stdlib::ManagedSplitState;
52
53#[cfg(feature = "std")]
54mod stdlib {
55    use super::*;
56    use std::sync::Arc;
57
58    #[derive(Clone)]
59    pub struct ManagedSplitState(Arc<SplitConnectionState>);
60    impl ManagedSplitState {
61        pub(crate) fn new() -> Self {
62            Self(Arc::new(SplitConnectionState::default()))
63        }
64    }
65
66    impl SplitStateContainer for ManagedSplitState {
67        type State = ManagedSplitState;
68
69        fn state(self) -> Self::State {
70            self
71        }
72    }
73
74    impl SplitState for ManagedSplitState {
75        fn is_open(&self) -> bool {
76            self.0.as_ref().is_open()
77        }
78
79        fn set_open(&self, open: bool) {
80            self.0.as_ref().set_open(open)
81        }
82
83        fn same(&self, other: &Self) -> bool {
84            Arc::ptr_eq(&self.0, &other.0)
85        }
86    }
87}