Boost logo

Boost-Commit :

From: joel_at_[hidden]
Date: 2007-11-04 20:13:12


Author: djowel
Date: 2007-11-04 20:13:11 EST (Sun, 04 Nov 2007)
New Revision: 40765
URL: http://svn.boost.org/trac/boost/changeset/40765

Log:
Fixed Ticket #1328 (http://svn.boost.org/trac/boost/ticket/1328)
Added:
   trunk/boost/spirit/core/non_terminal/impl/static.hpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/core/non_terminal/impl/grammar.ipp | 17 ++++++++++++++++-
   1 files changed, 16 insertions(+), 1 deletions(-)

Modified: trunk/boost/spirit/core/non_terminal/impl/grammar.ipp
==============================================================================
--- trunk/boost/spirit/core/non_terminal/impl/grammar.ipp (original)
+++ trunk/boost/spirit/core/non_terminal/impl/grammar.ipp 2007-11-04 20:13:11 EST (Sun, 04 Nov 2007)
@@ -20,6 +20,7 @@
 #endif
 
 #ifdef BOOST_SPIRIT_THREADSAFE
+#include <boost/spirit/core/non_terminal/impl/static.hpp>
 #include <boost/thread/tss.hpp>
 #include <boost/thread/mutex.hpp>
 #endif
@@ -207,6 +208,17 @@
 
 #endif /* defined(BOOST_SPIRIT_SINGLE_GRAMMAR_INSTANCE) */
 
+#ifdef BOOST_SPIRIT_THREADSAFE
+ class get_definition_static_data_tag
+ {
+ template<typename DerivedT, typename ContextT, typename ScannerT>
+ friend typename DerivedT::template definition<ScannerT> &
+ get_definition(grammar<DerivedT, ContextT> const* self);
+
+ get_definition_static_data_tag() {}
+ };
+#endif
+
     template<typename DerivedT, typename ContextT, typename ScannerT>
     inline typename DerivedT::template definition<ScannerT> &
     get_definition(grammar<DerivedT, ContextT> const* self)
@@ -222,7 +234,10 @@
         typedef typename helper_t::helper_weak_ptr_t ptr_t;
 
 # ifdef BOOST_SPIRIT_THREADSAFE
- static boost::thread_specific_ptr<ptr_t> tld_helper;
+ boost::thread_specific_ptr<ptr_t> & tld_helper
+ = static_<boost::thread_specific_ptr<ptr_t>,
+ get_definition_static_data_tag>(get_definition_static_data_tag());
+
         if (!tld_helper.get())
             tld_helper.reset(new ptr_t);
         ptr_t &helper = *tld_helper;

Added: trunk/boost/spirit/core/non_terminal/impl/static.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/spirit/core/non_terminal/impl/static.hpp 2007-11-04 20:13:11 EST (Sun, 04 Nov 2007)
@@ -0,0 +1,112 @@
+/*=============================================================================
+ Copyright (c) 2006 João Abecasis
+ http://spirit.sourceforge.net/
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+#if !defined(BOOST_SPIRIT_STATIC_HPP)
+#define BOOST_SPIRIT_STATIC_HPP
+
+#include <boost/noncopyable.hpp>
+#include <boost/call_traits.hpp>
+#include <boost/aligned_storage.hpp>
+
+#include <boost/type_traits/add_pointer.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+#include <boost/thread/once.hpp>
+
+#include <memory> // for placement new
+
+namespace boost { namespace spirit
+{
+
+ //
+ // Provides thread-safe initialization of a single static instance of T.
+ //
+ // This instance is guaranteed to be constructed on static storage in a
+ // thread-safe manner, on the first call to the constructor of static_.
+ //
+ // Requirements:
+ // T is default constructible
+ // (There's an alternate implementation that relaxes this
+ // requirement -- João Abecasis)
+ // T::T() MUST not throw!
+ // this is a requirement of boost::call_once.
+ //
+ template <class T, class Tag>
+ struct static_
+ : boost::noncopyable
+ {
+ typedef T value_type;
+ typedef typename boost::call_traits<T>::reference reference;
+ typedef typename boost::call_traits<T>::const_reference const_reference;
+
+ static_(Tag = Tag())
+ {
+ struct destructor
+ {
+ ~destructor()
+ {
+ static_::get_address()->~value_type();
+ }
+ };
+
+ struct default_ctor
+ {
+ static void construct()
+ {
+ ::new (static_::get_address()) value_type();
+ static destructor d;
+ }
+ };
+
+ boost::call_once(&default_ctor::construct, constructed_);
+ }
+
+ operator reference()
+ {
+ return this->get();
+ }
+
+ operator const_reference() const
+ {
+ return this->get();
+ }
+
+ reference get()
+ {
+ return *this->get_address();
+ }
+
+ const_reference get() const
+ {
+ return *this->get_address();
+ }
+
+ private:
+ typedef typename boost::add_pointer<value_type>::type pointer;
+
+ static pointer get_address()
+ {
+ return static_cast<pointer>(data_.address());
+ }
+
+ typedef boost::aligned_storage<sizeof(value_type),
+ boost::alignment_of<value_type>::value> storage_type;
+
+ static storage_type data_;
+ static once_flag constructed_;
+ };
+
+ template <class T, class Tag>
+ typename static_<T, Tag>::storage_type static_<T, Tag>::data_;
+
+ template <class T, class Tag>
+ once_flag static_<T, Tag>::constructed_ = BOOST_ONCE_INIT;
+
+}} // namespace boost::spirit
+
+#endif // include guard


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk