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();
}
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;
};
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.
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 :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With