[libc++] Make std::lock_guard
available with _LIBCPP_HAS_NO_THREADS
(#98717)
This change makes `std::lock_guard` available when `_LIBCPP_HAS_NO_THREADS` is set. This class is generic and doesn't require threading support, and is regularly used even in environments where threading isn't available like embedded. fixes #89891 --------- Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
This commit is contained in:
parent
9e9924cc2e
commit
6192f458f4
@ -16,8 +16,6 @@
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Mutex>
|
||||
@ -47,6 +45,4 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#endif // _LIBCPP___MUTEX_LOCK_GUARD_H
|
||||
|
@ -15,8 +15,6 @@
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t {
|
||||
@ -31,18 +29,16 @@ struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t {
|
||||
explicit adopt_lock_t() = default;
|
||||
};
|
||||
|
||||
# if _LIBCPP_STD_VER >= 17
|
||||
#if _LIBCPP_STD_VER >= 17
|
||||
inline constexpr defer_lock_t defer_lock = defer_lock_t();
|
||||
inline constexpr try_to_lock_t try_to_lock = try_to_lock_t();
|
||||
inline constexpr adopt_lock_t adopt_lock = adopt_lock_t();
|
||||
# elif !defined(_LIBCPP_CXX03_LANG)
|
||||
#elif !defined(_LIBCPP_CXX03_LANG)
|
||||
constexpr defer_lock_t defer_lock = defer_lock_t();
|
||||
constexpr try_to_lock_t try_to_lock = try_to_lock_t();
|
||||
constexpr adopt_lock_t adopt_lock = adopt_lock_t();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#endif // _LIBCPP___MUTEX_TAG_TYPES_H
|
||||
|
@ -14,13 +14,6 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::mutex m0;
|
||||
std::mutex m1;
|
||||
std::lock_guard<std::mutex> lg0(m0);
|
||||
std::lock_guard<std::mutex> lg(m1);
|
||||
lg = lg0;
|
||||
#include "types.h"
|
||||
|
||||
return 0;
|
||||
}
|
||||
static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");
|
@ -14,11 +14,6 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::mutex m;
|
||||
std::lock_guard<std::mutex> lg0(m);
|
||||
std::lock_guard<std::mutex> lg(lg0);
|
||||
#include "types.h"
|
||||
|
||||
return 0;
|
||||
}
|
||||
static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");
|
@ -5,8 +5,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: no-threads
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// <mutex>
|
||||
@ -16,28 +15,18 @@
|
||||
// lock_guard(mutex_type& m, adopt_lock_t);
|
||||
|
||||
#include <mutex>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include "make_test_thread.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
std::mutex m;
|
||||
|
||||
void do_try_lock() {
|
||||
assert(m.try_lock() == false);
|
||||
}
|
||||
#include "types.h"
|
||||
|
||||
int main(int, char**) {
|
||||
MyMutex m;
|
||||
{
|
||||
m.lock();
|
||||
std::lock_guard<std::mutex> lg(m, std::adopt_lock);
|
||||
std::thread t = support::make_test_thread(do_try_lock);
|
||||
t.join();
|
||||
std::lock_guard<MyMutex> lg(m, std::adopt_lock);
|
||||
assert(m.locked);
|
||||
}
|
||||
|
||||
m.lock();
|
||||
m.unlock();
|
||||
assert(!m.locked);
|
||||
|
||||
return 0;
|
||||
}
|
@ -6,20 +6,25 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-threads
|
||||
|
||||
// <mutex>
|
||||
|
||||
// template <class Mutex> class lock_guard;
|
||||
|
||||
// explicit lock_guard(mutex_type& m);
|
||||
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::mutex m;
|
||||
std::lock_guard<std::mutex> lg = m; // expected-error{{no viable conversion}}
|
||||
#include "types.h"
|
||||
|
||||
int main(int, char**) {
|
||||
MyMutex m;
|
||||
assert(!m.locked);
|
||||
std::lock_guard<MyMutex> lg(m);
|
||||
assert(m.locked);
|
||||
|
||||
static_assert(!std::is_convertible<MyMutex, std::lock_guard<MyMutex> >::value, "constructor must be explicit");
|
||||
|
||||
return 0;
|
||||
}
|
@ -6,24 +6,24 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-threads
|
||||
// UNSUPPORTED: c++03, c++11, c++14
|
||||
|
||||
// <mutex>
|
||||
|
||||
// lock_guard
|
||||
// template <class Mutex> class lock_guard;
|
||||
|
||||
// Make sure that the implicitly-generated CTAD works.
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "types.h"
|
||||
|
||||
int main(int, char**) {
|
||||
std::mutex mutex;
|
||||
MyMutex m;
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
ASSERT_SAME_TYPE(decltype(lock), std::lock_guard<std::mutex>);
|
||||
std::lock_guard lg(m);
|
||||
ASSERT_SAME_TYPE(decltype(lg), std::lock_guard<MyMutex>);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1,49 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: no-threads
|
||||
|
||||
// <mutex>
|
||||
|
||||
// template <class Mutex> class lock_guard;
|
||||
|
||||
// explicit lock_guard(mutex_type& m);
|
||||
|
||||
// template<class _Mutex> lock_guard(lock_guard<_Mutex>)
|
||||
// -> lock_guard<_Mutex>; // C++17
|
||||
|
||||
#include <mutex>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
|
||||
#include "make_test_thread.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
std::mutex m;
|
||||
|
||||
void do_try_lock() {
|
||||
assert(m.try_lock() == false);
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(m);
|
||||
std::thread t = support::make_test_thread(do_try_lock);
|
||||
t.join();
|
||||
}
|
||||
|
||||
m.lock();
|
||||
m.unlock();
|
||||
|
||||
#if TEST_STD_VER >= 17
|
||||
std::lock_guard lg(m);
|
||||
static_assert((std::is_same<decltype(lg), std::lock_guard<decltype(m)>>::value), "" );
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: no-threads
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// Test the interoperation of std::lock_guard with std::mutex, since that is such
|
||||
// a common use case.
|
||||
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
|
||||
#include "make_test_thread.h"
|
||||
#include "test_macros.h"
|
||||
|
||||
void do_try_lock(std::mutex& m) { assert(m.try_lock() == false); }
|
||||
|
||||
int main(int, char**) {
|
||||
{
|
||||
std::mutex m;
|
||||
{
|
||||
std::lock_guard<std::mutex> lg(m);
|
||||
std::thread t = support::make_test_thread(do_try_lock, std::ref(m));
|
||||
t.join();
|
||||
}
|
||||
|
||||
// This should work because the lock_guard unlocked the mutex when it was destroyed above.
|
||||
m.lock();
|
||||
m.unlock();
|
||||
}
|
||||
|
||||
// Test CTAD
|
||||
#if TEST_STD_VER >= 17
|
||||
{
|
||||
std::mutex m;
|
||||
std::lock_guard lg(m);
|
||||
static_assert(std::is_same<decltype(lg), std::lock_guard<std::mutex>>::value, "");
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@ -5,8 +5,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: no-threads
|
||||
|
||||
// <mutex>
|
||||
|
||||
@ -21,12 +19,6 @@
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
|
||||
#include "test_macros.h"
|
||||
#include "types.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type,
|
||||
std::mutex>::value), "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
static_assert(std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value, "");
|
@ -0,0 +1,33 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
|
||||
#define TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
|
||||
|
||||
#include <cassert>
|
||||
|
||||
struct MyMutex {
|
||||
bool locked = false;
|
||||
|
||||
MyMutex() = default;
|
||||
~MyMutex() { assert(!locked); }
|
||||
|
||||
void lock() {
|
||||
assert(!locked);
|
||||
locked = true;
|
||||
}
|
||||
void unlock() {
|
||||
assert(locked);
|
||||
locked = false;
|
||||
}
|
||||
|
||||
MyMutex(MyMutex const&) = delete;
|
||||
MyMutex& operator=(MyMutex const&) = delete;
|
||||
};
|
||||
|
||||
#endif // TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
|
Loading…
x
Reference in New Issue
Block a user