Fix executor hanging in some cases where tasks wake themselves.

This commit is contained in:
Dario Nieuwenhuis 2020-10-19 22:08:37 +02:00
parent 53a064445f
commit 80ce73a2c1

View file

@ -110,18 +110,16 @@ impl Queue {
}
unsafe fn dequeue_all(&self, on_task: impl Fn(*mut Header)) {
loop {
let mut task = self.head.swap(ptr::null_mut(), Ordering::AcqRel);
let mut task = self.head.swap(ptr::null_mut(), Ordering::AcqRel);
if task.is_null() {
// Queue is empty, we're done
return;
}
while !task.is_null() {
// If the task re-enqueues itself, the `next` pointer will get overwritten.
// Therefore, first read the next pointer, and only then process the task.
let next = (*task).next.load(Ordering::Relaxed);
while !task.is_null() {
on_task(task);
task = (*task).next.load(Ordering::Relaxed);
}
on_task(task);
task = next
}
}
}