2
0
mirror of https://github.com/boostorg/thread.git synced 2026-02-28 05:42:10 +00:00

Thread: 6342: Adapt the one_flag and call_once to the c++11 interface

[SVN r77767]
This commit is contained in:
Vicente J. Botet Escriba
2012-04-04 20:01:11 +00:00
parent 8d9370b005
commit 59265265d9
7 changed files with 95 additions and 26 deletions

View File

@@ -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 <boost/thread/thread.hpp>
#include <boost/thread/once.hpp>
#include <cassert>
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()
{

View File

@@ -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)

View File

@@ -22,7 +22,8 @@
namespace boost
{
// template<class Callable, class ...Args> void call_once(once_flag& flag, Callable func, Args&&... args);
// template<class Callable, class ...Args> void
// call_once(once_flag& flag, Callable&& func, Args&&... args);
inline void call_once(void (*func)(),once_flag& flag)
{
call_once(flag,func);

View File

@@ -21,38 +21,40 @@
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<typename Function>
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_VERSION==3
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
namespace detail
{

View File

@@ -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 std
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<typename Function>
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 @@ namespace boost
};
#define BOOST_ONCE_INIT {0,0}
#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
namespace detail
{
@@ -71,29 +99,29 @@ namespace boost
#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<std::ptrdiff_t>(flag_address),
detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(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 @@ namespace boost
{
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,7 +143,7 @@ namespace boost
mutex_name);
}
}
template<typename Function>
void call_once(once_flag& flag,Function f)
@@ -153,7 +181,7 @@ namespace boost
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);

View File

@@ -46,7 +46,11 @@ namespace boost
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"

View File

@@ -26,7 +26,11 @@ namespace boost
{
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;