Skip to content

Commit

Permalink
avoid recursive retire during seize drop
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraheemdev committed May 11, 2024
1 parent 9fae704 commit d670849
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"

[dependencies]
atomic-wait = "1.1.0"
seize = "0.4.1"
seize = { git = "https://github.com/ibraheemdev/seize", branch = "reclaim-all" }

[dev-dependencies]
rand = "0.8.5"
Expand Down
13 changes: 10 additions & 3 deletions src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1612,7 +1612,7 @@ impl<'root, K, V, S> HashMapRef<'root, K, V, S> {
let raw: *mut RawTable = link.cast();
let table = Table::<K, V>::from_raw(raw);
drop_table::<K, V>(table);
})
});
}
}

Expand Down Expand Up @@ -1647,6 +1647,11 @@ impl<K, V, S> Drop for HashMap<K, V, S> {
fn drop(&mut self) {
let mut raw = *self.table.get_mut();

// make sure everything is reclaimed before the collector is dropped,
// because reclaiming a table depends on accessing the collector
// through a shared pointer
unsafe { self.collector.reclaim_all() };

while !raw.is_null() {
let mut table = unsafe { Table::<K, V>::from_raw(raw) };
let next = *table.state_mut().next.get_mut();
Expand Down Expand Up @@ -1675,11 +1680,13 @@ unsafe fn drop_entries<K, V>(table: Table<K, V>) {
}

unsafe fn drop_table<K, V>(mut table: Table<K, V>) {
// safety: `drop_table` is being called from `Drop` or from the reclaimer,
// both cases in which the collector is still alive
// safety: `drop_table` is being called from `reclaim_all` in `Drop`, or
// a table is being reclaimed by our thread, both cases in which the collector
// is still alive and safe to access through the stable pointer
let collector = unsafe { &*table.state().collector };

// drop any entries deferred during an incremental resize
//
// safety: a deferred entry was retired after it was made unreachable
// from the next table during a resize. because our table was still accessible
// for this entry to be deferred, our table must have been retired *after* the
Expand Down
6 changes: 6 additions & 0 deletions src/raw/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,9 @@ impl<T> Deref for AliasableBox<T> {
unsafe { &*self.0.as_ptr() }
}
}

impl<T> Drop for AliasableBox<T> {
fn drop(&mut self) {
let _ = unsafe { Box::from_raw(self.0.as_ptr()) };
}
}

0 comments on commit d670849

Please sign in to comment.