"Nested" scoped_lock
Asked Answered
M

3

7

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

Minatory answered 23/10, 2011 at 9:47 Comment(1)
Use a boost::recursive_mutex instead of a boost::mutexFulcrum
I
12

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

Intractable answered 23/10, 2011 at 10:19 Comment(0)
B
4

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.

Bobbyebobbysocks answered 23/10, 2011 at 10:18 Comment(0)
A
0

You can use the tryLock in methodA if the try failed you should get the current threadId and continue with execution only if the thread id is the same with threadid which runs the MethodB.Otherwise if the try succeed you can continue with execution normally.

Astatine answered 23/10, 2011 at 9:57 Comment(4)
This seems like a race condition waiting to happen.Periwinkle
Normally the best answer in my opinion is the comment from BatchyX. But I really don't see any race condition here. Can you please explain me?Astatine
Sorry, with more thought you're probably right it could be made to work.Periwinkle
And how would you obtain the thread that is currently locking a boost::mutex?Irony

© 2022 - 2024 — McMap. All rights reserved.