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)) { 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() { while !task.is_null() {
// Queue is empty, we're done // If the task re-enqueues itself, the `next` pointer will get overwritten.
return; // 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);
on_task(task);
task = (*task).next.load(Ordering::Relaxed); task = next
}
} }
} }
} }