[Boost-bugs] [Boost C++ Libraries] #10478: Data race in boost/thread/future.hpp

Subject: [Boost-bugs] [Boost C++ Libraries] #10478: Data race in boost/thread/future.hpp
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-09-07 15:02:50


#10478: Data race in boost/thread/future.hpp
-------------------------------------------------+----------------------
 Reporter: Alexander Karzhenkov <karzhenkov@…> | Owner: anthonyw
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: thread
  Version: Boost 1.56.0 | Severity: Problem
 Keywords: future, shared state |
-------------------------------------------------+----------------------
 Non-static member function "mark_finished_with_result" of class template
 "future_async_shared_state" (inherited from
 "future_async_shared_state_base") is called from static member function
 "run" concurrently with constructor. Newly created thread uses the object
 being constructed by original thread. This is data race condition and
 results in undefined behavior [1.10.21, std-2011]. Moreover, the call of
 "mark_finished_with_result" may be completed even before constructor
 execution begins, which also leads to undefined behavior [12.7.1,
 std-2011].[[BR]]

 Program below illustrates the problem:[[BR]]

 {{{
 #define BOOST_THREAD_VERSION 4

 #include <iostream>
 #include <boost/thread.hpp>

 void func(int num)
 {
         //boost::this_thread::yield();
         if (num == 0) return;
         std::cout << 'A' << num << std::endl;
         async(boost::launch::async, func, num - 1);
         std::cout << 'B' << num << std::endl;
 }

 int main()
 {
         func(3);
 }
 }}}
 Under QNX 6.5.0 SP1 with gcc 4.8.3 it gives the following:[[BR]]

 {{{
 A3
 A2
 A1
 In function notify_all --
 d:/boost_1_56_0/boost/thread/pthread/condition_variable.hpp:142
 !pthread_cond_broadcast(&cond) -- assertion failed
 }}}
 After uncommenting the call of yield we get what’s expected:[[BR]]

 {{{
 A3
 A2
 A1
 B1
 B2
 B3
 }}}
 Possible solution for C++11 is to create new thread in the body of
 "future_async_shared_state" constructor instead of using member
 initializer syntax for base:
 {{{
 --- future.hpp Mon Aug 4 00:58:54 2014
 +++ future-fixed.hpp Thu Sep 4 13:00:54 2014
 @@ -882,5 +882,5 @@
          public:
 - explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
 :
 - base_type(thread(&future_async_shared_state::run, this,
 boost::forward<Fp>(f)))
 + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
            {
 + thr_ = thread(&future_async_shared_state::run, this,
 boost::forward<Fp>(f));
            }
 @@ -912,5 +912,5 @@
          public:
 - explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
 :
 - base_type(thread(&future_async_shared_state::run, this,
 boost::forward<Fp>(f)))
 + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f)
            {
 + thr_ = thread(&future_async_shared_state::run, this,
 boost::forward<Fp>(f));
            }
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/10478>
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:16 UTC