MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
call_once.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_ASYNC_CALL_ONCE_HPP__
2#define MSTL_CORE_ASYNC_CALL_ONCE_HPP__
3
10
14
20
30class once_flag {
31private:
32 atomic<uint32_t> state_;
33
34 template <typename Callable, typename... Args>
35 friend void call_once(once_flag& flag, Callable&& func, Args&&... args);
36
37public:
43 once_flag() noexcept : state_(0) {}
44 once_flag(const once_flag&) = delete;
45 once_flag& operator =(const once_flag&) = delete;
46 once_flag(once_flag&&) = delete;
47 once_flag& operator =(once_flag&&) = delete;
48};
49
64template <typename Callable, typename... Args>
65void call_once(once_flag& flag, Callable&& func, Args&&... args) {
66 if (flag.state_.load(memory_order_acquire) == 2) {
67 return;
68 }
69
70 uint32_t spin_count = 0;
71 while (true) {
72 const uint32_t state = flag.state_.load(memory_order_acquire);
73 if (state == 2) return;
74
75 if (state == 0) {
76 uint32_t expected = 0;
77 if (flag.state_.compare_exchange_strong(
78 expected, 1,
81 try {
82 _MSTL invoke<Callable, Args...>(
84 _MSTL forward<Args>(args)...
85 );
86 flag.state_.store(2, memory_order_release);
87 return;
88 } catch (...) {
89 flag.state_.store(0, memory_order_release);
90 throw;
91 }
92 }
93 spin_count = 0;
94 continue;
95 }
96
97 if (spin_count < 10) {
98 for (uint32_t i = 0; i < (1u << spin_count); ++i) {
99 this_thread::relax();
100 }
101 ++spin_count;
102 } else {
103 this_thread::yield();
104 }
105 }
106}
107 // CallOnce
109
111#endif // MSTL_CORE_ASYNC_CALL_ONCE_HPP__
MSTL原子类型完整实现
一次性调用标志类
once_flag() noexcept
构造函数
friend void call_once(once_flag &flag, Callable &&func, Args &&... args)
单次调用函数
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
void call_once(once_flag &flag, Callable &&func, Args &&... args)
单次调用函数
unsigned int uint32_t
32位无符号整数类型
MSTL_CONSTEXPR14 _INNER __invoke_result_aux< Callable, Args... >::type invoke(Callable &&f, Args &&... args) noexcept(is_nothrow_invocable< Callable, Args... >::value)
统一调用接口
MSTL_INLINE17 constexpr auto memory_order_release
释放内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_acq_rel
获取-释放内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_relaxed
宽松内存顺序常量
MSTL_INLINE17 constexpr auto memory_order_acquire
获取内存顺序常量
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
MSTL统一调用接口
通用原子类型模板
T load(const memory_order mo=memory_order_seq_cst) const noexcept
原子加载操作
bool compare_exchange_strong(T &expected, T desired, const memory_order success, const memory_order failure) noexcept
强比较交换操作
void store(T value, const memory_order mo=memory_order_seq_cst) noexcept
原子存储操作