protobuf/src/google/protobuf/stubs/mutex.h
Go to the documentation of this file.
1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #ifndef GOOGLE_PROTOBUF_STUBS_MUTEX_H_
31 #define GOOGLE_PROTOBUF_STUBS_MUTEX_H_
32 
33 #include <mutex>
34 
35 #ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
36 
37 #include <windows.h>
38 
39 // GetMessage conflicts with GeneratedMessageReflection::GetMessage().
40 #ifdef GetMessage
41 #undef GetMessage
42 #endif
43 
44 #endif
45 
46 #include <google/protobuf/stubs/macros.h>
47 
48 // Define thread-safety annotations for use below, if we are building with
49 // Clang.
50 #if defined(__clang__) && !defined(SWIG)
51 #define GOOGLE_PROTOBUF_ACQUIRE(...) \
52  __attribute__((acquire_capability(__VA_ARGS__)))
53 #define GOOGLE_PROTOBUF_RELEASE(...) \
54  __attribute__((release_capability(__VA_ARGS__)))
55 #define GOOGLE_PROTOBUF_SCOPED_CAPABILITY __attribute__((scoped_lockable))
56 #define GOOGLE_PROTOBUF_CAPABILITY(x) __attribute__((capability(x)))
57 #else
58 #define GOOGLE_PROTOBUF_ACQUIRE(...)
59 #define GOOGLE_PROTOBUF_RELEASE(...)
60 #define GOOGLE_PROTOBUF_SCOPED_CAPABILITY
61 #define GOOGLE_PROTOBUF_CAPABILITY(x)
62 #endif
63 
64 #include <google/protobuf/port_def.inc>
65 
66 // ===================================================================
67 // emulates google3/base/mutex.h
68 namespace google {
69 namespace protobuf {
70 namespace internal {
71 
72 #define GOOGLE_PROTOBUF_LINKER_INITIALIZED
73 
74 #ifdef GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP
75 
76 // This class is a lightweight replacement for std::mutex on Windows platforms.
77 // std::mutex does not work on Windows XP SP2 with the latest VC++ libraries,
78 // because it utilizes the Concurrency Runtime that is only supported on Windows
79 // XP SP3 and above.
80 class PROTOBUF_EXPORT CriticalSectionLock {
81  public:
82  CriticalSectionLock() { InitializeCriticalSection(&critical_section_); }
83  ~CriticalSectionLock() { DeleteCriticalSection(&critical_section_); }
84  void lock() { EnterCriticalSection(&critical_section_); }
85  void unlock() { LeaveCriticalSection(&critical_section_); }
86 
87  private:
88  CRITICAL_SECTION critical_section_;
89 
90  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CriticalSectionLock);
91 };
92 
93 #endif
94 
95 // In MSVC std::mutex does not have a constexpr constructor.
96 // This wrapper makes the constructor constexpr.
97 template <typename T>
99  public:
100  constexpr CallOnceInitializedMutex() : flag_{}, buf_{} {}
102 
103  void lock() { get().lock(); }
104  void unlock() { get().unlock(); }
105 
106  private:
107  T& get() {
108  std::call_once(flag_, [&] { ::new (static_cast<void*>(&buf_)) T(); });
109  return reinterpret_cast<T&>(buf_);
110  }
111 
113  alignas(T) char buf_[sizeof(T)];
114 };
115 
116 // Mutex is a natural type to wrap. As both google and other organization have
117 // specialized mutexes. gRPC also provides an injection mechanism for custom
118 // mutexes.
119 class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex {
120  public:
121 #if defined(__QNX__)
122  constexpr WrappedMutex() = default;
123 #else
124  constexpr WrappedMutex() {}
125 #endif
126  void Lock() GOOGLE_PROTOBUF_ACQUIRE() { mu_.lock(); }
127  void Unlock() GOOGLE_PROTOBUF_RELEASE() { mu_.unlock(); }
128  // Crash if this Mutex is not held exclusively by this thread.
129  // May fail to crash when it should; will never crash when it should not.
130  void AssertHeld() const {}
131 
132  private:
133 #if defined(GOOGLE_PROTOBUF_SUPPORT_WINDOWS_XP)
134  CallOnceInitializedMutex<CriticalSectionLock> mu_{};
135 #elif defined(_WIN32)
136  CallOnceInitializedMutex<std::mutex> mu_{};
137 #else
138  std::mutex mu_{};
139 #endif
140 };
141 
142 using Mutex = WrappedMutex;
143 
144 // MutexLock(mu) acquires mu when constructed and releases it when destroyed.
145 class GOOGLE_PROTOBUF_SCOPED_CAPABILITY PROTOBUF_EXPORT MutexLock {
146  public:
148  this->mu_->Lock();
149  }
150  ~MutexLock() GOOGLE_PROTOBUF_RELEASE() { this->mu_->Unlock(); }
151 
152  private:
153  Mutex *const mu_;
155 };
156 
157 // TODO(kenton): Implement these? Hard to implement portably.
158 typedef MutexLock ReaderMutexLock;
159 typedef MutexLock WriterMutexLock;
160 
161 // MutexLockMaybe is like MutexLock, but is a no-op when mu is nullptr.
162 class PROTOBUF_EXPORT MutexLockMaybe {
163  public:
164  explicit MutexLockMaybe(Mutex *mu) :
165  mu_(mu) { if (this->mu_ != nullptr) { this->mu_->Lock(); } }
166  ~MutexLockMaybe() { if (this->mu_ != nullptr) { this->mu_->Unlock(); } }
167  private:
168  Mutex *const mu_;
170 };
171 
172 #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
173 template<typename T>
174 class ThreadLocalStorage {
175  public:
176  ThreadLocalStorage() {
177  pthread_key_create(&key_, &ThreadLocalStorage::Delete);
178  }
179  ~ThreadLocalStorage() {
180  pthread_key_delete(key_);
181  }
182  T* Get() {
183  T* result = static_cast<T*>(pthread_getspecific(key_));
184  if (result == nullptr) {
185  result = new T();
186  pthread_setspecific(key_, result);
187  }
188  return result;
189  }
190  private:
191  static void Delete(void* value) {
192  delete static_cast<T*>(value);
193  }
194  pthread_key_t key_;
195 
196  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage);
197 };
198 #endif
199 
200 } // namespace internal
201 
202 // We made these internal so that they would show up as such in the docs,
203 // but we don't want to stick "internal::" in front of them everywhere.
204 using internal::Mutex;
205 using internal::MutexLock;
208 using internal::MutexLockMaybe;
209 
210 } // namespace protobuf
211 } // namespace google
212 
213 #undef GOOGLE_PROTOBUF_ACQUIRE
214 #undef GOOGLE_PROTOBUF_RELEASE
215 
216 #include <google/protobuf/port_undef.inc>
217 
218 #endif // GOOGLE_PROTOBUF_STUBS_MUTEX_H_
google::protobuf.internal::GOOGLE_PROTOBUF_CAPABILITY
class GOOGLE_PROTOBUF_CAPABILITY("mutex") PROTOBUF_EXPORT WrappedMutex
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:96
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
google::protobuf.internal::CallOnceInitializedMutex::CallOnceInitializedMutex
constexpr CallOnceInitializedMutex()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:100
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
MutexLock
#define MutexLock(x)
Definition: bloaty/third_party/re2/util/mutex.h:125
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
#define GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TypeName)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/macros.h:40
google::protobuf.internal::Get
const T & Get(const void *ptr)
Definition: bloaty/third_party/protobuf/src/google/protobuf/generated_message_util.cc:97
mutex
static uv_mutex_t mutex
Definition: threadpool.c:34
google::protobuf.internal::MutexLockMaybe::~MutexLockMaybe
~MutexLockMaybe()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:166
google::protobuf.internal::CallOnceInitializedMutex::buf_
char buf_[sizeof(T)]
Definition: protobuf/src/google/protobuf/stubs/mutex.h:113
google::protobuf.internal::CallOnceInitializedMutex::lock
void lock()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:103
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
env.new
def new
Definition: env.py:51
T
#define T(upbtypeconst, upbtype, ctype, default_value)
mu_
Mutex mu_
Definition: oob_backend_metric.cc:115
absl::call_once
void call_once(absl::once_flag &flag, Callable &&fn, Args &&... args)
Definition: abseil-cpp/absl/base/call_once.h:206
google::protobuf.internal::CallOnceInitializedMutex::~CallOnceInitializedMutex
~CallOnceInitializedMutex()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:101
google::protobuf.internal::once_flag
std::once_flag once_flag
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/once.h:43
google::protobuf.internal::CallOnceInitializedMutex
Definition: protobuf/src/google/protobuf/stubs/mutex.h:98
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
GOOGLE_PROTOBUF_RELEASE
#define GOOGLE_PROTOBUF_RELEASE(...)
Definition: protobuf/src/google/protobuf/stubs/mutex.h:59
GOOGLE_PROTOBUF_SCOPED_CAPABILITY
#define GOOGLE_PROTOBUF_SCOPED_CAPABILITY
Definition: protobuf/src/google/protobuf/stubs/mutex.h:60
key_
RlsLb::RequestKey key_
Definition: rls.cc:659
Delete
void Delete(T *t)
Definition: third_party/boringssl-with-bazel/src/ssl/internal.h:208
google::protobuf.internal::CallOnceInitializedMutex::get
T & get()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:107
google::protobuf.internal::MutexLock
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:116
google::protobuf.internal::MutexLockMaybe
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:130
google::protobuf.internal::CallOnceInitializedMutex::flag_
std::once_flag flag_
Definition: protobuf/src/google/protobuf/stubs/mutex.h:112
google::protobuf.internal::MutexLock::~MutexLock
~MutexLock() GOOGLE_PROTOBUF_RELEASE()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:150
google::protobuf.internal::Mutex
WrappedMutex Mutex
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:113
google::protobuf.internal::CallOnceInitializedMutex::unlock
void unlock()
Definition: protobuf/src/google/protobuf/stubs/mutex.h:104
internal
Definition: benchmark/test/output_test_helper.cc:20
google::protobuf.internal::MutexLock::MutexLock
MutexLock(Mutex *mu) GOOGLE_PROTOBUF_ACQUIRE(mu)
Definition: protobuf/src/google/protobuf/stubs/mutex.h:147
google::protobuf.internal::ReaderMutexLock
MutexLock ReaderMutexLock
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:126
GOOGLE_PROTOBUF_ACQUIRE
#define GOOGLE_PROTOBUF_ACQUIRE(...)
Definition: protobuf/src/google/protobuf/stubs/mutex.h:58
google::protobuf.internal::MutexLockMaybe::MutexLockMaybe
MutexLockMaybe(Mutex *mu)
Definition: protobuf/src/google/protobuf/stubs/mutex.h:164
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf.internal::WriterMutexLock
MutexLock WriterMutexLock
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:127


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:31