diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/gix-features/src/fs.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-features/src/fs.rs')
-rw-r--r-- | vendor/gix-features/src/fs.rs | 130 |
1 files changed, 0 insertions, 130 deletions
diff --git a/vendor/gix-features/src/fs.rs b/vendor/gix-features/src/fs.rs index f65779b92..f07ac1f0f 100644 --- a/vendor/gix-features/src/fs.rs +++ b/vendor/gix-features/src/fs.rs @@ -114,133 +114,3 @@ pub fn open_options_no_follow() -> std::fs::OpenOptions { } options } - -mod snapshot { - use std::ops::Deref; - - use crate::threading::{get_mut, get_ref, MutableOnDemand, OwnShared}; - - /// A structure holding enough information to reload a value if its on-disk representation changes as determined by its modified time. - #[derive(Debug)] - pub struct Snapshot<T: std::fmt::Debug> { - value: T, - modified: std::time::SystemTime, - } - - impl<T: Clone + std::fmt::Debug> Clone for Snapshot<T> { - fn clone(&self) -> Self { - Self { - value: self.value.clone(), - modified: self.modified, - } - } - } - - /// A snapshot of a resource which is up-to-date in the moment it is retrieved. - pub type SharedSnapshot<T> = OwnShared<Snapshot<T>>; - - /// Use this type for fields in structs that are to store the [`Snapshot`], typically behind an [`OwnShared`]. - /// - /// Note that the resource itself is behind another [`OwnShared`] to allow it to be used without holding any kind of lock, hence - /// without blocking updates while it is used. - #[derive(Debug, Default)] - pub struct MutableSnapshot<T: std::fmt::Debug>(pub MutableOnDemand<Option<SharedSnapshot<T>>>); - - impl<T: std::fmt::Debug> Deref for Snapshot<T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.value - } - } - - impl<T: std::fmt::Debug> Deref for MutableSnapshot<T> { - type Target = MutableOnDemand<Option<SharedSnapshot<T>>>; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl<T: std::fmt::Debug> MutableSnapshot<T> { - /// Create a new instance of this type. - /// - /// Useful in case `Default::default()` isn't working for some reason. - pub fn new() -> Self { - MutableSnapshot(MutableOnDemand::new(None)) - } - - /// Refresh `state` forcefully by re-`open`ing the resource. Note that `open()` returns `None` if the resource isn't - /// present on disk, and that it's critical that the modified time is obtained _before_ opening the resource. - pub fn force_refresh<E>( - &self, - open: impl FnOnce() -> Result<Option<(std::time::SystemTime, T)>, E>, - ) -> Result<(), E> { - let mut state = get_mut(&self.0); - *state = open()?.map(|(modified, value)| OwnShared::new(Snapshot { value, modified })); - Ok(()) - } - - /// Assure that the resource in `state` is up-to-date by comparing the `current_modification_time` with the one we know in `state` - /// and by acting accordingly. - /// Returns the potentially updated/reloaded resource if it is still present on disk, which then represents a snapshot that is up-to-date - /// in that very moment, or `None` if the underlying file doesn't exist. - /// - /// Note that even though this is racy, each time a request is made there is a chance to see the actual state. - pub fn recent_snapshot<E>( - &self, - mut current_modification_time: impl FnMut() -> Option<std::time::SystemTime>, - open: impl FnOnce() -> Result<Option<T>, E>, - ) -> Result<Option<SharedSnapshot<T>>, E> { - let state = get_ref(self); - let recent_modification = current_modification_time(); - let buffer = match (&*state, recent_modification) { - (None, None) => (*state).clone(), - (Some(_), None) => { - drop(state); - let mut state = get_mut(self); - *state = None; - (*state).clone() - } - (Some(snapshot), Some(modified_time)) => { - if snapshot.modified < modified_time { - drop(state); - let mut state = get_mut(self); - - if let (Some(_snapshot), Some(modified_time)) = (&*state, current_modification_time()) { - *state = open()?.map(|value| { - OwnShared::new(Snapshot { - value, - modified: modified_time, - }) - }); - } - - (*state).clone() - } else { - // Note that this relies on sub-section precision or else is a race when the packed file was just changed. - // It's nothing we can know though, so… up to the caller unfortunately. - Some(snapshot.clone()) - } - } - (None, Some(_modified_time)) => { - drop(state); - let mut state = get_mut(self); - // Still in the same situation? If so, load the buffer. This compensates for the trampling herd - // during lazy-loading at the expense of another mtime check. - if let (None, Some(modified_time)) = (&*state, current_modification_time()) { - *state = open()?.map(|value| { - OwnShared::new(Snapshot { - value, - modified: modified_time, - }) - }); - } - (*state).clone() - } - }; - Ok(buffer) - } - } -} -pub use snapshot::{MutableSnapshot, SharedSnapshot, Snapshot}; |