Fix the memory order in Subject

This commit is contained in:
Ruihan Li 2024-12-25 13:54:20 +08:00 committed by Tate, Hongliang Tian
parent 8a27f7a3b5
commit 7c249cf0ca

View File

@ -23,6 +23,7 @@ impl<E: Events, F: EventsFilter<E>> Subject<E, F> {
num_observers: AtomicUsize::new(0), num_observers: AtomicUsize::new(0),
} }
} }
/// Register an observer. /// Register an observer.
/// ///
/// A registered observer will get notified through its `on_events` method. /// A registered observer will get notified through its `on_events` method.
@ -37,7 +38,8 @@ impl<E: Events, F: EventsFilter<E>> Subject<E, F> {
observers.insert(observer, filter).is_none() observers.insert(observer, filter).is_none()
}; };
if is_new { 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<E: Events, F: EventsFilter<E>> Subject<E, F> {
/// It will remove the observers which have been freed. /// It will remove the observers which have been freed.
pub fn notify_observers(&self, events: &E) { pub fn notify_observers(&self, events: &E) {
// Fast path. // 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; return;
} }