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),
}
}
/// Register an observer.
///
/// 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()
};
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.
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;
}