mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-04 03:44:59 +00:00
[libc++][NFC] Clean up std::__call_once
__call_once is large and cluttered with #ifdef preprocessor guards. This cleans it up a bit by using an exception guard instead of try-catch. Differential Revision: https://reviews.llvm.org/D112319 Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
This commit is contained in:
parent
641124a9b9
commit
be8c2df2b1
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <__assert>
|
#include <__assert>
|
||||||
#include <__thread/id.h>
|
#include <__thread/id.h>
|
||||||
|
#include <__utility/exception_guard.h>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
@ -205,56 +206,40 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
|
|||||||
void (*func)(void*))
|
void (*func)(void*))
|
||||||
{
|
{
|
||||||
#if defined(_LIBCPP_HAS_NO_THREADS)
|
#if defined(_LIBCPP_HAS_NO_THREADS)
|
||||||
if (flag == once_flag::_Unset)
|
|
||||||
{
|
if (flag == once_flag::_Unset) {
|
||||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
auto guard = std::__make_exception_guard([&flag] { flag = once_flag::_Unset; });
|
||||||
try
|
flag = once_flag::_Pending;
|
||||||
{
|
func(arg);
|
||||||
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
|
flag = once_flag::_Complete;
|
||||||
flag = once_flag::_Pending;
|
guard.__complete();
|
||||||
func(arg);
|
|
||||||
flag = once_flag::_Complete;
|
|
||||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
flag = once_flag::_Unset;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !_LIBCPP_HAS_NO_THREADS
|
#else // !_LIBCPP_HAS_NO_THREADS
|
||||||
|
|
||||||
__libcpp_mutex_lock(&mut);
|
__libcpp_mutex_lock(&mut);
|
||||||
while (flag == once_flag::_Pending)
|
while (flag == once_flag::_Pending)
|
||||||
__libcpp_condvar_wait(&cv, &mut);
|
__libcpp_condvar_wait(&cv, &mut);
|
||||||
if (flag == once_flag::_Unset)
|
if (flag == once_flag::_Unset) {
|
||||||
{
|
auto guard = std::__make_exception_guard([&flag] {
|
||||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
|
|
||||||
__libcpp_relaxed_store(&flag, once_flag::_Pending);
|
|
||||||
__libcpp_mutex_unlock(&mut);
|
|
||||||
func(arg);
|
|
||||||
__libcpp_mutex_lock(&mut);
|
|
||||||
__libcpp_atomic_store(&flag, once_flag::_Complete,
|
|
||||||
_AO_Release);
|
|
||||||
__libcpp_mutex_unlock(&mut);
|
|
||||||
__libcpp_condvar_broadcast(&cv);
|
|
||||||
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
__libcpp_mutex_lock(&mut);
|
__libcpp_mutex_lock(&mut);
|
||||||
__libcpp_relaxed_store(&flag, once_flag::_Unset);
|
__libcpp_relaxed_store(&flag, once_flag::_Unset);
|
||||||
__libcpp_mutex_unlock(&mut);
|
__libcpp_mutex_unlock(&mut);
|
||||||
__libcpp_condvar_broadcast(&cv);
|
__libcpp_condvar_broadcast(&cv);
|
||||||
throw;
|
});
|
||||||
}
|
|
||||||
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
|
__libcpp_relaxed_store(&flag, once_flag::_Pending);
|
||||||
}
|
|
||||||
else
|
|
||||||
__libcpp_mutex_unlock(&mut);
|
__libcpp_mutex_unlock(&mut);
|
||||||
|
func(arg);
|
||||||
|
__libcpp_mutex_lock(&mut);
|
||||||
|
__libcpp_atomic_store(&flag, once_flag::_Complete, _AO_Release);
|
||||||
|
__libcpp_mutex_unlock(&mut);
|
||||||
|
__libcpp_condvar_broadcast(&cv);
|
||||||
|
guard.__complete();
|
||||||
|
} else {
|
||||||
|
__libcpp_mutex_unlock(&mut);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !_LIBCPP_HAS_NO_THREADS
|
#endif // !_LIBCPP_HAS_NO_THREADS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user