[Boost-bugs] [Boost C++ Libraries] #6204: If we send a notify(cond.notify_one()) before waiting for the mutex (cond.wait(lock)), then while waiting, we do not get it. We lose a notification. Therefore, we must protect the notification too.

Subject: [Boost-bugs] [Boost C++ Libraries] #6204: If we send a notify(cond.notify_one()) before waiting for the mutex (cond.wait(lock)), then while waiting, we do not get it. We lose a notification. Therefore, we must protect the notification too.
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2011-12-03 12:16:45


#6204: If we send a notify(cond.notify_one()) before waiting for the mutex
(cond.wait(lock)), then while waiting, we do not get it. We lose a
notification. Therefore, we must protect the notification too.
------------------------------+---------------------------------------------
 Reporter: kikots@… | Owner: anthonyw
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: thread
  Version: Boost 1.48.0 | Severity: Problem
 Keywords: |
------------------------------+---------------------------------------------
 Hello.
 Its about boost/std condition variable.
 If we send a notify(cond.notify_one()) before waiting for the mutex
 (cond.wait(lock)), then while waiting, we

 do not get it. We lose a notification. Therefore, we must protect the
 notification too.
 Example boost:
 http://www.boost.org/doc/libs/1_48_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref
 void retrieve_data();
 void prepare_data();

 void prepare_data_for_processing()
 {
     retrieve_data();
     prepare_data();
     {
         boost::lock_guard<boost::mutex> lock(mut);
         data_ready=true;
     }
     cond.notify_one();
 }

 It is not correct. It should be like this:
 void retrieve_data();
 void prepare_data();

 void prepare_data_for_processing()
 {
     retrieve_data();
     prepare_data();
     boost::lock_guard<boost::mutex> lock(mut);
     {
         // boost::lock_guard<boost::mutex> lock(mut);
         data_ready=true;
     }
     cond.notify_one();
 }

 This is true for boost version 1.39, 1.48, and C + +11.
 Look at the code in action, for boost and C++11.
 http://liveworkspace.org/code/db3576e5bf5a5c128152762ba0f30027
 http://liveworkspace.org/code/e812540f1b5b1ac6915394c397e0c2cf

 This code show the problem:
    // unlock main thread and wait
 // lock1.unlock(); lock3.unlock(); mtx_cond0.lock(); // good
    query_done_cond.notify_one();
    std::cout << "put t1 \n";
    lock1.unlock(); lock3.unlock(); mtx_cond0.lock(); // bad


 Or it should be like this:

 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3070.html

 void thread_func()
 {
     std::unique_lock<std::mutex> lk(m);
     the_data=find_the_answer();
     data_ready=true;
     std::notify_all_at_thread_exit(cv,std::move(lk));
 } // destroy thread_locals, notify cv, unlock mutex

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/6204>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:07 UTC