facebook / facebook/folly

ConcurrentHashMap::try_emplace returns an iterator which does not keep the corresponding value alive

Open
#1,911 2 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.