You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dirstat/src/defer_drop.rs

41 lines
1.7 KiB

//! Mechanism to defer dropping of large objects to background threads
use super::*;
use futures::{
prelude::*,
future::OptionFuture,
};
pub const DEFER_DROP_VEC_SIZE_FLOOR: usize = 1024 * 1024; // 1 MB
/// Drop a `Vec<T>` that is `Send` and `'static`.
///
/// This will move the object to a background task if it is deemed nessisary.
/// # Note
/// This *must* be `await`ed to work properly. If you are not in an async context, use `drop_vec_sync`.
pub fn drop_vec<T>(vec: Vec<T>) -> impl Future<Output = ()> + 'static
where T: Send + 'static
{
let len_bytes = vec.len() * std::mem::size_of::<T>();
OptionFuture::from(if len_bytes > DEFER_DROP_VEC_SIZE_FLOOR {
cfg_eprintln!(Verbose; config::get_global(), "Size of vector ({} bytes, {} elements of {:?}) exceeds defer drop size floor {}. Moving vector to a seperate thread for de-allocation", len_bytes, vec.len(), std::any::type_name::<T>(), DEFER_DROP_VEC_SIZE_FLOOR);
Some(async move {
tokio::task::spawn_blocking(move || drop(vec)).await.expect("Child panic while dropping vector");
})
} else {
None
}).map(|_| ())
}
/// Drop a `Vec<T>` that is `Send` and `'static`.
///
/// This will move the object to a background task if it is deemed nessisary.
pub fn drop_vec_sync<T>(vec: Vec<T>)
where T: Send + 'static
{
let len_bytes = vec.len() * std::mem::size_of::<T>();
if len_bytes > DEFER_DROP_VEC_SIZE_FLOOR {
cfg_eprintln!(Verbose; config::get_global(), "Size of vector ({} bytes, {} elements of {:?}) exceeds defer drop size floor {}. Moving vector to a seperate thread for de-allocation", len_bytes, vec.len(), std::any::type_name::<T>(), DEFER_DROP_VEC_SIZE_FLOOR);
tokio::task::spawn_blocking(move || drop(vec));
}
}