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:
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user