Make re-using watcher structures from dead processes actually work
The previous version only worked if they exited gracefully.
Change-Id: I03ff152f54c94f0aa81a45ba64f5a7a68227e3fe
diff --git a/aos/ipc_lib/aos_sync.h b/aos/ipc_lib/aos_sync.h
index 8290faa..a61fcc1 100644
--- a/aos/ipc_lib/aos_sync.h
+++ b/aos/ipc_lib/aos_sync.h
@@ -95,7 +95,7 @@
// this mutex may not be used with any of the mutex_ functions.
// Initializes a variable which can be used to wait for this thread to die.
-// This can only be called once after initializing *m.
+// This can only be called once after initializing *m to 0.
void death_notification_init(aos_mutex *m);
// Manually triggers a death notification for this thread.
diff --git a/aos/ipc_lib/lockless_queue.cc b/aos/ipc_lib/lockless_queue.cc
index 78f990d..a4539f8 100644
--- a/aos/ipc_lib/lockless_queue.cc
+++ b/aos/ipc_lib/lockless_queue.cc
@@ -356,10 +356,14 @@
for (int i = 0; i < num_watchers; ++i) {
// If we see a slot the kernel has marked as dead, everything we do reusing
// it needs to happen-after whatever that process did before dying.
- const uint32_t tid =
- __atomic_load_n(&(memory_->GetWatcher(i)->tid.futex), __ATOMIC_ACQUIRE);
+ auto *const futex = &(memory_->GetWatcher(i)->tid.futex);
+ const uint32_t tid = __atomic_load_n(futex, __ATOMIC_ACQUIRE);
if (tid == 0 || (tid & FUTEX_OWNER_DIED)) {
watcher_index_ = i;
+ // Relaxed is OK here because we're the only task going to touch it
+ // between here and the write in death_notification_init below (other
+ // recovery is blocked by us holding the setup lock).
+ __atomic_store_n(futex, 0, __ATOMIC_RELAXED);
break;
}
}