Remove unsafe from executor api

This commit is contained in:
Dario Nieuwenhuis 2020-10-31 16:37:43 +01:00
parent e9843c3f0a
commit 4cc8bbd06c
2 changed files with 22 additions and 24 deletions

View File

@ -258,42 +258,40 @@ impl Executor {
} }
/// Spawn a future on this executor. /// Spawn a future on this executor.
/// pub fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> {
/// safety: can only be called from the executor thread
pub unsafe fn spawn(&'static self, token: SpawnToken) -> Result<(), SpawnError> {
let header = token.header; let header = token.header;
mem::forget(token); mem::forget(token);
match header { match header {
Some(header) => { Some(header) => unsafe {
let header = header.as_ref(); let header = header.as_ref();
header.executor.set(self); header.executor.set(self);
self.enqueue(header as *const _ as _); self.enqueue(header as *const _ as _);
Ok(()) Ok(())
} },
None => Err(SpawnError::Busy), None => Err(SpawnError::Busy),
} }
} }
/// Runs the executor until the queue is empty. /// Runs the executor until the queue is empty.
/// pub fn run(&self) {
/// safety: can only be called from the executor thread unsafe {
pub unsafe fn run(&self) { self.queue.dequeue_all(|p| {
self.queue.dequeue_all(|p| { let header = &*p;
let header = &*p;
let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel); let state = header.state.fetch_and(!STATE_QUEUED, Ordering::AcqRel);
if state & STATE_RUNNING == 0 { if state & STATE_RUNNING == 0 {
// If task is not running, ignore it. This can happen in the following scenario: // If task is not running, ignore it. This can happen in the following scenario:
// - Task gets dequeued, poll starts // - Task gets dequeued, poll starts
// - While task is being polled, it gets woken. It gets placed in the queue. // - While task is being polled, it gets woken. It gets placed in the queue.
// - Task poll finishes, returning done=true // - Task poll finishes, returning done=true
// - RUNNING bit is cleared, but the task is already in the queue. // - RUNNING bit is cleared, but the task is already in the queue.
return; return;
} }
// Run the task // Run the task
header.poll_fn.read()(p as _); header.poll_fn.read()(p as _);
}); });
}
} }
} }

View File

@ -34,14 +34,14 @@ impl<A: Alarm> TimerExecutor<A> {
/// Spawn a future on this executor. /// Spawn a future on this executor.
/// ///
/// safety: can only be called from the executor thread /// 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) self.inner.spawn(token)
} }
/// Runs the executor until the queue is empty. /// Runs the executor until the queue is empty.
/// ///
/// safety: can only be called from the executor thread /// 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, || { with_timer_queue(&self.timer_queue, || {
self.timer_queue.check_expirations(); self.timer_queue.check_expirations();
self.inner.run(); self.inner.run();