Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Query std::mutex for lock state

I have a situation where I'd like to do something like that shown below, but there doesn't seem to be a way of querying the mutex without changing its state. I don't want the someFunctionCalledRepeatedlyFromAnotherThread() to hang around waiting for the mutex to free up if it is locked. It must return immediately after performing some alternative action. I'm guessing this omission is there for safety, as the lock may free up in the time between querying it and the function returning. In my case, bad stuff will not happen if the lock is freed while doSomeAlternativeAction() is happening. The fact I'm in this situation probably means I'm doing something wrong, so how should I change my design?

class MyClass 
{
    std::mutex initMutex;
public:
    void someInitializationFunction()
    {
        std::lock_guard<std::mutex> lock(initMutex);
        // Do some work
    }

    void someFunctionCalledRepeatedlyFromAnotherThread()
    {
        if (initMutex.isLocked()) 
        {
            doSomeAlternativeAction();
            return;
        }
        // otherwise . . .
        std::lock_guard<std::mutex> lock(initMutex);
        // carry on with work as usual
    }
}
like image 922
learnvst Avatar asked Apr 15 '14 09:04

learnvst


1 Answers

Asking mutex for its state is useless: it may be unlocked now, but by the time you get around to lock it, it may be locked. So it does not have such method.

It does, however, have a method try_lock() which locks it if it is not locked and returns true if it acquired the lock and false otherwise. And std::unique_lock (the more advanced version of std::lock_guard) has option to call it.

So you can do:

void someFunctionCalledRepeatedlyFromAnotherThread()
{
    std::unique_lock<std::mutex> lock(initMutex, std::try_to_lock);
    if(!lock.owns_lock())
    {
        doSomeAlternativeAction();
        return;
    }
    // otherwise ... go ahead, you have the lock
}
like image 106
Jan Hudec Avatar answered Oct 17 '22 07:10

Jan Hudec