Skip to content

[libc++] Make std::lock_guard available with _LIBCPP_HAS_NO_THREADS #98717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions libcxx/include/__mutex/lock_guard.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
# pragma GCC system_header
#endif

#ifndef _LIBCPP_HAS_NO_THREADS

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _Mutex>
Expand Down Expand Up @@ -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
10 changes: 3 additions & 7 deletions libcxx/include/__mutex/tag_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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, "");
Original file line number Diff line number Diff line change
Expand Up @@ -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, "");
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads

// UNSUPPORTED: c++03

// <mutex>
Expand All @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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>

#include "types.h"

int main(int, char**) {
MyMutex m;
assert(!m.locked);
std::lock_guard<MyMutex> lg(m);
assert(m.locked);

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

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: no-threads

// <mutex>

Expand All @@ -21,12 +19,6 @@
#include <mutex>
#include <type_traits>

#include "test_macros.h"

int main(int, char**)
{
static_assert((std::is_same<std::lock_guard<std::mutex>::mutex_type,
std::mutex>::value), "");
#include "types.h"

return 0;
}
static_assert(std::is_same<std::lock_guard<MyMutex>::mutex_type, MyMutex>::value, "");
Original file line number Diff line number Diff line change
@@ -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