From 7c249cf0ca71fe9e288e504ead014a71d91a9906 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Wed, 25 Dec 2024 13:54:20 +0800 Subject: [PATCH] Fix the memory order in `Subject` --- kernel/src/events/subject.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kernel/src/events/subject.rs b/kernel/src/events/subject.rs index 8628dda69..fd9b2ad47 100644 --- a/kernel/src/events/subject.rs +++ b/kernel/src/events/subject.rs @@ -23,6 +23,7 @@ impl> Subject { num_observers: AtomicUsize::new(0), } } + /// Register an observer. /// /// A registered observer will get notified through its `on_events` method. @@ -37,7 +38,8 @@ impl> Subject { observers.insert(observer, filter).is_none() }; if is_new { - self.num_observers.fetch_add(1, Ordering::Relaxed); + // This `Acquire` pairs with the `Release` in `notify_observers`. + self.num_observers.fetch_add(1, Ordering::Acquire); } } @@ -66,7 +68,11 @@ impl> Subject { /// It will remove the observers which have been freed. pub fn notify_observers(&self, events: &E) { // Fast path. - if self.num_observers.load(Ordering::Relaxed) == 0 { + // + // Note: This must use `Release`, which pairs with `Acquire` in `register_observer`, to + // ensure that even if this fast path is used, a concurrently registered observer will see + // the event we want to notify. + if self.num_observers.fetch_add(0, Ordering::Release) == 0 { return; }