diff --git a/src/directory/file_watcher.rs b/src/directory/file_watcher.rs index 28f85ec6f..c87b7a78a 100644 --- a/src/directory/file_watcher.rs +++ b/src/directory/file_watcher.rs @@ -28,7 +28,11 @@ impl FileWatcher { } pub fn spawn(&self) { - if self.state.compare_and_swap(0, 1, Ordering::SeqCst) > 0 { + if self + .state + .compare_exchange(0, 1, Ordering::SeqCst, Ordering::SeqCst) + .is_err() + { return; } diff --git a/src/reader/pool.rs b/src/reader/pool.rs index 7134e5adb..516ef766c 100644 --- a/src/reader/pool.rs +++ b/src/reader/pool.rs @@ -100,20 +100,32 @@ impl Pool { /// At the exit of this method, /// - freshest_generation has a value greater or equal than generation - /// - freshest_generation has a value that has been advertised - /// - freshest_generation has) + /// - freshest_generation has the last value that has been advertised fn advertise_generation(&self, generation: usize) { // not optimal at all but the easiest to read proof. + let mut former_generation = self.freshest_generation.load(Ordering::Acquire); loop { - let former_generation = self.freshest_generation.load(Ordering::Acquire); - if former_generation >= generation { - break; - } - self.freshest_generation.compare_and_swap( + match self.freshest_generation.compare_exchange( former_generation, generation, Ordering::SeqCst, - ); + Ordering::SeqCst, + ) { + Ok(_) => { + // We successfuly updated the value. + return; + } + Err(current_generation) => { + // The value was updated after we did our load apparently. + // In theory, it is always a value greater than ours, but just to + // simplify the logic, we keep looping until we reach a + // value >= to our target value. + if current_generation >= generation { + return; + } + former_generation = current_generation; + } + } } }