Skip to content

Commit e2ddebe

Browse files
voznesenskymcopybara-github
authored andcommitted
Put ABSL annotations back in descriptor
(was failing builds with certain thread safety flags set) PiperOrigin-RevId: 826886077
1 parent b56a463 commit e2ddebe

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

python/google/protobuf/pyext/descriptor.cc

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
#include <string>
2020

2121
#include "google/protobuf/descriptor.pb.h"
22+
#include "absl/base/attributes.h"
2223
#include "absl/base/const_init.h"
24+
#include "absl/base/thread_annotations.h"
2325
#include "absl/container/flat_hash_map.h"
2426
#include "absl/log/absl_check.h"
2527
#include "absl/strings/string_view.h"
@@ -78,7 +80,7 @@ namespace python {
7880

7981
// Zero-cost mutex wrapper that compiles away to nothing in GIL-enabled builds.
8082
// Similar to nanobind's ft_mutex pattern.
81-
class FreeThreadingMutex {
83+
class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED FreeThreadingMutex {
8284
public:
8385
FreeThreadingMutex() = default;
8486
explicit constexpr FreeThreadingMutex(absl::ConstInitType)
@@ -96,21 +98,23 @@ class FreeThreadingMutex {
9698
void Unlock() {}
9799
#else
98100
// Free-threaded build: real mutex
99-
void Lock() { mutex_.Lock(); }
100-
void Unlock() { mutex_.Unlock(); }
101+
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { mutex_.Lock(); }
102+
void Unlock() ABSL_UNLOCK_FUNCTION() { mutex_.Unlock(); }
101103

102104
private:
103105
absl::Mutex mutex_;
104106
#endif
105107
};
106108

107109
// RAII lock guard for FreeThreadingMutex
108-
class FreeThreadingLockGuard {
110+
class ABSL_SCOPED_LOCKABLE FreeThreadingLockGuard {
109111
public:
110-
explicit FreeThreadingLockGuard(FreeThreadingMutex& mutex) : mutex_(mutex) {
112+
explicit FreeThreadingLockGuard(FreeThreadingMutex& mutex)
113+
ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex)
114+
: mutex_(mutex) {
111115
mutex_.Lock();
112116
}
113-
~FreeThreadingLockGuard() { mutex_.Unlock(); }
117+
~FreeThreadingLockGuard() ABSL_UNLOCK_FUNCTION() { mutex_.Unlock(); }
114118

115119
FreeThreadingLockGuard(const FreeThreadingLockGuard&) = delete;
116120
FreeThreadingLockGuard& operator=(const FreeThreadingLockGuard&) = delete;
@@ -119,18 +123,19 @@ class FreeThreadingLockGuard {
119123
FreeThreadingMutex& mutex_;
120124
};
121125

126+
// Mutex to protect interned_descriptors from concurrent access in
127+
// free-threading Python builds. Zero-cost in GIL-enabled builds.
128+
// NOTE: Free-threading support is still experimental.
129+
FreeThreadingMutex interned_descriptors_mutex(absl::kConstInit);
130+
122131
// Store interned descriptors, so that the same C++ descriptor yields the same
123132
// Python object. Objects are not immortal: this map does not own the
124133
// references, and items are deleted when the last reference to the object is
125134
// released.
126135
// This is enough to support the "is" operator on live objects.
127136
// All descriptors are stored here.
128-
absl::flat_hash_map<const void*, PyObject*>* interned_descriptors;
129-
130-
// Mutex to protect interned_descriptors from concurrent access in
131-
// free-threading Python builds. Zero-cost in GIL-enabled builds.
132-
// NOTE: Free-threading support is still experimental.
133-
FreeThreadingMutex interned_descriptors_mutex(absl::kConstInit);
137+
absl::flat_hash_map<const void*, PyObject*>* interned_descriptors
138+
ABSL_PT_GUARDED_BY(interned_descriptors_mutex);
134139

135140
PyObject* PyString_FromCppString(absl::string_view str) {
136141
return PyUnicode_FromStringAndSize(str.data(),

0 commit comments

Comments
 (0)