aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2020-10-19 22:08:37 +0200
committerDario Nieuwenhuis <[email protected]>2020-10-19 22:08:37 +0200
commit80ce73a2c1535d70752f06cbcd9f6ebd33904a05 (patch)
tree5ccca580ae7a494ff3b896beb5cb5c34dfb6d6c7
parent53a064445f5d4761992bf2801b044586cc7dbeaf (diff)
Fix executor hanging in some cases where tasks wake themselves.
-rw-r--r--embassy/src/executor/executor.rs18
1 files changed, 8 insertions, 10 deletions
diff --git a/embassy/src/executor/executor.rs b/embassy/src/executor/executor.rs
index 62b781bad..43127d61c 100644
--- a/embassy/src/executor/executor.rs
+++ b/embassy/src/executor/executor.rs
@@ -110,18 +110,16 @@ impl Queue {
110 } 110 }
111 111
112 unsafe fn dequeue_all(&self, on_task: impl Fn(*mut Header)) { 112 unsafe fn dequeue_all(&self, on_task: impl Fn(*mut Header)) {
113 loop { 113 let mut task = self.head.swap(ptr::null_mut(), Ordering::AcqRel);
114 let mut task = self.head.swap(ptr::null_mut(), Ordering::AcqRel);
115 114
116 if task.is_null() { 115 while !task.is_null() {
117 // Queue is empty, we're done 116 // If the task re-enqueues itself, the `next` pointer will get overwritten.
118 return; 117 // Therefore, first read the next pointer, and only then process the task.
119 } 118 let next = (*task).next.load(Ordering::Relaxed);
120 119
121 while !task.is_null() { 120 on_task(task);
122 on_task(task); 121
123 task = (*task).next.load(Ordering::Relaxed); 122 task = next
124 }
125 } 123 }
126 } 124 }
127} 125}