Take critical section instead of unsafe
This commit is contained in:
parent
c1120c7138
commit
edb8f21a74
@ -411,15 +411,6 @@ impl SyncExecutor {
|
||||
self.run_queue.dequeue_all(|p| {
|
||||
let task = p.header();
|
||||
|
||||
if !task.state.run_dequeue() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
trace::task_exec_begin(self, &p);
|
||||
|
||||
|
||||
@ -81,7 +81,16 @@ impl RunQueue {
|
||||
// safety: there are no concurrent accesses to `next`
|
||||
next = unsafe { task.header().run_queue_item.next.get() };
|
||||
|
||||
let run_task = task.header().state.run_dequeue();
|
||||
|
||||
if run_task {
|
||||
// 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.
|
||||
on_task(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,11 +63,19 @@ impl RunQueue {
|
||||
// If the task re-enqueues itself, the `next` pointer will get overwritten.
|
||||
// Therefore, first read the next pointer, and only then process the task.
|
||||
|
||||
// safety: we know if the task is enqueued, no one else will touch the `next` pointer.
|
||||
let cs = unsafe { CriticalSection::new() };
|
||||
let run_task = critical_section::with(|cs| {
|
||||
next = task.header().run_queue_item.next.borrow(cs).get();
|
||||
task.header().state.run_dequeue(cs)
|
||||
});
|
||||
|
||||
if run_task {
|
||||
// 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.
|
||||
on_task(task);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user