Returning a reference from under a lock: Idiomatic or just too darn clever?

256 views Asked by At

Suppose you have a data structure where values are kept in nodes, e.g., the standard maps or lists, and that structure has a lock to guard it. Suppose also the value types (mapped_type for the maps) is complex enough that each one has its own lock.

So the basic operation is to grab the map's lock, get the (reference to the) value, and unlock the map's lock. Now you can lock the value's lock and party on it as long as you want.

The problem - as I see it - is you can't assign a reference - only initialize it. So I propose the following sort of code, given the some map type M with instance m (and it's mutex m_mutex):

const MappedType& mt = [this, key]() -> const MappedType& {
  std::lock_guard _{m_mutex};
  return m[key];
}();

That would be the case where you can use at to add an element. If you didn't want to do that you could:

const MappedType& mt = [this, key]() -> const MappedType& {
  std::lock_guard _{m_mutex};
  M::const_iterator it = m.find(key);
  if (m.cend() != it)
    return it->second;
  else
    return M::default_m;   // some static M to indicate 'missing', or maybe you throw
}();

Good idea or too clever to pass a code review? What would the idiomatic way to do this in modern C++ be?

0

There are 0 answers