$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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