Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Nested" scoped_lock

My shortened, simplified class looks as follows:

class A
{
    public:
    // ...
    methodA();
    methodB();

    protected:
    mutable boost::mutex m_mutex;
    sometype*  m_myVar;
}

A::methodA( int someParam )
{
    boost::mutex::scoped_lock myLock(m_mutex);
    m_myVar->doSomethingElse();
}

A::methodB( int someParam )
{
    boost::mutex::scoped_lock myLock(m_mutex);
    m_myVar->doSomething();
    this->methodA(someParam);
}

I would like to synchronize access on m_myVar. When calling A::methodB(), the thread runs into the lock with the same mutex twice and obviously blocks on the first line of A::methodA()

Is there any way to make scoped_lock not blocking the same thread when passing again?

Sure, I simply could call m_mutex.unlock(). But this would free the other threads waiting on the lock as well - which is absolutely not what I want.

Any idea?

Best regards Tobias

like image 359
Atmocreations Avatar asked Oct 23 '11 09:10

Atmocreations


2 Answers

This is what boost::recursive_mutex for it allows to obtain the lock by the same thread without deadlocking several times. Use it instead of boost::mutex

like image 92
Artyom Avatar answered Oct 02 '22 09:10

Artyom


There are different things that you can do here. You can use a recursive mutex that can be acquired multiple times within the same thread, or you can split methodA into a private method with the implementation and no locks and a public method that locks and then calls the private implementation. Then methodB would call the internal implementation while holding the lock. Because the method is private you have control over all the uses and you can ensure that the implementation method is only called while holding the lock.

like image 37
David Rodríguez - dribeas Avatar answered Oct 02 '22 09:10

David Rodríguez - dribeas