aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2020-10-31 16:37:43 +0100
committerDario Nieuwenhuis <[email protected]>2020-10-31 16:37:50 +0100
commit4cc8bbd06ca2c5bf447921ca648aa074164095d2 (patch)
tree97137a673b76d38f266cb4d8253d78015e6b3ea5
parente9843c3f0a521311ddbe7316303913f295bf7e33 (diff)
Remove unsafe from executor api
-rw-r--r--embassy/src/executor/executor.rs46
-rw-r--r--embassy/src/executor/timer_executor.rs4
2 files changed, 24 insertions, 26 deletions
diff --git a/embassy/src/executor/executor.rs b/embassy/src/executor/executor.rs
index e7bb659fb..2f6bfad58 100644
--- a/embassy/src/executor/executor.rs
+++ b/embassy/src/executor/executor.rs
@@ -258,42 +258,40 @@ impl Executor {
258 } 258 }
259 259
260 /// Spawn a future on this executor. 260 /// Spawn a future on this executor.
261 /// 261 pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> {
262 /// safety: can only be called from the executor thread
263 pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> {
264 let header = token.header; 262 let header = token.header;
265 mem::forget(token); 263 mem::forget(token);
266 264
267 match header { 265 match header {
268 Some(header) => { 266 Some(header) => unsafe {
269 let header = header.as_ref(); 267 let header = header.as_ref();
270 header.executor.set(self); 268 header.executor.set(self);
271 self.enqueue(header as *const _ as _); 269 self.enqueue(header as *const _ as _);
272 Ok(()) 270 Ok(())
273 } 271 },
274 None => Err(SpawnError::Busy), 272 None => Err(SpawnError::Busy),
275 } 273 }
276 } 274 }
277 275
278 /// Runs the executor until the queue is empty. 276 /// Runs the executor until the queue is empty.
279 /// 277 pub fn run(&self) {
280 /// safety: can only be called from the executor thread 278 unsafe {
281 pub unsafe fn run(&self) { 279 self.queue.dequeue_all(|p| {
282 self.queue.dequeue_all(|p| { 280 let header = &*p;
283 let header = &*p; 281
284 282 let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel);
285 let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel); 283 if state & STATE_RUNNING == 0 {
286 if state & STATE_RUNNING == 0 { 284 // If task is not running, ignore it. This can happen in the following scenario:
287 // If task is not running, ignore it. This can happen in the following scenario: 285 // - Task gets dequeued, poll starts
288 // - Task gets dequeued, poll starts 286 // - While task is being polled, it gets woken. It gets placed in the queue.
289 // - While task is being polled, it gets woken. It gets placed in the queue. 287 // - Task poll finishes, returning done=true
290 // - Task poll finishes, returning done=true 288 // - RUNNING bit is cleared, but the task is already in the queue.
291 // - RUNNING bit is cleared, but the task is already in the queue. 289 return;
292 return; 290 }
293 } 291
294 292 // Run the task
295 // Run the task 293 header.poll_fn.read()(p as _);
296 header.poll_fn.read()(p as _); 294 });
297 }); 295 }
298 } 296 }
299} 297}
diff --git a/embassy/src/executor/timer_executor.rs b/embassy/src/executor/timer_executor.rs
index 21a81383a..1f89490f2 100644
--- a/embassy/src/executor/timer_executor.rs
+++ b/embassy/src/executor/timer_executor.rs
@@ -34,14 +34,14 @@ impl<A: Alarm> TimerExecutor<A> {
34 /// Spawn a future on this executor. 34 /// Spawn a future on this executor.
35 /// 35 ///
36 /// safety: can only be called from the executor thread 36 /// safety: can only be called from the executor thread
37 pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { 37 pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> {
38 self.inner.spawn(token) 38 self.inner.spawn(token)
39 } 39 }
40 40
41 /// Runs the executor until the queue is empty. 41 /// Runs the executor until the queue is empty.
42 /// 42 ///
43 /// safety: can only be called from the executor thread 43 /// safety: can only be called from the executor thread
44 pub unsafe fn run(&'static self) { 44 pub fn run(&'static self) {
45 with_timer_queue(&self.timer_queue, || { 45 with_timer_queue(&self.timer_queue, || {
46 self.timer_queue.check_expirations(); 46 self.timer_queue.check_expirations();
47 self.inner.run(); 47 self.inner.run();