Fix //aos/common:event
I discovered while using ipc_comparison that it didn't properly handle
spurious wakeups. We don't use it very widely, so it's not surprising
that this bug went unnoticed.
Change-Id: I6675fa2f54ce185d0c67965c2a780ad550978133
diff --git a/aos/common/event.cc b/aos/common/event.cc
index ae32d39..af9c9c5 100644
--- a/aos/common/event.cc
+++ b/aos/common/event.cc
@@ -11,25 +11,28 @@
}
void Event::Wait() {
- int ret;
- do {
- ret = futex_wait(&impl_);
- } while (ret == 1);
- if (ret == 0) return;
- CHECK_EQ(-1, ret);
- PLOG(FATAL, "futex_wait(%p) failed", &impl_);
+ while (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) == 0) {
+ const int ret = futex_wait(&impl_);
+ if (ret != 0) {
+ CHECK_EQ(-1, ret);
+ PLOG(FATAL, "futex_wait(%p) failed", &impl_);
+ }
+ }
}
bool Event::WaitTimeout(const ::aos::time::Time &timeout) {
const auto timeout_timespec = timeout.ToTimespec();
- int ret;
- do {
- ret = futex_wait_timeout(&impl_, &timeout_timespec);
- } while (ret == 1);
- if (ret == 0) return true;
- if (ret == 2) return false;
- CHECK_EQ(-1, ret);
- PLOG(FATAL, "futex_wait(%p) failed", &impl_);
+ while (true) {
+ if (__atomic_load_n(&impl_, __ATOMIC_SEQ_CST) != 0) {
+ return true;
+ }
+ const int ret = futex_wait_timeout(&impl_, &timeout_timespec);
+ if (ret != 0) {
+ if (ret == 2) return false;
+ CHECK_EQ(-1, ret);
+ PLOG(FATAL, "futex_wait(%p) failed", &impl_);
+ }
+ }
}
// We're not going to expose the number woken because that's not easily portable