ConcurrentHashMap::try_emplace returns an iterator which does not keep the corresponding value alive
- Dominant language
- C++
- Stars
- 30.5k
- Forks
- 5.9k
- PR merge metrics
- No merged PRs in 30d
Description
The documentation suggests that the iterators contain hazard points to the elements, and the elements will remain accessible while the iterator is alive, even if it is erased from the map:
https://github.com/facebook/folly/blob/main/folly/concurrency/ConcurrentHashMap.h#L44
Here is a very simple repro of the bug, in which an element is destroyed while an iterator to it is still held:
```
static std::atomic hasBeenDestroyed = false;
struct Value {
Value(bool logDestruction) : logDestruction_(logDestruction) {}
~Value() {
if (logDestruction_) {
hasBeenDestroyed = true;
}
}
bool logDestruction_;
};
folly::ConcurrentHashMapSIMD> map;
auto [it, inserted] = map.try_emplace(1, make_unique(true));
std::thread t([&]() {
auto it1 = map.find(1);
map.erase(it1);
// Add enough entries to the cache to trigger a GC of the erased
// iterators.
for (int i = 2; i < 100000; ++i) {
map.try_emplace(i, make_unique(false));
}
});
t.join();
std::cout << "Has element 1 been destroyed? " << hasBeenDestroyed << std::endl;
```
Logs:
```
Has element 1 been destroyed? 1
```
Contributor guide
Assessment
This issue has not been assessed yet.