Re: [Boost-bugs] [Boost C++ Libraries] #8730: Race condition in once_block.hpp

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #8730: Race condition in once_block.hpp
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-06-25 21:07:53


#8730: Race condition in once_block.hpp
-------------------------------+------------------------------------------
  Reporter: apolukhin | Owner: andysem
      Type: Bugs | Status: new
 Milestone: To Be Determined | Component: log
   Version: Boost 1.54.0 | Severity: Problem
Resolution: | Keywords: call_once atomics thread log
-------------------------------+------------------------------------------

Comment (by apolukhin):

 Replying to [comment:3 andysem]:
> Do you have a particular use case that may show breakage with the
 current implementation of once_block? On what hardware? With references to
 the code, if possible.

 Let's take a look at `boost/log/utility/once_block.hpp`. Macro
 `BOOST_LOG_ONCE_BLOCK()` is defined as
 {{{
     BOOST_LOG_ONCE_BLOCK_INTERNAL(\
         BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_flag_),\
         BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_once_block_sentry_))
 }}}

 That block contains `BOOST_LOG_ONCE_BLOCK_INTERNAL` will unwrap to
 something like
 {{{
     static boost::log::once_block_flag flag_var = {
 boost::log::once_block_flag::uninitialized };
 }}}

 where `boost::log::once_block_flag` is a POD type.
 Note the `static` keyword usage. It means that it will be converted by
 compiler to something like this:
 {{{
 if (!is_once_block_flag_inited) { // Variable constructed with compiler
     new (flag_var)
 boost::log::once_block_flag(boost::log::once_block_flag::uninitialized);
     is_once_block_flag_inited = true;
 }
 }}}

 Now consider the situation:
 Thread no1 checks for !is_foo_inited, enters the if block and starts to
 execute the placement new. At that time thread no2 checks for
 !is_foo_inited and enters the if block... That is not good, leads to
 memory leaks and undefined behavior!

 That's only top of the iceberg. There are some more problems in
 `once_block_sentry::executed()`. What for is all the code inside
 once_block.cpp: you are using `boost::thread` but do not use
 `boost::call_once`? What is the reason?

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8730#comment:4>
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:13 UTC