xref: /aosp_15_r20/external/grpc-grpc/include/grpcpp/impl/sync.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2019 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #ifndef GRPCPP_IMPL_SYNC_H
20*cc02d7e2SAndroid Build Coastguard Worker #define GRPCPP_IMPL_SYNC_H
21*cc02d7e2SAndroid Build Coastguard Worker 
22*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/port_platform.h>
23*cc02d7e2SAndroid Build Coastguard Worker 
24*cc02d7e2SAndroid Build Coastguard Worker #ifdef GPR_HAS_PTHREAD_H
25*cc02d7e2SAndroid Build Coastguard Worker #include <pthread.h>
26*cc02d7e2SAndroid Build Coastguard Worker #endif
27*cc02d7e2SAndroid Build Coastguard Worker 
28*cc02d7e2SAndroid Build Coastguard Worker #include <mutex>
29*cc02d7e2SAndroid Build Coastguard Worker 
30*cc02d7e2SAndroid Build Coastguard Worker #include "absl/synchronization/mutex.h"
31*cc02d7e2SAndroid Build Coastguard Worker 
32*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
33*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/sync.h>
34*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/time.h>
35*cc02d7e2SAndroid Build Coastguard Worker 
36*cc02d7e2SAndroid Build Coastguard Worker // The core library is not accessible in C++ codegen headers, and vice versa.
37*cc02d7e2SAndroid Build Coastguard Worker // Thus, we need to have duplicate headers with similar functionality.
38*cc02d7e2SAndroid Build Coastguard Worker // Make sure any change to this file is also reflected in
39*cc02d7e2SAndroid Build Coastguard Worker // src/core/lib/gprpp/sync.h too.
40*cc02d7e2SAndroid Build Coastguard Worker //
41*cc02d7e2SAndroid Build Coastguard Worker // Whenever possible, prefer "src/core/lib/gprpp/sync.h" over this file,
42*cc02d7e2SAndroid Build Coastguard Worker // since in core we do not rely on g_core_codegen_interface and hence do not
43*cc02d7e2SAndroid Build Coastguard Worker // pay the costs of virtual function calls.
44*cc02d7e2SAndroid Build Coastguard Worker 
45*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
46*cc02d7e2SAndroid Build Coastguard Worker namespace internal {
47*cc02d7e2SAndroid Build Coastguard Worker 
48*cc02d7e2SAndroid Build Coastguard Worker #ifdef GPR_ABSEIL_SYNC
49*cc02d7e2SAndroid Build Coastguard Worker 
50*cc02d7e2SAndroid Build Coastguard Worker using Mutex = absl::Mutex;
51*cc02d7e2SAndroid Build Coastguard Worker using MutexLock = absl::MutexLock;
52*cc02d7e2SAndroid Build Coastguard Worker using ReleasableMutexLock = absl::ReleasableMutexLock;
53*cc02d7e2SAndroid Build Coastguard Worker using CondVar = absl::CondVar;
54*cc02d7e2SAndroid Build Coastguard Worker 
55*cc02d7e2SAndroid Build Coastguard Worker #else
56*cc02d7e2SAndroid Build Coastguard Worker 
57*cc02d7e2SAndroid Build Coastguard Worker class ABSL_LOCKABLE Mutex {
58*cc02d7e2SAndroid Build Coastguard Worker  public:
59*cc02d7e2SAndroid Build Coastguard Worker   Mutex() { gpr_mu_init(&mu_); }
60*cc02d7e2SAndroid Build Coastguard Worker   ~Mutex() { gpr_mu_destroy(&mu_); }
61*cc02d7e2SAndroid Build Coastguard Worker 
62*cc02d7e2SAndroid Build Coastguard Worker   Mutex(const Mutex&) = delete;
63*cc02d7e2SAndroid Build Coastguard Worker   Mutex& operator=(const Mutex&) = delete;
64*cc02d7e2SAndroid Build Coastguard Worker 
65*cc02d7e2SAndroid Build Coastguard Worker   void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { gpr_mu_lock(&mu_); }
66*cc02d7e2SAndroid Build Coastguard Worker   void Unlock() ABSL_UNLOCK_FUNCTION() { gpr_mu_unlock(&mu_); }
67*cc02d7e2SAndroid Build Coastguard Worker 
68*cc02d7e2SAndroid Build Coastguard Worker  private:
69*cc02d7e2SAndroid Build Coastguard Worker   union {
70*cc02d7e2SAndroid Build Coastguard Worker     gpr_mu mu_;
71*cc02d7e2SAndroid Build Coastguard Worker     std::mutex do_not_use_sth_;
72*cc02d7e2SAndroid Build Coastguard Worker #ifdef GPR_HAS_PTHREAD_H
73*cc02d7e2SAndroid Build Coastguard Worker     pthread_mutex_t do_not_use_pth_;
74*cc02d7e2SAndroid Build Coastguard Worker #endif
75*cc02d7e2SAndroid Build Coastguard Worker   };
76*cc02d7e2SAndroid Build Coastguard Worker 
77*cc02d7e2SAndroid Build Coastguard Worker   friend class CondVar;
78*cc02d7e2SAndroid Build Coastguard Worker };
79*cc02d7e2SAndroid Build Coastguard Worker 
80*cc02d7e2SAndroid Build Coastguard Worker class ABSL_SCOPED_LOCKABLE MutexLock {
81*cc02d7e2SAndroid Build Coastguard Worker  public:
82*cc02d7e2SAndroid Build Coastguard Worker   explicit MutexLock(Mutex* mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) {
83*cc02d7e2SAndroid Build Coastguard Worker     mu_->Lock();
84*cc02d7e2SAndroid Build Coastguard Worker   }
85*cc02d7e2SAndroid Build Coastguard Worker   ~MutexLock() ABSL_UNLOCK_FUNCTION() { mu_->Unlock(); }
86*cc02d7e2SAndroid Build Coastguard Worker 
87*cc02d7e2SAndroid Build Coastguard Worker   MutexLock(const MutexLock&) = delete;
88*cc02d7e2SAndroid Build Coastguard Worker   MutexLock& operator=(const MutexLock&) = delete;
89*cc02d7e2SAndroid Build Coastguard Worker 
90*cc02d7e2SAndroid Build Coastguard Worker  private:
91*cc02d7e2SAndroid Build Coastguard Worker   Mutex* const mu_;
92*cc02d7e2SAndroid Build Coastguard Worker };
93*cc02d7e2SAndroid Build Coastguard Worker 
94*cc02d7e2SAndroid Build Coastguard Worker class ABSL_SCOPED_LOCKABLE ReleasableMutexLock {
95*cc02d7e2SAndroid Build Coastguard Worker  public:
96*cc02d7e2SAndroid Build Coastguard Worker   explicit ReleasableMutexLock(Mutex* mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
97*cc02d7e2SAndroid Build Coastguard Worker       : mu_(mu) {
98*cc02d7e2SAndroid Build Coastguard Worker     mu_->Lock();
99*cc02d7e2SAndroid Build Coastguard Worker   }
100*cc02d7e2SAndroid Build Coastguard Worker   ~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() {
101*cc02d7e2SAndroid Build Coastguard Worker     if (!released_) mu_->Unlock();
102*cc02d7e2SAndroid Build Coastguard Worker   }
103*cc02d7e2SAndroid Build Coastguard Worker 
104*cc02d7e2SAndroid Build Coastguard Worker   ReleasableMutexLock(const ReleasableMutexLock&) = delete;
105*cc02d7e2SAndroid Build Coastguard Worker   ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete;
106*cc02d7e2SAndroid Build Coastguard Worker 
107*cc02d7e2SAndroid Build Coastguard Worker   void Release() ABSL_UNLOCK_FUNCTION() {
108*cc02d7e2SAndroid Build Coastguard Worker     GPR_DEBUG_ASSERT(!released_);
109*cc02d7e2SAndroid Build Coastguard Worker     released_ = true;
110*cc02d7e2SAndroid Build Coastguard Worker     mu_->Unlock();
111*cc02d7e2SAndroid Build Coastguard Worker   }
112*cc02d7e2SAndroid Build Coastguard Worker 
113*cc02d7e2SAndroid Build Coastguard Worker  private:
114*cc02d7e2SAndroid Build Coastguard Worker   Mutex* const mu_;
115*cc02d7e2SAndroid Build Coastguard Worker   bool released_ = false;
116*cc02d7e2SAndroid Build Coastguard Worker };
117*cc02d7e2SAndroid Build Coastguard Worker 
118*cc02d7e2SAndroid Build Coastguard Worker class CondVar {
119*cc02d7e2SAndroid Build Coastguard Worker  public:
120*cc02d7e2SAndroid Build Coastguard Worker   CondVar() { gpr_cv_init(&cv_); }
121*cc02d7e2SAndroid Build Coastguard Worker   ~CondVar() { gpr_cv_destroy(&cv_); }
122*cc02d7e2SAndroid Build Coastguard Worker 
123*cc02d7e2SAndroid Build Coastguard Worker   CondVar(const CondVar&) = delete;
124*cc02d7e2SAndroid Build Coastguard Worker   CondVar& operator=(const CondVar&) = delete;
125*cc02d7e2SAndroid Build Coastguard Worker 
126*cc02d7e2SAndroid Build Coastguard Worker   void Signal() { gpr_cv_signal(&cv_); }
127*cc02d7e2SAndroid Build Coastguard Worker   void SignalAll() { gpr_cv_broadcast(&cv_); }
128*cc02d7e2SAndroid Build Coastguard Worker 
129*cc02d7e2SAndroid Build Coastguard Worker   void Wait(Mutex* mu) {
130*cc02d7e2SAndroid Build Coastguard Worker     gpr_cv_wait(&cv_, &mu->mu_, gpr_inf_future(GPR_CLOCK_REALTIME));
131*cc02d7e2SAndroid Build Coastguard Worker   }
132*cc02d7e2SAndroid Build Coastguard Worker 
133*cc02d7e2SAndroid Build Coastguard Worker  private:
134*cc02d7e2SAndroid Build Coastguard Worker   gpr_cv cv_;
135*cc02d7e2SAndroid Build Coastguard Worker };
136*cc02d7e2SAndroid Build Coastguard Worker 
137*cc02d7e2SAndroid Build Coastguard Worker #endif  // GPR_ABSEIL_SYNC
138*cc02d7e2SAndroid Build Coastguard Worker 
139*cc02d7e2SAndroid Build Coastguard Worker template <typename Predicate>
140*cc02d7e2SAndroid Build Coastguard Worker GRPC_DEPRECATED("incompatible with thread safety analysis")
WaitUntil(CondVar * cv,Mutex * mu,Predicate pred)141*cc02d7e2SAndroid Build Coastguard Worker static void WaitUntil(CondVar* cv, Mutex* mu, Predicate pred) {
142*cc02d7e2SAndroid Build Coastguard Worker   while (!pred()) {
143*cc02d7e2SAndroid Build Coastguard Worker     cv->Wait(mu);
144*cc02d7e2SAndroid Build Coastguard Worker   }
145*cc02d7e2SAndroid Build Coastguard Worker }
146*cc02d7e2SAndroid Build Coastguard Worker 
147*cc02d7e2SAndroid Build Coastguard Worker }  // namespace internal
148*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
149*cc02d7e2SAndroid Build Coastguard Worker 
150*cc02d7e2SAndroid Build Coastguard Worker #endif  // GRPCPP_IMPL_SYNC_H
151