aboutsummaryrefslogtreecommitdiff
path: root/embassy-hal-common
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-06-09 21:28:13 +0200
committerGitHub <[email protected]>2022-06-09 21:28:13 +0200
commitdb344c2bda55bd0352a43720788185cc4d3a420e (patch)
treeb93b2d927d5c84b74dce456f9be5e88ec4bbfe18 /embassy-hal-common
parent77c7d8f31b89d13117a7294842d60f02950fdd23 (diff)
common/PeripheralMutex: remove unsafe API. (#802)
Following the project's decision that "leak unsafe" APIs are not marked as "unsafe", update PeripheralMutex to accept non-'static state without unsafe. Fixes #801
Diffstat (limited to 'embassy-hal-common')
-rw-r--r--embassy-hal-common/src/peripheral.rs26
1 files changed, 2 insertions, 24 deletions
diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs
index 89420a422..db2bc7888 100644
--- a/embassy-hal-common/src/peripheral.rs
+++ b/embassy-hal-common/src/peripheral.rs
@@ -52,33 +52,11 @@ pub(crate) fn can_be_preempted(irq: &impl Interrupt) -> bool {
52impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { 52impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
53 /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state. 53 /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state.
54 /// 54 ///
55 /// self requires `S` to live for `'static`, because if the `PeripheralMutex` is leaked, the
56 /// interrupt won't be disabled, which may try accessing the state at any time. To use non-`'static`
57 /// state, see [`Self::new_unchecked`].
58 ///
59 /// Registers `on_interrupt` as the `irq`'s handler, and enables it. 55 /// Registers `on_interrupt` as the `irq`'s handler, and enables it.
60 pub fn new( 56 pub fn new(
61 irq: S::Interrupt, 57 irq: S::Interrupt,
62 storage: &'a mut StateStorage<S>, 58 storage: &'a mut StateStorage<S>,
63 init: impl FnOnce() -> S, 59 init: impl FnOnce() -> S,
64 ) -> Self
65 where
66 'a: 'static,
67 {
68 // safety: safe because state is `'static`.
69 unsafe { Self::new_unchecked(irq, storage, init) }
70 }
71
72 /// Create a `PeripheralMutex` without requiring the state is `'static`.
73 ///
74 /// See also [`Self::new`].
75 ///
76 /// # Safety
77 /// The created instance must not be leaked (its `drop` must run).
78 pub unsafe fn new_unchecked(
79 irq: S::Interrupt,
80 storage: &'a mut StateStorage<S>,
81 init: impl FnOnce() -> S,
82 ) -> Self { 60 ) -> Self {
83 if can_be_preempted(&irq) { 61 if can_be_preempted(&irq) {
84 panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"); 62 panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps");
@@ -88,10 +66,10 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
88 66
89 // Safety: The pointer is valid and not used by anyone else 67 // Safety: The pointer is valid and not used by anyone else
90 // because we have the `&mut StateStorage`. 68 // because we have the `&mut StateStorage`.
91 state_ptr.write(init()); 69 unsafe { state_ptr.write(init()) };
92 70
93 irq.disable(); 71 irq.disable();
94 irq.set_handler(|p| { 72 irq.set_handler(|p| unsafe {
95 // Safety: it's OK to get a &mut to the state, since 73 // Safety: it's OK to get a &mut to the state, since
96 // - We checked that the thread owning the `PeripheralMutex` can't preempt us in `new`. 74 // - We checked that the thread owning the `PeripheralMutex` can't preempt us in `new`.
97 // Interrupts' priorities can only be changed with raw embassy `Interrupts`, 75 // Interrupts' priorities can only be changed with raw embassy `Interrupts`,