Boost version 1.40. Compiler VC9.
I have found an issue where
condition_variable_any::wait does not fully unlock a recursive_mutex if its
recursion count is greater than 1. Is this deliberate? The simple code
below reproduces the issue – the program will deadlock.
bool g_endThread(false);
boost::condition_variable_any
g_whatToWaitFor;
boost::recursive_mutex
g_mutex;
void secondWorkerFunc()
{
boost::recursive_mutex::scoped_lock lock(g_mutex);
std::cout
<< "Worker
2\n";
while (g_endThread == false)
{
std::cout << "Worker
2 starting wait\n";
g_whatToWaitFor.wait(lock); // ****
Will wait for ever ****
}
}
void workerThreadFunc()
{
boost::recursive_mutex::scoped_lock lock(g_mutex);
std::cout
<< "Worker 1\n";
secondWorkerFunc();
}
int _tmain(int /*argc*/,
_TCHAR* /*argv*/[])
{
boost::thread
workerThread(workerThreadFunc);
std::cout
<< "Main thread
starting sleep\n";
boost::this_thread::sleep(boost::posix_time::seconds(1));
std::cout
<< "Main thread
finished sleep\n";
{
boost::recursive_mutex::scoped_lock lock(g_mutex);
g_endThread = true;
}
g_whatToWaitFor.notify_one();
std::cout
<< "Main thread
waiting for worker\n";
workerThread.join();
return 0;
}
This code outputs:
Main thread starting sleep
Worker 1
Worker 2
Worker 2 starting wait
Main thread finished sleep
I am aware of the adopt_lock argument to the lock
constructor, but that doesn’t work if the thread hasn’t already locked
the mutex. What I think I need is one of 2 things:
1. A wait function on conditional_variable_any that
will completely unlock and then relock a recursive_mutex. This would be
ideal.
2. A new argument to the lock constructor that has
the same behaviour as adopt_lock if the thread already has the mutex. If
the thread does not have the mutex the new constructor will locks the mutex
(same as the basic constructor with no extra argument). This would allow
me to have a class with multiple methods that can call each other and where any
method could be the first one to be called in any given thread.
Am I missing something?
Thanks,
Rob Moore