[libcxx-commits] [libcxx] [libc++][ThreadSafety] Add thread safety annotations for variadic std::scoped_lock (PR #204462)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Jun 18 12:47:19 PDT 2026
================
@@ -469,25 +469,44 @@ public:
};
template <class... _MArgs>
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
+class _LIBCPP_SCOPED_LOCKABLE scoped_lock {
+# else
class scoped_lock {
+# endif
static_assert(sizeof...(_MArgs) > 1, "At least 2 lock types required");
typedef tuple<_MArgs&...> _MutexTuple;
public:
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(_MArgs&... __margs) : __t_(__margs...) {
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI explicit scoped_lock(_MArgs&... __margs)
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
+ _LIBCPP_ACQUIRE_CAPABILITY(__margs...)
+# endif
+ : __t_(__margs...) {
std::lock(__margs...);
}
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI scoped_lock(adopt_lock_t, _MArgs&... __margs) : __t_(__margs...) {}
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI scoped_lock(adopt_lock_t, _MArgs&... __margs)
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
+ _LIBCPP_REQUIRES_CAPABILITY(__margs...)
+# endif
+ : __t_(__margs...) {
+ }
- _LIBCPP_HIDE_FROM_ABI ~scoped_lock() { __unlock_unpack(make_index_sequence<sizeof...(_MArgs)>(), __t_); }
+# if defined(_LIBCPP_CLANG_VER) && _LIBCPP_CLANG_VER >= 2101
+ _LIBCPP_RELEASE_CAPABILITY
+# endif
+ _LIBCPP_HIDE_FROM_ABI ~scoped_lock() {
+ __unlock_unpack(make_index_sequence<sizeof...(_MArgs)>(), __t_);
+ }
scoped_lock(scoped_lock const&) = delete;
scoped_lock& operator=(scoped_lock const&) = delete;
private:
template <size_t... _Indx>
- _LIBCPP_HIDE_FROM_ABI static void __unlock_unpack(index_sequence<_Indx...>, _MutexTuple& __mt) {
+ _LIBCPP_NO_THREAD_SAFETY_ANALYSIS _LIBCPP_HIDE_FROM_ABI static void
----------------
AnthonyCalandraGeotab wrote:
Just annotating with `_LIBCPP_RELEASE_CAPABILITY` by itself gives me the following error:
> error: 'clang::release_capability' attribute without capability arguments can only be applied to non-static methods of a class
OK, fair enough I guess... there's probably some limitation I'm not aware of here.
So now let me try passing it the mutexes through the tuple.
When I look at how the macro is defined I see:
```cpp
#define _LIBCPP_RELEASE_CAPABILITY [[_Clang::__release_capability__]]
```
So looks like it doesn't take arguments. I thought that's kind of confusing because the error messages makes me think it could. I'll make them take arguments then:
```cpp
#define _LIBCPP_RELEASE_CAPABILITY(...) [[_Clang::__release_capability__(__VA_ARGS__)]]
```
I think the next error I got was the attribute was being applied to the function type (I had to put it after the parameter list to access the arguments in the macro).
So let's use a GNU-style attribute... Okay, works now. :)
https://github.com/llvm/llvm-project/pull/204462
More information about the libcxx-commits
mailing list