Boost logo

Boost :

From: Bronek Kozicki (brok_at_[hidden])
Date: 2006-10-06 04:54:56


Roland Schwarz wrote:
> Initialisation of local static objects is
> potentially not thread-safe.

> From this it follows that the constructor call
> poses a race condition, when a second thread is
> making a call to foo, while the first still is
> in the constructor of bar.

indeed.

> In a templated function
>
> template<typename DerivedT, typename ContextT, typename ScannerT>
> inline typename DerivedT::template definition<ScannerT> &
> get_definition(grammar<DerivedT, ContextT> const* self)
> {
> ...
> typedef grammar<DerivedT, ContextT> self_t;
> typedef impl::grammar_helper<self_t, DerivedT, ScannerT>
> helper_t;
> typedef typename helper_t::helper_weak_ptr_t ptr_t;
>
> static boost::thread_specific_ptr<ptr_t> tld_helper;
> if (!tld_helper.get())
> tld_helper.reset(new ptr_t);
> ptr_t &helper = *tld_helper;
> ...
> }
>
> a local static thread_specific pointer is beeing
> used for thread safety. To make this really thread
> safe the pointer normally should be declared at
> global (namespace) scope. This is not possible in
> this case, since the pointer type is parameterized
> on a template parameter.

What's wrong with simple:

template <typename T> struct wrapper
{
   static T data;
};

template <typename T>
T wrapper<T>::data;

template<C> void foo(C arg)
{
   bar<C>& abar = wrapper<bar<C> >::data;
}

... which will trigger static (thread-safe) initialization.

B.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk