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