Boost C++ Libraries: Ticket #10478: Data race in boost/thread/future.hpp https://svn.boost.org/trac10/ticket/10478 <p> 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 /> </p> <p> Program below illustrates the problem:<br /> </p> <pre class="wiki">#define BOOST_THREAD_VERSION 4 #include &lt;iostream&gt; #include &lt;boost/thread.hpp&gt; void func(int num) { //boost::this_thread::yield(); if (num == 0) return; std::cout &lt;&lt; 'A' &lt;&lt; num &lt;&lt; std::endl; async(boost::launch::async, func, num - 1); std::cout &lt;&lt; 'B' &lt;&lt; num &lt;&lt; std::endl; } int main() { func(3); } </pre><p> Under QNX 6.5.0 SP1 with gcc 4.8.3 it gives the following:<br /> </p> <pre class="wiki">A3 A2 A1 In function notify_all -- d:/boost_1_56_0/boost/thread/pthread/condition_variable.hpp:142 !pthread_cond_broadcast(&amp;cond) -- assertion failed </pre><p> After uncommenting the call of yield we get what’s expected:<br /> </p> <pre class="wiki">A3 A2 A1 B1 B2 B3 </pre><p> 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: </p> <pre class="wiki">--- 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(&amp;future_async_shared_state::run, this, boost::forward&lt;Fp&gt;(f))) + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) { + thr_ = thread(&amp;future_async_shared_state::run, this, boost::forward&lt;Fp&gt;(f)); } @@ -912,5 +912,5 @@ public: - explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) : - base_type(thread(&amp;future_async_shared_state::run, this, boost::forward&lt;Fp&gt;(f))) + explicit future_async_shared_state(BOOST_THREAD_FWD_REF(Fp) f) { + thr_ = thread(&amp;future_async_shared_state::run, this, boost::forward&lt;Fp&gt;(f)); } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10478 Trac 1.4.3 viboes Wed, 10 Sep 2014 05:19:19 GMT owner, status changed https://svn.boost.org/trac10/ticket/10478#comment:1 https://svn.boost.org/trac10/ticket/10478#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> Thanks for catching this data race condition :) </p> <p> Have you checked if your patch fixes the issue? </p> Ticket Alexander Karzhenkov <karzhenkov@…> Wed, 10 Sep 2014 05:58:40 GMT <link>https://svn.boost.org/trac10/ticket/10478#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10478#comment:2</guid> <description> <p> Yes, after applying the patch sample program runs normally with and without "yield". Maybe it's also reasonable to remove constructor of "future_async_shared_state_base" taking "thread" as parameter. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 10 Sep 2014 11:47:14 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/10478#comment:3 https://svn.boost.org/trac10/ticket/10478#comment:3 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.57.0</span> </li> </ul> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/11e4c950acc8f86b7cf404c4df4e3d3d50d4e55e"><span class="icon">​</span>https://github.com/boostorg/thread/commit/11e4c950acc8f86b7cf404c4df4e3d3d50d4e55e</a> </p> Ticket viboes Tue, 16 Sep 2014 06:03:54 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/10478#comment:4 https://svn.boost.org/trac10/ticket/10478#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket