@@ -2815,10 +2815,12 @@ enum NotifyOption {
2815
2815
/// We allow callers to either always notify by constructing with `notify_on_drop` or choose to
2816
2816
/// notify or not based on whether relevant changes have been made, providing a closure to
2817
2817
/// `optionally_notify` which returns a `NotifyOption`.
2818
- struct PersistenceNotifierGuard<'a, F: FnMut () -> NotifyOption> {
2818
+ struct PersistenceNotifierGuard<'a, F: FnOnce () -> NotifyOption> {
2819
2819
event_persist_notifier: &'a Notifier,
2820
2820
needs_persist_flag: &'a AtomicBool,
2821
- should_persist: F,
2821
+ // Always `Some` once initialized, but tracked as an `Option` to obtain the closure by value in
2822
+ // [`PersistenceNotifierGuard::drop`].
2823
+ should_persist: Option<F>,
2822
2824
// We hold onto this result so the lock doesn't get released immediately.
2823
2825
_read_guard: RwLockReadGuard<'a, ()>,
2824
2826
}
@@ -2833,20 +2835,20 @@ impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> {
2833
2835
/// isn't ideal.
2834
2836
fn notify_on_drop<C: AChannelManager>(
2835
2837
cm: &'a C,
2836
- ) -> PersistenceNotifierGuard<'a, impl FnMut () -> NotifyOption> {
2838
+ ) -> PersistenceNotifierGuard<'a, impl FnOnce () -> NotifyOption> {
2837
2839
Self::optionally_notify(cm, || -> NotifyOption { NotifyOption::DoPersist })
2838
2840
}
2839
2841
2840
2842
#[rustfmt::skip]
2841
- fn optionally_notify<F: FnMut () -> NotifyOption, C: AChannelManager>(cm: &'a C, mut persist_check: F)
2842
- -> PersistenceNotifierGuard<'a, impl FnMut () -> NotifyOption> {
2843
+ fn optionally_notify<F: FnOnce () -> NotifyOption, C: AChannelManager>(cm: &'a C, persist_check: F)
2844
+ -> PersistenceNotifierGuard<'a, impl FnOnce () -> NotifyOption> {
2843
2845
let read_guard = cm.get_cm().total_consistency_lock.read().unwrap();
2844
2846
let force_notify = cm.get_cm().process_background_events();
2845
2847
2846
2848
PersistenceNotifierGuard {
2847
2849
event_persist_notifier: &cm.get_cm().event_persist_notifier,
2848
2850
needs_persist_flag: &cm.get_cm().needs_persist_flag,
2849
- should_persist: move || {
2851
+ should_persist: Some( move || {
2850
2852
// Pick the "most" action between `persist_check` and the background events
2851
2853
// processing and return that.
2852
2854
let notify = persist_check();
@@ -2857,7 +2859,7 @@ impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> {
2857
2859
(_, NotifyOption::SkipPersistHandleEvents) => NotifyOption::SkipPersistHandleEvents,
2858
2860
_ => NotifyOption::SkipPersistNoEvents,
2859
2861
}
2860
- },
2862
+ }) ,
2861
2863
_read_guard: read_guard,
2862
2864
}
2863
2865
}
@@ -2873,16 +2875,16 @@ impl<'a> PersistenceNotifierGuard<'a, fn() -> NotifyOption> {
2873
2875
PersistenceNotifierGuard {
2874
2876
event_persist_notifier: &cm.get_cm().event_persist_notifier,
2875
2877
needs_persist_flag: &cm.get_cm().needs_persist_flag,
2876
- should_persist: persist_check,
2878
+ should_persist: Some( persist_check) ,
2877
2879
_read_guard: read_guard,
2878
2880
}
2879
2881
}
2880
2882
}
2881
2883
2882
- impl<'a, F: FnMut () -> NotifyOption> Drop for PersistenceNotifierGuard<'a, F> {
2884
+ impl<'a, F: FnOnce () -> NotifyOption> Drop for PersistenceNotifierGuard<'a, F> {
2883
2885
#[rustfmt::skip]
2884
2886
fn drop(&mut self) {
2885
- match (self.should_persist)() {
2887
+ match (self.should_persist.take().unwrap() )() {
2886
2888
NotifyOption::DoPersist => {
2887
2889
self.needs_persist_flag.store(true, Ordering::Release);
2888
2890
self.event_persist_notifier.notify()
0 commit comments