Fix executor hanging in some cases where tasks wake themselves.
This commit is contained in:
parent
53a064445f
commit
80ce73a2c1
1 changed files with 8 additions and 10 deletions
|
@ -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
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue