c++boostmutex

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


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();
}

Solution

  • 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;
    };