Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::mutex::~mutex(): Assertion `!pthread_mutex_destroy(&m)' failed

Tags:

c++

mutex

boost

I got the captioned error in the mutex destructor. since the error may due to the mutex is in lock state during destruction, I create a new mutex class which is inherited from boost:mutex. it is to make sure the mutex is unlock during destruction. However, the same error still occurs. Any hits would be appreciated!

class CMutes : public boost::mutex
{
public:
    CMutes()
    {

    };

    virtual ~CMutes()
    {
        if (m_bLock)
            boost::mutex::unlock();
    };

    void lock()
    {
        if(!m_bLock)
            boost::mutex::lock();
        else
            cout << "Mutex is in lock state\n";
    };

    void unlock()
    {
        if (m_bLock)
            boost::mutex::unlock();
        else
            cout << "Mutex is in unlock state\n";
    }

    boost::mutex& getMutex()
    {
        return *this;
    }

private:

    bool m_bLock;
};

EDIT: Yes you are right. I should use RAII. However, I am in a situation. I need to lock a resource before another thread is finish processing it. something like below.

Thread A:
void getDate()
{
 m_oLock.lock();
 // access resource
}

void unlock()
{
 m_oLock.unlock();
}
Thread B:
void Process()
{
 threadA.getData();
 threadA.unlock();
}
like image 420
Michael D Avatar asked Oct 19 '11 06:10

Michael D


3 Answers

Do Not inherit from boost::mutex, the boost::mutex class does not have a virtual destructor, so it is not actually meant for Inheritance.

Possible Root Cause:
The error you are getting indicates that you are calling unlock on a mutex that was never locked. Something like:

boost::mutex m;   
m.unlock(); 

By trying to do lock and unlock, it seems you lose the track of whether the mutex as locked.This is very often the problem when you perform resource management manually. C++ allows a specific mechansim called Resource Allocation is Initilization(RAII) for safe guarding against such problems.

Suggestted Solution:
You should use RAII, rather than unlocking the mutex explicitly. You could use the boost::mutex::scoped_lock to implement RAII:

struct YourStruct
{
    void doSomething()
    {
        boost::mutex::scoped_lock l(m_mutex);
        //do something Interesting
    }
    private: 
        boost::mutex m_mutex;
};
like image 172
Alok Save Avatar answered Nov 18 '22 13:11

Alok Save


I had the same error (which is how I found this question). I solved by problem by adding a join to the relevant thread. My main process was finishing up before the thread did and the mutex was being torn down before it could be unlocked.

like image 39
tacaswell Avatar answered Nov 18 '22 15:11

tacaswell


POSIX states that the only errors returned from a pthread_mutex_destroy operation are EINVAL if the mutex is somehow invalid, or EBUSY if someone is using it (explicitly or via condition variables).

The most likely scenario is the second one.

However, I'm not seeing any changes to the m_bLock member variable in any of your code. Are you sure you don't want to change this variable in the lock and unlock calls?

If it is in use, you'll just have to wait until whoever is using it is willing to release it. Any other option is unlikely to be good for you :-)

like image 35
paxdiablo Avatar answered Nov 18 '22 14:11

paxdiablo