I am currently using Facebook's concurrent hash map and I am wondering if something like this would be possible:
folly::ConcurrentHashMap<std::string, some_class> m;
// add some elements
const auto it = m.find("a");
// during this time, another thread removes the "a" element
if (it != m.end())
it->second.something(); // it is now an invalid iterator
After reading through the source of the hash map, I came across this:
Iterators hold hazard pointers to the returned elements. Elements can only be accessed while Iterators are still valid!
This is pretty unsettling and it feels like using any returned iterators are unsafe, is this so?
The returned iterators are safe to use; however, the iterator object must be alive for the dereferenced value to be safe to access.
The 'hazard pointer' keeps the referenced value alive until the iterator is destructed.
operator[]
and at()
return the actual value for the given key, and so can't return a proxy object containing the hazard pointer. To ensure that they never return a reference to a dead object they instead return a copy of the value.
Whether you use iterators, or operator[]
/at()
, you will be operating on the value for the key at the time that you accessed the data, rather than the latest value for the given key.