Sanich
Sanich

Reputation: 1835

Using boost::mutex::scoped_lock inside const function

This code won't compile:

    class MyClass
    {
        boost::mutex _mutex; 

        void foo() const
        {
          boost::mutex::scoped_lock lock(_mutex);
         //critical section
        }
    }

But defining the function as non const will work fine. Please, can someone explain why? Thanks!

Upvotes: 3

Views: 2196

Answers (5)

shaks
shaks

Reputation: 11

Please can you explain why it didn't work. Is locking the _mutex is 'modifing' it?

Precisely, the _mutex object will change it's internal state from say "unlocked" to "locked" state. So, you need the mutable keyword fora const-function to preserve logical constness of the function while allowing the mutex to be modifiable.

Upvotes: 0

JBL
JBL

Reputation: 12907

You can't lock a mutex inside a const-member function because this actually modifies the internal state of the mutex (lock is not itself a const function).

If you want to keep the function const, you'll have to declare the mutex as mutable which is a cv-qualifier that allows const functions to modify it, i.e.

//can now be locked (i.e. modified) by a const function
mutable boost::mutex _mutex;

Using mutable relax the const constraints on the member variable which is declared with this qualifier, that's a way to get around constness, so be careful not to abuse this. In this case, it seems reasonable because a mutex is an internal tool of your class, and does not participate in "logical constness" (as opposed to "bitwise constness").

Upvotes: 8

Jason R
Jason R

Reputation: 11696

The problem occurs because boost::mutex::lock(), which is called by the constructor of boost::mutex::scoped_lock, is not a const member function. Since the mutex is a member of MyClass, that means that MyClass::_mutex::lock() cannot be called from a non-const member function of MyClass.

The solution is to declare the mutex as a mutable member. This indicates to the compiler that _mutex may be modified, even in a const member function:

class MyClass
{
    mutable boost::mutex _mutex; 

    void foo() const
    {
      boost::mutex::scoped_lock lock(_mutex);
     //critical section
    }
}

Upvotes: 1

Bas in het Veld
Bas in het Veld

Reputation: 1312

Raistmaj is right.

The reason is that a constant method guarantees it does not change its class instance. By declaring the mutex mutable, you make an exception for that variable.

Upvotes: 1

Jose Palma
Jose Palma

Reputation: 756

This code should compile

class MyClass
{
    mutable boost::mutex _mutex; 
    void foo() const
    {
       boost::mutex::scoped_lock lock(_mutex);
       //critical section
    }
}

Upvotes: 3

Related Questions