Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should Mutex's lock/unlock functions be "const"?

I am maintaining a library that contains a Mutex class. I cannot decide if the lock() and unlock() functions exposed by this class should be const or not. I looked for similar code on the Web, and could find both implementations.

First implementation, lock() and unlock() are not const. It means someone who uses the Mutex class in a const function should put extra effort to call Mutex's functions:

class Mutex
{
public:
   void lock();
   void unlock();
};

class Foo
{
public:
   void getBar(Bar& bar) const
   {
      m_mutex.lock();
      bar = m_bar;
      m_mutex.unlock();
   }

private:
   // Mutable, responsability of the user (or we could use a const_cast when needed)
   mutable Mutex m_mutex;
   Bar   m_bar;
};

Second implementation, lock() and unlock() are const, even if that does not sound very natural (as we modify the Mutex instance), but the user does not have to bother when calling those functions in one of his const functions:

class Mutex
{
public:
   void lock() const;
   void unlock() const;
};

class Foo
{
public:
   void getBar(Bar& bar) const
   {
      m_mutex.lock();
      bar = m_bar;
      m_mutex.unlock();
   }

private:
   Mutex m_mutex;
   Bar   m_bar;
};

What solution do you prefer ? I hope your opinions will help me to take a decision.

like image 661
user431610 Avatar asked Aug 26 '10 08:08

user431610


1 Answers

mutable was made for this kind of stuff. Namely, mutable applies to things that don't take part in the logical constness of an object. (If one value is "logically constant", it means the 'primary' values are constant; the value of the object, from the outside, cannot change.)

The value of your object is independent from the state of the mutex (it's only an implementation detail to provide consistency, and it's state is not known outside the class), which is a good sign your mutex should be mutable.


Note, you should not go the const_cast route. This leads to undefined behavior if you did:

const Foo f;

Bar b;
f.getBar(b); // takes const off of mutex, modifies (bang you're dead)
like image 176
GManNickG Avatar answered Oct 14 '22 07:10

GManNickG