Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.

Commit 60109ca

Browse files
committed
concurrent_hash_map: fix free_data()
If free_data() was called twice this led to assertion failure and possible double free. This patch skips freeing data when tls_ptr is already nullptr.
1 parent 9ed63df commit 60109ca

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

include/libpmemobj++/container/concurrent_hash_map.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,9 @@ class concurrent_hash_map
23162316
void
23172317
free_data()
23182318
{
2319+
if (!this->tls_ptr)
2320+
return;
2321+
23192322
auto pop = get_pool_base();
23202323

23212324
transaction::run(pop, [&] {

tests/concurrent_hash_map_tx/concurrent_hash_map_tx.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,28 @@ test_tx_singlethread(nvobj::pool<root> &pop)
358358

359359
UT_ASSERT(static_cast<int>(map->size()) == number_of_inserts);
360360

361+
try {
362+
pmem::obj::transaction::run(pop, [&] {
363+
map->free_data();
364+
pmem::obj::transaction::abort(0);
365+
});
366+
} catch (pmem::manual_tx_abort &) {
367+
} catch (...) {
368+
UT_ASSERT(0);
369+
}
370+
371+
verify_elements(pop, number_of_inserts);
372+
373+
try {
374+
pmem::obj::transaction::run(pop, [&] {
375+
map->free_data();
376+
pmem::obj::delete_persistent<persistent_map_type>(map);
377+
});
378+
} catch (...) {
379+
UT_ASSERT(0);
380+
}
381+
361382
pmem::obj::transaction::run(pop, [&] {
362-
pmem::obj::delete_persistent<persistent_map_type>(map);
363383
pmem::obj::delete_persistent<persistent_map_type>(map2);
364384
});
365385
}

0 commit comments

Comments
 (0)