Index: boost/thread/pthread/once.hpp =================================================================== --- boost/thread/pthread/once.hpp (revision 77687) +++ boost/thread/pthread/once.hpp (working copy) @@ -21,39 +21,41 @@ namespace boost { -#if BOOST_THREAD_VERSION==3 +#define BOOST_ONCE_INITIAL_FLAG_VALUE 0 +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + struct once_flag { BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT - : epoch(0) + : epoch(BOOST_ONCE_INITIAL_FLAG_VALUE) {} #ifndef BOOST_NO_DELETED_FUNCTIONS once_flag(const once_flag&) = delete; once_flag& operator=(const once_flag&) = delete; #else // BOOST_NO_DELETED_FUNCTIONS private: - once_flag(const once_flag&); - once_flag& operator=(const once_flag&); + once_flag(once_flag&); + once_flag& operator=(once_flag&); public: #endif // BOOST_NO_DELETED_FUNCTIONS private: boost::uintmax_t epoch; - + template + friend + void call_once(once_flag& flag,Function f); }; -#else // BOOST_THREAD_VERSION==3 +#else // BOOST_THREAD_PROVIDES_ONCE_CXX11 struct once_flag { boost::uintmax_t epoch; }; -#define BOOST_ONCE_INITIAL_FLAG_VALUE 0 #define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE} +#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11 -#endif // BOOST_THREAD_VERSION==3 - namespace detail { BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch(); Index: boost/thread/detail/config.hpp =================================================================== --- boost/thread/detail/config.hpp (revision 77718) +++ boost/thread/detail/config.hpp (working copy) @@ -19,6 +19,7 @@ // This compiler doesn't support Boost.Move #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) #define BOOST_THREAD_DONT_USE_MOVE +#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS #endif // Default version is 1 @@ -59,26 +60,48 @@ #endif #if BOOST_THREAD_VERSION==1 +#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY #define BOOST_THREAD_PROMISE_LAZY #endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 +#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V2_0_0 +#endif +#endif #if BOOST_THREAD_VERSION==2 +#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 +#define BOOST_THREAD_PROVIDES_ONCE_CXX11 +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE #define BOOST_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE #define BOOST_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_USES_FUTURE #define BOOST_THREAD_USES_FUTURE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS #define BOOST_THREAD_FUTURE_USES_ALLOCATORS +#endif +#if ! defined BOOST_THREAD_SHARED_MUTEX_DONT_PROVIDE_UPWARDS_CONVERSIONS #define BOOST_THREAD_SHARED_MUTEX_PROVIDES_UPWARDS_CONVERSION +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION #define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_GENERIC #define BOOST_THREAD_SHARED_MUTEX_GENERIC -#if ! defined BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 +#endif +#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V2_0_0 #define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 #endif #endif -// BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 defined by default up to Boost 1.52 +// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V2_0_0 defined by default up to Boost 1.52 // BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 defined by default up to Boost 1.55 #if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 -#define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V2_0_0 +#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V2_0_0 #endif #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) Index: boost/thread/win32/once.hpp =================================================================== --- boost/thread/win32/once.hpp (revision 77687) +++ boost/thread/win32/once.hpp (working copy) @@ -3,7 +3,7 @@ // once.hpp // -// (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2005-7 Anthony Williams // (C) Copyright 2005 John Maddock // // Distributed under the Boost Software License, Version 1.0. (See @@ -30,6 +30,33 @@ namespace boost { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + + struct once_flag + { + BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT + : status(0), count(0) + {} +#ifndef BOOST_NO_DELETED_FUNCTIONS + once_flag(const once_flag&) = delete; + once_flag& operator=(const once_flag&) = delete; +#else // BOOST_NO_DELETED_FUNCTIONS + private: + once_flag(once_flag&); + once_flag& operator=(once_flag&); + public: +#endif // BOOST_NO_DELETED_FUNCTIONS + private: + long status; + long count; + template + friend + void call_once(once_flag& flag,Function f); + }; + +#define BOOST_ONCE_INIT once_flag() +#else // BOOST_THREAD_PROVIDES_ONCE_CXX11 + struct once_flag { long status; @@ -37,6 +64,7 @@ }; #define BOOST_ONCE_INIT {0,0} +#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11 namespace detail { @@ -71,29 +99,29 @@ #else static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; #endif - BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) == + BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) == (sizeof(once_char_type)*(once_mutex_name_fixed_length+1))); - + std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); - detail::int_to_string(reinterpret_cast(flag_address), + detail::int_to_string(reinterpret_cast(flag_address), mutex_name + once_mutex_name_fixed_length); - detail::int_to_string(win32::GetCurrentProcessId(), + detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2); } - + inline void* open_once_event(once_char_type* mutex_name,void* flag_address) { if(!*mutex_name) { name_once_mutex(mutex_name,flag_address); } - -#ifdef BOOST_NO_ANSI_APIS + +#ifdef BOOST_NO_ANSI_APIS return ::boost::detail::win32::OpenEventW( #else return ::boost::detail::win32::OpenEventA( #endif - ::boost::detail::win32::synchronize | + ::boost::detail::win32::synchronize | ::boost::detail::win32::event_modify_state, false, mutex_name); @@ -105,7 +133,7 @@ { name_once_mutex(mutex_name,flag_address); } -#ifdef BOOST_NO_ANSI_APIS +#ifdef BOOST_NO_ANSI_APIS return ::boost::detail::win32::CreateEventW( #else return ::boost::detail::win32::CreateEventA( @@ -115,8 +143,8 @@ mutex_name); } } - + template void call_once(once_flag& flag,Function f) { @@ -153,7 +181,7 @@ counted=true; } BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value); - if(!event_handle && + if(!event_handle && (::boost::detail::interlocked_read_acquire(&flag.count)>1)) { event_handle=detail::create_once_event(mutex_name,&flag); Index: boost/thread/once.hpp =================================================================== --- boost/thread/once.hpp (revision 77687) +++ boost/thread/once.hpp (working copy) @@ -22,7 +22,8 @@ namespace boost { - // template void call_once(once_flag& flag, Callable func, Args&&... args); + // template void + // call_once(once_flag& flag, Callable&& func, Args&&... args); inline void call_once(void (*func)(),once_flag& flag) { call_once(flag,func); Index: libs/thread/example/once.cpp =================================================================== --- libs/thread/example/once.cpp (revision 77687) +++ libs/thread/example/once.cpp (working copy) @@ -1,15 +1,22 @@ // Copyright (C) 2001-2003 // William E. Kempf // -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// Distributed under 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) +#define BOOST_THREAD_PROVIDES_ONCE_CXX11 + #include #include #include int value=0; +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 +boost::once_flag once; +#else boost::once_flag once = BOOST_ONCE_INIT; +boost::once_flag once2 = once; +#endif void init() { Index: libs/thread/src/win32/thread.cpp =================================================================== --- libs/thread/src/win32/thread.cpp (revision 77718) +++ libs/thread/src/win32/thread.cpp (working copy) @@ -26,7 +26,11 @@ { namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; +#endif #if defined(UNDER_CE) // Windows CE does not define the TLS_OUT_OF_INDEXES constant. DWORD tls_out_of_index=0xFFFFFFFF; Index: libs/thread/src/pthread/thread.cpp =================================================================== --- libs/thread/src/pthread/thread.cpp (revision 77718) +++ libs/thread/src/pthread/thread.cpp (working copy) @@ -46,7 +46,11 @@ namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; +#endif pthread_key_t current_thread_tls_key; extern "C"