diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-12-03 00:56:16 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-12-03 00:56:16 +0100 |
| commit | 02abe00439ba873945bd6b60546a200b3da751f1 (patch) | |
| tree | 62724bbe40f58380ce7ce67125e10348c5867adb /embassy-net/src/stack.rs | |
| parent | f109e73c6d7ef2ad93102b7c8223f5cef30ef36f (diff) | |
net: don't use UnsafeCell.
The "must not be called reentrantly" invariant is too "global" to
maintain comfortably, and the cost of the RefCell is negligible,
so this was a case of premature optimization.
Diffstat (limited to 'embassy-net/src/stack.rs')
| -rw-r--r-- | embassy-net/src/stack.rs | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/embassy-net/src/stack.rs b/embassy-net/src/stack.rs index 3a7610758..631087405 100644 --- a/embassy-net/src/stack.rs +++ b/embassy-net/src/stack.rs | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | use core::cell::UnsafeCell; | 1 | use core::cell::RefCell; |
| 2 | use core::future::{poll_fn, Future}; | 2 | use core::future::{poll_fn, Future}; |
| 3 | use core::task::{Context, Poll}; | 3 | use core::task::{Context, Poll}; |
| 4 | 4 | ||
| @@ -62,8 +62,8 @@ pub enum ConfigStrategy { | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | pub struct Stack<D: Device> { | 64 | pub struct Stack<D: Device> { |
| 65 | pub(crate) socket: UnsafeCell<SocketStack>, | 65 | pub(crate) socket: RefCell<SocketStack>, |
| 66 | inner: UnsafeCell<Inner<D>>, | 66 | inner: RefCell<Inner<D>>, |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | struct Inner<D: Device> { | 69 | struct Inner<D: Device> { |
| @@ -81,8 +81,6 @@ pub(crate) struct SocketStack { | |||
| 81 | next_local_port: u16, | 81 | next_local_port: u16, |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | unsafe impl<D: Device> Send for Stack<D> {} | ||
| 85 | |||
| 86 | impl<D: Device + 'static> Stack<D> { | 84 | impl<D: Device + 'static> Stack<D> { |
| 87 | pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>( | 85 | pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>( |
| 88 | device: D, | 86 | device: D, |
| @@ -143,40 +141,38 @@ impl<D: Device + 'static> Stack<D> { | |||
| 143 | } | 141 | } |
| 144 | 142 | ||
| 145 | Self { | 143 | Self { |
| 146 | socket: UnsafeCell::new(socket), | 144 | socket: RefCell::new(socket), |
| 147 | inner: UnsafeCell::new(inner), | 145 | inner: RefCell::new(inner), |
| 148 | } | 146 | } |
| 149 | } | 147 | } |
| 150 | 148 | ||
| 151 | /// SAFETY: must not call reentrantly. | 149 | fn with<R>(&self, f: impl FnOnce(&SocketStack, &Inner<D>) -> R) -> R { |
| 152 | unsafe fn with<R>(&self, f: impl FnOnce(&SocketStack, &Inner<D>) -> R) -> R { | 150 | f(&*self.socket.borrow(), &*self.inner.borrow()) |
| 153 | f(&*self.socket.get(), &*self.inner.get()) | ||
| 154 | } | 151 | } |
| 155 | 152 | ||
| 156 | /// SAFETY: must not call reentrantly. | 153 | fn with_mut<R>(&self, f: impl FnOnce(&mut SocketStack, &mut Inner<D>) -> R) -> R { |
| 157 | unsafe fn with_mut<R>(&self, f: impl FnOnce(&mut SocketStack, &mut Inner<D>) -> R) -> R { | 154 | f(&mut *self.socket.borrow_mut(), &mut *self.inner.borrow_mut()) |
| 158 | f(&mut *self.socket.get(), &mut *self.inner.get()) | ||
| 159 | } | 155 | } |
| 160 | 156 | ||
| 161 | pub fn ethernet_address(&self) -> [u8; 6] { | 157 | pub fn ethernet_address(&self) -> [u8; 6] { |
| 162 | unsafe { self.with(|_s, i| i.device.device.ethernet_address()) } | 158 | self.with(|_s, i| i.device.device.ethernet_address()) |
| 163 | } | 159 | } |
| 164 | 160 | ||
| 165 | pub fn is_link_up(&self) -> bool { | 161 | pub fn is_link_up(&self) -> bool { |
| 166 | unsafe { self.with(|_s, i| i.link_up) } | 162 | self.with(|_s, i| i.link_up) |
| 167 | } | 163 | } |
| 168 | 164 | ||
| 169 | pub fn is_config_up(&self) -> bool { | 165 | pub fn is_config_up(&self) -> bool { |
| 170 | unsafe { self.with(|_s, i| i.config.is_some()) } | 166 | self.with(|_s, i| i.config.is_some()) |
| 171 | } | 167 | } |
| 172 | 168 | ||
| 173 | pub fn config(&self) -> Option<Config> { | 169 | pub fn config(&self) -> Option<Config> { |
| 174 | unsafe { self.with(|_s, i| i.config.clone()) } | 170 | self.with(|_s, i| i.config.clone()) |
| 175 | } | 171 | } |
| 176 | 172 | ||
| 177 | pub async fn run(&self) -> ! { | 173 | pub async fn run(&self) -> ! { |
| 178 | poll_fn(|cx| { | 174 | poll_fn(|cx| { |
| 179 | unsafe { self.with_mut(|s, i| i.poll(cx, s)) } | 175 | self.with_mut(|s, i| i.poll(cx, s)); |
| 180 | Poll::<()>::Pending | 176 | Poll::<()>::Pending |
| 181 | }) | 177 | }) |
| 182 | .await; | 178 | .await; |
