Current situation
Right now I have a method like
Data lookupData(Key id)
{
std::lock_guard<std::mutex> lock(m_mutex);
auto it = m_dict.find(id);
if(it == m_dict.end())
{
return Data::Empty;
}
else
{
return it->second;
}
}
Problem
However I now have a situation where, if the result is not found, I want the calling code to be able to do some more stuff while keeping the lock held.
One straightforward solution is to take the mutex lock outside of this method and require calling code to lock the mutex instead, maybe by documenting this in a doc comment or something. However it feels like it would be better to be able to enforce this, by passing some kind of receipt to the method proving that we actually hold a lock on the mutex in question.
Potential solution(s)
So I'm considering doing something like
Data lookupData(Key id, const std::unique_lock<std::mutex> & lock)
{
if(lock.mutex() != m_mutex) { /* throw * }
if(! lock.owns_lock()) { /* throw */ }
auto it = m_dict.find(id);
if(it == m_dict.end())
{
return Data::Empty;
}
else
{
return it->second;
}
}
Alternatively instead of
if(! lock.owns_lock()) { /* throw */ }
I could do something like
if(! lock.owns_lock()) { lock.lock(); }
(obviously removing the const
qualifier from the lock
parameter) so that the method can be called either with or without the lock being held.
Questions
- Is the idea of a method requiring proof that a mutex is locked a good one, or if not, why not?
- Assuming the answer to the above is "yes," are the above approaches recommended? If not, why not, and what would be recommended instead?
- Are there names for the type of problem and/or the general solutions described above that I can Google to read more about this sort of thing?