From d7925608f3bd488fb4bdaedcaedb1a030cb0fcf8 Mon Sep 17 00:00:00 2001 From: Zachary Dremann Date: Mon, 15 Apr 2024 15:40:59 -0400 Subject: [PATCH] Only reset directories if we modify the contents --- crates/applesauce/src/threads/mod.rs | 4 ++-- crates/applesauce/src/threads/writer.rs | 6 ++++++ crates/applesauce/src/times.rs | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/applesauce/src/threads/mod.rs b/crates/applesauce/src/threads/mod.rs index 02be126..b225689 100644 --- a/crates/applesauce/src/threads/mod.rs +++ b/crates/applesauce/src/threads/mod.rs @@ -76,7 +76,7 @@ pub struct Context { // Fields are dropped in top-down order, so ensure we update the parent's times before // dropping the operation (which will notify that the operation is done if this is the last // file). - _parent_reset: Option>, + parent_resetter: Option>, operation: Arc, path: PathBuf, progress: Box, @@ -205,7 +205,7 @@ impl BackgroundThreads { path, progress: inner_progress, orig_metadata: metadata, - _parent_reset: dir_reset, + parent_resetter: dir_reset, orig_times: saved_times, }), }) diff --git a/crates/applesauce/src/threads/writer.rs b/crates/applesauce/src/threads/writer.rs index 2db38c2..0a80963 100644 --- a/crates/applesauce/src/threads/writer.rs +++ b/crates/applesauce/src/threads/writer.rs @@ -157,6 +157,9 @@ impl Handler { let _entered = tracing::debug_span!("rename tmp file").entered(); tmp_file.persist(&item.context.path)? }; + if let Some(resetter) = &item.context.parent_resetter { + resetter.activate(); + } if let Err(e) = times::reset_times(&new_file, &item.context.orig_times) { tracing::error!("Unable to reset times: {e}"); } @@ -184,6 +187,9 @@ impl Handler { )?; let new_file = tmp_file.persist(&item.context.path)?; + if let Some(resetter) = &item.context.parent_resetter { + resetter.activate(); + } if let Err(e) = times::reset_times(&new_file, &item.context.orig_times) { tracing::error!("Unable to reset times: {e}"); } diff --git a/crates/applesauce/src/times.rs b/crates/applesauce/src/times.rs index 0834ad8..928d108 100644 --- a/crates/applesauce/src/times.rs +++ b/crates/applesauce/src/times.rs @@ -5,6 +5,7 @@ use std::mem::MaybeUninit; use std::os::fd::AsRawFd; use std::os::unix::ffi::OsStrExt; use std::path::Path; +use std::sync::atomic::AtomicBool; use std::{io, mem, ptr}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -200,10 +201,14 @@ pub fn reset_times(f: &F, saved: &Saved) - f.reset_times(saved) } +/// Reset the times of a file/dir +/// +/// By default, will do nothing on drop, unless `activate` is called at least once #[derive(Debug)] pub struct Resetter { dir_path: CString, saved_times: Saved, + activated: AtomicBool, } impl Resetter { @@ -212,12 +217,20 @@ impl Resetter { Ok(Self { dir_path, saved_times, + activated: AtomicBool::new(false), }) } + + pub fn activate(&self) { + self.activated + .store(true, std::sync::atomic::Ordering::Relaxed); + } } impl Drop for Resetter { fn drop(&mut self) { - let _ = times::reset_times(self.dir_path.as_c_str(), &self.saved_times); + if self.activated.load(std::sync::atomic::Ordering::Relaxed) { + let _ = times::reset_times(self.dir_path.as_c_str(), &self.saved_times); + } } }