diff --git a/include/__mutex/once_flag.h b/include/__mutex/once_flag.h index 086f75c..d66bb87 100644 --- a/include/__mutex/once_flag.h +++ b/include/__mutex/once_flag.h @@ -21,6 +21,10 @@ # include #endif +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_CXX03_LANG) +#include +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif @@ -60,7 +64,11 @@ struct _LIBCPP_TEMPLATE_VIS once_flag { static const _State_type _Complete = ~_State_type(0); private: +#if defined(_LIBCPP_ABI_MICROSOFT) + atomic<_State_type> __state_; +#else _State_type __state_; +#endif #ifndef _LIBCPP_CXX03_LANG template @@ -115,13 +123,21 @@ void _LIBCPP_HIDE_FROM_ABI __call_once_proxy(void* __vp) { (*__p)(); } +#ifdef _LIBCPP_ABI_MICROSOFT +_LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile atomic&, void*, void (*)(void*)); +#else _LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, void*, void (*)(void*)); +#endif #ifndef _LIBCPP_CXX03_LANG template inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) { +#if defined(_LIBCPP_ABI_MICROSOFT) + if (__flag.__state_.load(memory_order_acquire) != ~once_flag::_State_type(0)) { +#else if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) { +#endif typedef tuple<_Callable&&, _Args&&...> _Gp; _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); __call_once_param<_Gp> __p(__f); @@ -133,7 +149,11 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __fun template inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) { +#if defined(_LIBCPP_ABI_MICROSOFT) + if (__flag.__state_.load(memory_order_acquire) != ~once_flag::_State_type(0)) { +#else if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) { +#endif __call_once_param<_Callable> __p(__func); std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); } @@ -141,7 +161,11 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func template inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) { +#if defined(_LIBCPP_ABI_MICROSOFT) + if (__flag.__state_.load(memory_order_relaxed) != ~once_flag::_State_type(0)) { +#else if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) { +#endif __call_once_param __p(__func); std::__call_once(__flag.__state_, &__p, &__call_once_proxy); }