diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/gix-tempfile/src/registry.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip |
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-tempfile/src/registry.rs')
-rw-r--r-- | vendor/gix-tempfile/src/registry.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/vendor/gix-tempfile/src/registry.rs b/vendor/gix-tempfile/src/registry.rs new file mode 100644 index 000000000..9eaab23a6 --- /dev/null +++ b/vendor/gix-tempfile/src/registry.rs @@ -0,0 +1,67 @@ +use crate::REGISTRY; + +/// Remove all tempfiles still registered on our global registry, and leak their data to be signal-safe. +/// This happens on a best-effort basis with all errors being ignored. +/// +/// # Safety +/// Note that Mutexes of any kind are not allowed, and so aren't allocation or deallocation of memory. +/// We are using lock-free datastructures and sprinkle in `std::mem::forget` to avoid deallocating. +/// Most importantly, we use `try_lock()` which uses an atomic int only without blocking, making our register method safe to use, +/// at the expense of possibly missing a lock file if another thread wants to obtain it or put it back +/// (i.e. mutates the registry shard). +pub fn cleanup_tempfiles_signal_safe() { + let current_pid = std::process::id(); + #[cfg(feature = "hp-hashmap")] + { + use crate::NEXT_MAP_INDEX; + use std::sync::atomic::Ordering; + + let one_past_last_index = NEXT_MAP_INDEX.load(Ordering::SeqCst); + for idx in 0..one_past_last_index { + if let Some(entry) = REGISTRY.try_entry(idx) { + entry.and_modify(|tempfile| { + if tempfile + .as_ref() + .map_or(false, |tf| tf.owning_process_id == current_pid) + { + if let Some(tempfile) = tempfile.take() { + tempfile.drop_without_deallocation(); + } + } + }); + } + } + } + #[cfg(not(feature = "hp-hashmap"))] + { + REGISTRY.for_each(|tf| { + if tf.as_ref().map_or(false, |tf| tf.owning_process_id == current_pid) { + if let Some(tf) = tf.take() { + tf.drop_without_deallocation(); + } + } + }); + } +} + +/// Remove all tempfiles still registered on our global registry. +/// This happens on a best-effort basis with all errors being ignored. +/// +/// # Note +/// +/// Must not be called from within signal hooks. For that, use [`cleanup_tempfiles_signal_safe()`]. +pub fn cleanup_tempfiles() { + let current_pid = std::process::id(); + #[cfg(feature = "hp-hashmap")] + REGISTRY.iter_mut().for_each(|mut tf| { + if tf.as_ref().map_or(false, |tf| tf.owning_process_id == current_pid) { + tf.take(); + } + }); + #[cfg(not(feature = "hp-hashmap"))] + REGISTRY.for_each(|tf| { + if tf.as_ref().map_or(false, |tf| tf.owning_process_id == current_pid) { + tf.take(); + } + }); +} |