[Lldb-commits] [lldb] [lldb] Add Locked<T> and SharedLocked<T> RAII handles in Utility (NFC) (PR #198941)
Ingo Müller via lldb-commits
lldb-commits at lists.llvm.org
Fri May 22 06:58:46 PDT 2026
================
@@ -0,0 +1,225 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Locked.h"
+
+#include "gtest/gtest.h"
+
+#include <memory>
+#include <mutex>
+#include <shared_mutex>
+#include <thread>
+#include <type_traits>
+
+using namespace lldb_private;
+
+namespace {
+struct Widget {
+ int value = 0;
+};
+} // namespace
+
+// Default mutex types match the LLDB conventions: recursive_mutex for write
+// access, llvm::sys::RWMutex for read access.
+static_assert(
+ std::is_same_v<LockedPtr<Widget>::mutex_type, std::recursive_mutex>);
+static_assert(
+ std::is_same_v<LockedSP<Widget>::mutex_type, std::recursive_mutex>);
+static_assert(
+ std::is_same_v<LockedUP<Widget>::mutex_type, std::recursive_mutex>);
+static_assert(
+ std::is_same_v<SharedLockedPtr<Widget>::mutex_type, llvm::sys::RWMutex>);
+static_assert(
+ std::is_same_v<SharedLockedSP<Widget>::mutex_type, llvm::sys::RWMutex>);
+static_assert(
+ std::is_same_v<SharedLockedUP<Widget>::mutex_type, llvm::sys::RWMutex>);
+
+// Force compile-time validation of every (pointer-flavor x mutex) combination
+// the templates are intended to support.
+template class lldb_private::Locked<Widget *, std::mutex>;
+template class lldb_private::Locked<Widget *, std::recursive_mutex>;
+template class lldb_private::Locked<Widget *, llvm::sys::RWMutex>;
+template class lldb_private::Locked<std::shared_ptr<Widget>,
+ std::recursive_mutex>;
+template class lldb_private::Locked<std::unique_ptr<Widget>,
+ std::recursive_mutex>;
+template class lldb_private::SharedLocked<const Widget *, std::shared_mutex>;
+template class lldb_private::SharedLocked<const Widget *, llvm::sys::RWMutex>;
+template class lldb_private::SharedLocked<std::shared_ptr<const Widget>,
+ llvm::sys::RWMutex>;
+template class lldb_private::SharedLocked<std::unique_ptr<const Widget>,
+ llvm::sys::RWMutex>;
+
+// Locked is move-only; SharedLocked is copyable.
+static_assert(!std::is_copy_constructible_v<LockedPtr<Widget>>);
+static_assert(!std::is_copy_assignable_v<LockedPtr<Widget>>);
+static_assert(std::is_move_constructible_v<LockedPtr<Widget>>);
+static_assert(std::is_move_assignable_v<LockedPtr<Widget>>);
+
+static_assert(std::is_copy_constructible_v<SharedLockedPtr<Widget>>);
+static_assert(std::is_copy_assignable_v<SharedLockedPtr<Widget>>);
+static_assert(std::is_move_constructible_v<SharedLockedPtr<Widget>>);
+static_assert(std::is_move_assignable_v<SharedLockedPtr<Widget>>);
+
+TEST(LockedTest, DefaultConstructed) {
+ LockedPtr<Widget> handle;
+ EXPECT_FALSE(handle);
+ EXPECT_EQ(handle.get(), nullptr);
+
+ SharedLockedPtr<Widget> shared;
+ EXPECT_FALSE(shared);
+ EXPECT_EQ(shared.get(), nullptr);
+}
+
+TEST(LockedTest, ExclusivePtrAccess) {
+ std::recursive_mutex mutex;
+ Widget widget;
+
+ LockedPtr<Widget> handle(mutex, &widget);
+ ASSERT_TRUE(handle);
+ EXPECT_EQ(handle.get(), &widget);
+
+ // A different thread cannot acquire the mutex while the handle holds it.
+ std::thread other([&] { EXPECT_FALSE(mutex.try_lock()); });
+ other.join();
+
+ handle->value = 7;
+ EXPECT_EQ((*handle).value, 7);
+}
+
+TEST(LockedTest, ExclusiveReleasesOnDestruction) {
+ std::mutex mutex;
+ Widget widget;
+ {
+ LockedPtr<Widget, std::mutex> handle(mutex, &widget);
+ EXPECT_FALSE(mutex.try_lock());
+ }
+ EXPECT_TRUE(mutex.try_lock());
+ mutex.unlock();
----------------
ingomueller-net wrote:
Maybe #199218 is a solution?
https://github.com/llvm/llvm-project/pull/198941
More information about the lldb-commits
mailing list