[Boost-bugs] [Boost C++ Libraries] #2939: Possible thread-safety issue with Boost Function

Subject: [Boost-bugs] [Boost C++ Libraries] #2939: Possible thread-safety issue with Boost Function
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-04-12 04:56:23


#2939: Possible thread-safety issue with Boost Function
---------------------------------------+------------------------------------
 Reporter: boost-trac_at_[hidden] | Owner: dgregor
     Type: Bugs | Status: new
Milestone: Boost 1.39.0 | Component: function
  Version: Boost 1.38.0 | Severity: Problem
 Keywords: |
---------------------------------------+------------------------------------
 Hi, I realize this might slip through the mailing lists so I am posting it
 here:

 http://article.gmane.org/gmane.comp.lib.boost.devel/188442

 I was just looking through the Boost Function source and noticed the
 following in assign_to:
 {{{
       // Note: it is extremely important that this initialization use
       // static initialization. Otherwise, we will have a race
       // condition here in multi-threaded code. See
       // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
       static vtable_type stored_vtable =
         { { &manager_type::manage }, &invoker_type::invoke };
 }}}

 However, my copy of the C++ standard seems to say this regarding local
 statics in section 6.7:

 The zero-initialization (8.5) of all local objects with static storage
 duration (3.7.1) is performed before any other initialization takes place.
 A local object of POD type (3.9) with static storage duration initialized
 with constant-expressions is initialized before its block is first
 entered. An implementation is permitted to perform early initialization of
 other local objects with static storage duration under the same conditions
 that an implementation is permitted to statically initialize an object
 with static storage duration in namespace scope.

 I read this to mean that an implementation may decide to initialize
 stored_vtable statically or the first time the block is entered. So I
 think that this means we cannot rely on static initialization behaviour.

 If you agree, then a simple fix for this might just be:

 {{{
 template<typename VTable, typename Invoker, typename Manager>
 struct vtable_static_constructor
 {
   static VTable vtable;
 };

 template<...>
 VTable vtable_static_constructor<V,I,M>::vtable =
   { {&Manager::manage, &Manager::invoke } };

 assign_to()
 {
 ...
   vtable_type & stored_vtable =
 vtable_static_constructor<vtable_type,invoker_type,manager_type>::vtable;
 ...
 }
 }}}

 If not, could you please point me to where in the standard this is
 guaranteed to be statically initialized? It would help me decide whether
 or not to fix some other code that has a similar pattern, if nothing else.

 Thanks in advance!

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