Implement variadic lock_guard.
Summary: This patch implements the variadic `lock_guard` paper. Making `lock_guard` variadic is a ABI breaking change because the specialization `lock_guard<_Mutex>` mangles differently then when it was the primary template. This change only provides variadic `lock_guard` in ABI V2 or when `_LIBCPP_ABI_VARIADIC_LOCK_GUARD` is defined. Note that in ABI V2 `lock_guard` must always be declared as a variadic template, even in C++03, in order to keep the ABI consistent. For this reason `lock_guard` is forward declared as a variadic template in all standard dialects and therefore depends on variadic templates being provided as an extension in C++03. All supported versions of Clang and GCC provide this extension. Reviewers: mclow.lists Subscribers: K-ballo, mclow.lists, cfe-commits Differential Revision: http://reviews.llvm.org/D21260 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@272634 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -109,6 +109,19 @@ public:
|
||||
lock_guard& operator=(lock_guard const&) = delete;
|
||||
};
|
||||
|
||||
template <class... MutexTypes> // Variadic lock_guard only provided in ABI V2.
|
||||
class lock_guard
|
||||
{
|
||||
public:
|
||||
explicit lock_guard(MutexTypes&... m);
|
||||
lock_guard(MutexTypes&... m, adopt_lock_t);
|
||||
~lock_guard();
|
||||
lock_guard(lock_guard const&) = delete;
|
||||
lock_guard& operator=(lock_guard const&) = delete;
|
||||
private:
|
||||
tuple<MutexTypes&...> pm; // exposition only
|
||||
};
|
||||
|
||||
template <class Mutex>
|
||||
class unique_lock
|
||||
{
|
||||
@@ -427,6 +440,27 @@ lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
|
||||
__lock_first(0, __l0, __l1, __l2, __l3...);
|
||||
}
|
||||
|
||||
template <class _L0>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __unlock(_L0& __l0) {
|
||||
__l0.unlock();
|
||||
}
|
||||
|
||||
template <class _L0, class _L1>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __unlock(_L0& __l0, _L1& __l1) {
|
||||
__l0.unlock();
|
||||
__l1.unlock();
|
||||
}
|
||||
|
||||
template <class _L0, class _L1, class _L2, class ..._L3>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void __unlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) {
|
||||
__l0.unlock();
|
||||
__l1.unlock();
|
||||
_VSTD::__unlock(__l2, __l3...);
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
#endif // !_LIBCPP_HAS_NO_THREADS
|
||||
@@ -577,6 +611,63 @@ call_once(once_flag& __flag, const _Callable& __func)
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
|
||||
#if defined(_LIBCPP_ABI_VARIADIC_LOCK_GUARD) \
|
||||
&& !defined(_LIBCPP_CXX03_LANG)
|
||||
template <>
|
||||
class _LIBCPP_TYPE_VIS_ONLY lock_guard<> {
|
||||
public:
|
||||
explicit lock_guard() = default;
|
||||
~lock_guard() = default;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit lock_guard(adopt_lock_t) {}
|
||||
|
||||
lock_guard(lock_guard const&) = delete;
|
||||
lock_guard& operator=(lock_guard const&) = delete;
|
||||
};
|
||||
|
||||
template <class ..._MArgs>
|
||||
class _LIBCPP_TYPE_VIS_ONLY lock_guard
|
||||
{
|
||||
static_assert(sizeof...(_MArgs) >= 2, "At least 2 lock types required");
|
||||
typedef tuple<_MArgs&...> _MutexTuple;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
explicit lock_guard(_MArgs&... __margs)
|
||||
: __t_(__margs...)
|
||||
{
|
||||
_VSTD::lock(__margs...);
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
lock_guard(_MArgs&... __margs, adopt_lock_t)
|
||||
: __t_(__margs...)
|
||||
{
|
||||
}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
~lock_guard() {
|
||||
typedef typename __make_tuple_indices<sizeof...(_MArgs)>::type _Indices;
|
||||
__unlock_unpack(_Indices{}, __t_);
|
||||
}
|
||||
|
||||
lock_guard(lock_guard const&) = delete;
|
||||
lock_guard& operator=(lock_guard const&) = delete;
|
||||
|
||||
private:
|
||||
template <size_t ..._Indx>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
static void __unlock_unpack(__tuple_indices<_Indx...>, _MutexTuple& __mt) {
|
||||
_VSTD::__unlock(_VSTD::get<_Indx>(__mt)...);
|
||||
}
|
||||
|
||||
_MutexTuple __t_;
|
||||
};
|
||||
|
||||
#endif // _LIBCPP_ABI_VARIADIC_LOCK_GUARD
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_MUTEX
|
||||
|
||||
Reference in New Issue
Block a user