From 4cc8bbd06ca2c5bf447921ca648aa074164095d2 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Sat, 31 Oct 2020 16:37:43 +0100 Subject: [PATCH] Remove unsafe from executor api --- embassy/src/executor/executor.rs | 42 ++++++++++++-------------- embassy/src/executor/timer_executor.rs | 4 +-- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/embassy/src/executor/executor.rs b/embassy/src/executor/executor.rs index e7bb659f..2f6bfad5 100644 --- a/embassy/src/executor/executor.rs +++ b/embassy/src/executor/executor.rs @@ -258,42 +258,40 @@ impl Executor { } /// Spawn a future on this executor. - /// - /// safety: can only be called from the executor thread - pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { + pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { let header = token.header; mem::forget(token); match header { - Some(header) => { + Some(header) => unsafe { let header = header.as_ref(); header.executor.set(self); self.enqueue(header as *const _ as _); Ok(()) - } + }, None => Err(SpawnError::Busy), } } /// Runs the executor until the queue is empty. - /// - /// safety: can only be called from the executor thread - pub unsafe fn run(&self) { - self.queue.dequeue_all(|p| { - let header = &*p; + pub fn run(&self) { + unsafe { + self.queue.dequeue_all(|p| { + let header = &*p; - let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel); - if state & STATE_RUNNING == 0 { - // If task is not running, ignore it. This can happen in the following scenario: - // - Task gets dequeued, poll starts - // - While task is being polled, it gets woken. It gets placed in the queue. - // - Task poll finishes, returning done=true - // - RUNNING bit is cleared, but the task is already in the queue. - return; - } + let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel); + if state & STATE_RUNNING == 0 { + // If task is not running, ignore it. This can happen in the following scenario: + // - Task gets dequeued, poll starts + // - While task is being polled, it gets woken. It gets placed in the queue. + // - Task poll finishes, returning done=true + // - RUNNING bit is cleared, but the task is already in the queue. + return; + } - // Run the task - header.poll_fn.read()(p as _); - }); + // Run the task + header.poll_fn.read()(p as _); + }); + } } } diff --git a/embassy/src/executor/timer_executor.rs b/embassy/src/executor/timer_executor.rs index 21a81383..1f89490f 100644 --- a/embassy/src/executor/timer_executor.rs +++ b/embassy/src/executor/timer_executor.rs @@ -34,14 +34,14 @@ impl TimerExecutor { /// Spawn a future on this executor. /// /// safety: can only be called from the executor thread - pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { + pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> { self.inner.spawn(token) } /// Runs the executor until the queue is empty. /// /// safety: can only be called from the executor thread - pub unsafe fn run(&'static self) { + pub fn run(&'static self) { with_timer_queue(&self.timer_queue, || { self.timer_queue.check_expirations(); self.inner.run();