Skip to content

Commit

Permalink
Merge pull request #384 from moka-rs/run-gc-when-drop
Browse files Browse the repository at this point in the history
Ensure `crossbeam-epoch` to run GC when dropping a cache
  • Loading branch information
tatsuya6502 authored Jan 20, 2024
2 parents 9303de3 + a79eae2 commit a8c6845
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/future/base_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,21 @@ pub(crate) struct Inner<K, V, S> {
clocks: Clocks,
}

impl<K, V, S> Drop for Inner<K, V, S> {
fn drop(&mut self) {
// Ensure crossbeam-epoch to collect garbages (`deferred_fn`s) in the
// global bag so that previously cached values will be dropped.
for _ in 0..128 {
crossbeam_epoch::pin().flush();
}

// NOTE: The `CacheStore` (`cht`) will be dropped after returning from this
// `drop` method. It uses crossbeam-epoch internally, but we do not have to
// call `flush` for it because its `drop` methods do not create
// `deferred_fn`s, and drop its values in place.
}
}

//
// functions/methods used by BaseCache
//
Expand Down
12 changes: 12 additions & 0 deletions src/future/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5454,6 +5454,18 @@ mod tests {
assert_eq!(counters.value_dropped(), KEYS, "value_dropped");
}

// https://github.com/moka-rs/moka/issues/383
#[tokio::test]
async fn ensure_gc_runs_when_dropping_cache() {
let cache = Cache::builder().build();
let val = Arc::new(0);
cache
.get_with(1, std::future::ready(Arc::clone(&val)))
.await;
drop(cache);
assert_eq!(Arc::strong_count(&val), 1);
}

#[tokio::test]
async fn test_debug_format() {
let cache = Cache::new(10);
Expand Down
13 changes: 13 additions & 0 deletions src/sync/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4831,6 +4831,19 @@ mod tests {
assert_eq!(counters.value_dropped(), KEYS, "value_dropped");
}

// https://github.com/moka-rs/moka/issues/383
#[test]
fn ensure_gc_runs_when_dropping_cache() {
let cache = Cache::builder().build();
let val = Arc::new(0);
{
let val = Arc::clone(&val);
cache.get_with(1, move || val);
}
drop(cache);
assert_eq!(Arc::strong_count(&val), 1);
}

#[test]
fn test_debug_format() {
let cache = Cache::new(10);
Expand Down
15 changes: 15 additions & 0 deletions src/sync_base/base_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,21 @@ pub(crate) struct Inner<K, V, S> {
clocks: Clocks,
}

impl<K, V, S> Drop for Inner<K, V, S> {
fn drop(&mut self) {
// Ensure crossbeam-epoch to collect garbages (`deferred_fn`s) in the
// global bag so that previously cached values will be dropped.
for _ in 0..128 {
crossbeam_epoch::pin().flush();
}

// NOTE: The `CacheStore` (`cht`) will be dropped after returning from this
// `drop` method. It uses crossbeam-epoch internally, but we do not have to
// call `flush` for it because its `drop` methods do not create
// `deferred_fn`s, and drop its values in place.
}
}

//
// functions/methods used by BaseCache
//
Expand Down

0 comments on commit a8c6845

Please sign in to comment.