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

Micromill Electronics Limited trading as Cobham Surveillance, Waterberry, Drive, Waterlooville, Hampshire, PO7 7XX. www.cobham.com

Registered Office: Brook Road, Wimborne, Dorset, BH21 2BJ, England
Registered Number: 1456922 
VAT GB339059146

THIS EMAIL AND ANY ATTACHED FILES ARE CONFIDENTIAL AND MAY BE LEGALLY PRIVILEGED 
If you are not the addressee, any disclosure, reproduction, copying, distribution, or other dissemination or use of this communication is strictly prohibited. 
If you have received this transmission in error please notify the sender immediately and then delete this e-mail.
Please consider the environment before printing this email.