Skip to content

Commit 6192f45

Browse files
petrhosekldionne
andauthored
[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 <[email protected]>
1 parent 9e9924c commit 6192f45

File tree

11 files changed

+113
-114
lines changed

11 files changed

+113
-114
lines changed

libcxx/include/__mutex/lock_guard.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
# pragma GCC system_header
1717
#endif
1818

19-
#ifndef _LIBCPP_HAS_NO_THREADS
20-
2119
_LIBCPP_BEGIN_NAMESPACE_STD
2220

2321
template <class _Mutex>
@@ -47,6 +45,4 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard);
4745

4846
_LIBCPP_END_NAMESPACE_STD
4947

50-
#endif // _LIBCPP_HAS_NO_THREADS
51-
5248
#endif // _LIBCPP___MUTEX_LOCK_GUARD_H

libcxx/include/__mutex/tag_types.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
# pragma GCC system_header
1616
#endif
1717

18-
#ifndef _LIBCPP_HAS_NO_THREADS
19-
2018
_LIBCPP_BEGIN_NAMESPACE_STD
2119

2220
struct _LIBCPP_EXPORTED_FROM_ABI defer_lock_t {
@@ -31,18 +29,16 @@ struct _LIBCPP_EXPORTED_FROM_ABI adopt_lock_t {
3129
explicit adopt_lock_t() = default;
3230
};
3331

34-
# if _LIBCPP_STD_VER >= 17
32+
#if _LIBCPP_STD_VER >= 17
3533
inline constexpr defer_lock_t defer_lock = defer_lock_t();
3634
inline constexpr try_to_lock_t try_to_lock = try_to_lock_t();
3735
inline constexpr adopt_lock_t adopt_lock = adopt_lock_t();
38-
# elif !defined(_LIBCPP_CXX03_LANG)
36+
#elif !defined(_LIBCPP_CXX03_LANG)
3937
constexpr defer_lock_t defer_lock = defer_lock_t();
4038
constexpr try_to_lock_t try_to_lock = try_to_lock_t();
4139
constexpr adopt_lock_t adopt_lock = adopt_lock_t();
42-
# endif
40+
#endif
4341

4442
_LIBCPP_END_NAMESPACE_STD
4543

46-
#endif // _LIBCPP_HAS_NO_THREADS
47-
4844
#endif // _LIBCPP___MUTEX_TAG_TYPES_H

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.fail.cpp renamed to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/assign.compile.pass.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@
1414

1515
#include <mutex>
1616

17-
int main(int, char**)
18-
{
19-
std::mutex m0;
20-
std::mutex m1;
21-
std::lock_guard<std::mutex> lg0(m0);
22-
std::lock_guard<std::mutex> lg(m1);
23-
lg = lg0;
17+
#include "types.h"
2418

25-
return 0;
26-
}
19+
static_assert(!std::is_copy_assignable<std::lock_guard<MyMutex> >::value, "");

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.fail.cpp renamed to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/copy.compile.pass.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414

1515
#include <mutex>
1616

17-
int main(int, char**)
18-
{
19-
std::mutex m;
20-
std::lock_guard<std::mutex> lg0(m);
21-
std::lock_guard<std::mutex> lg(lg0);
17+
#include "types.h"
2218

23-
return 0;
24-
}
19+
static_assert(!std::is_copy_constructible<std::lock_guard<MyMutex> >::value, "");

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/adopt_lock.pass.cpp renamed to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.adopt_lock.pass.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
//
9-
// UNSUPPORTED: no-threads
8+
109
// UNSUPPORTED: c++03
1110

1211
// <mutex>
@@ -16,28 +15,18 @@
1615
// lock_guard(mutex_type& m, adopt_lock_t);
1716

1817
#include <mutex>
19-
#include <cstdlib>
2018
#include <cassert>
2119

22-
#include "make_test_thread.h"
23-
#include "test_macros.h"
24-
25-
std::mutex m;
26-
27-
void do_try_lock() {
28-
assert(m.try_lock() == false);
29-
}
20+
#include "types.h"
3021

3122
int main(int, char**) {
23+
MyMutex m;
3224
{
3325
m.lock();
34-
std::lock_guard<std::mutex> lg(m, std::adopt_lock);
35-
std::thread t = support::make_test_thread(do_try_lock);
36-
t.join();
26+
std::lock_guard<MyMutex> lg(m, std::adopt_lock);
27+
assert(m.locked);
3728
}
38-
39-
m.lock();
40-
m.unlock();
29+
assert(!m.locked);
4130

4231
return 0;
4332
}

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.verify.cpp renamed to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/ctor.mutex.pass.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,25 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: no-threads
10-
119
// <mutex>
1210

1311
// template <class Mutex> class lock_guard;
1412

1513
// explicit lock_guard(mutex_type& m);
1614

15+
#include <cassert>
1716
#include <mutex>
17+
#include <type_traits>
18+
19+
#include "types.h"
20+
21+
int main(int, char**) {
22+
MyMutex m;
23+
assert(!m.locked);
24+
std::lock_guard<MyMutex> lg(m);
25+
assert(m.locked);
1826

19-
int main(int, char**)
20-
{
21-
std::mutex m;
22-
std::lock_guard<std::mutex> lg = m; // expected-error{{no viable conversion}}
27+
static_assert(!std::is_convertible<MyMutex, std::lock_guard<MyMutex> >::value, "constructor must be explicit");
2328

2429
return 0;
2530
}

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/implicit_ctad.pass.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,24 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
// UNSUPPORTED: no-threads
109
// UNSUPPORTED: c++03, c++11, c++14
1110

1211
// <mutex>
1312

14-
// lock_guard
13+
// template <class Mutex> class lock_guard;
1514

1615
// Make sure that the implicitly-generated CTAD works.
1716

1817
#include <mutex>
1918

2019
#include "test_macros.h"
20+
#include "types.h"
2121

2222
int main(int, char**) {
23-
std::mutex mutex;
23+
MyMutex m;
2424
{
25-
std::lock_guard lock(mutex);
26-
ASSERT_SAME_TYPE(decltype(lock), std::lock_guard<std::mutex>);
25+
std::lock_guard lg(m);
26+
ASSERT_SAME_TYPE(decltype(lg), std::lock_guard<MyMutex>);
2727
}
2828

2929
return 0;

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/mutex.pass.cpp

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// UNSUPPORTED: no-threads
10+
// UNSUPPORTED: c++03
11+
12+
// Test the interoperation of std::lock_guard with std::mutex, since that is such
13+
// a common use case.
14+
15+
#include <cassert>
16+
#include <mutex>
17+
#include <type_traits>
18+
#include <functional>
19+
20+
#include "make_test_thread.h"
21+
#include "test_macros.h"
22+
23+
void do_try_lock(std::mutex& m) { assert(m.try_lock() == false); }
24+
25+
int main(int, char**) {
26+
{
27+
std::mutex m;
28+
{
29+
std::lock_guard<std::mutex> lg(m);
30+
std::thread t = support::make_test_thread(do_try_lock, std::ref(m));
31+
t.join();
32+
}
33+
34+
// This should work because the lock_guard unlocked the mutex when it was destroyed above.
35+
m.lock();
36+
m.unlock();
37+
}
38+
39+
// Test CTAD
40+
#if TEST_STD_VER >= 17
41+
{
42+
std::mutex m;
43+
std::lock_guard lg(m);
44+
static_assert(std::is_same<decltype(lg), std::lock_guard<std::mutex>>::value, "");
45+
}
46+
#endif
47+
48+
return 0;
49+
}

libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.pass.cpp renamed to libcxx/test/std/thread/thread.mutex/thread.lock/thread.lock.guard/types.compile.pass.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
//
9-
// UNSUPPORTED: no-threads
108

119
// <mutex>
1210

@@ -21,12 +19,6 @@
2119
#include <mutex>
2220
#include <type_traits>
2321

24-
#include "test_macros.h"
25-
26-
int main(int, char**)
27-
{
28-
static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type,
29-
std::mutex>::value), "");
22+
#include "types.h"
3023

31-
return 0;
32-
}
24+
static_assert(std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value, "");
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
10+
#define TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H
11+
12+
#include <cassert>
13+
14+
struct MyMutex {
15+
bool locked = false;
16+
17+
MyMutex() = default;
18+
~MyMutex() { assert(!locked); }
19+
20+
void lock() {
21+
assert(!locked);
22+
locked = true;
23+
}
24+
void unlock() {
25+
assert(locked);
26+
locked = false;
27+
}
28+
29+
MyMutex(MyMutex const&) = delete;
30+
MyMutex& operator=(MyMutex const&) = delete;
31+
};
32+
33+
#endif // TEST_STD_THREAD_THREAD_MUTEX_THREAD_LOCK_THREAD_LOCK_GUARD_TYPES_H

0 commit comments

Comments
 (0)