3 * Copyright 2019 gRPC authors.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #ifndef GRPCPP_IMPL_CODEGEN_SYNC_H
20 #define GRPCPP_IMPL_CODEGEN_SYNC_H
22 #include <grpc/impl/codegen/port_platform.h>
24 #ifdef GPR_HAS_PTHREAD_H
30 #include <grpc/impl/codegen/log.h>
31 #include <grpc/impl/codegen/sync.h>
33 #include <grpcpp/impl/codegen/core_codegen_interface.h>
35 // The core library is not accessible in C++ codegen headers, and vice versa.
36 // Thus, we need to have duplicate headers with similar functionality.
37 // Make sure any change to this file is also reflected in
38 // src/core/lib/gprpp/sync.h too.
40 // Whenever possible, prefer "src/core/lib/gprpp/sync.h" over this file,
41 // since in core we do not rely on g_core_codegen_interface and hence do not
42 // pay the costs of virtual function calls.
49 Mutex() { g_core_codegen_interface->gpr_mu_init(&mu_); }
50 ~Mutex() { g_core_codegen_interface->gpr_mu_destroy(&mu_); }
52 Mutex(const Mutex&) = delete;
53 Mutex& operator=(const Mutex&) = delete;
55 gpr_mu* get() { return &mu_; }
56 const gpr_mu* get() const { return &mu_; }
61 std::mutex do_not_use_sth_;
62 #ifdef GPR_HAS_PTHREAD_H
63 pthread_mutex_t do_not_use_pth_;
68 // MutexLock is a std::
71 explicit MutexLock(Mutex* mu) : mu_(mu->get()) {
72 g_core_codegen_interface->gpr_mu_lock(mu_);
74 explicit MutexLock(gpr_mu* mu) : mu_(mu) {
75 g_core_codegen_interface->gpr_mu_lock(mu_);
77 ~MutexLock() { g_core_codegen_interface->gpr_mu_unlock(mu_); }
79 MutexLock(const MutexLock&) = delete;
80 MutexLock& operator=(const MutexLock&) = delete;
86 class ReleasableMutexLock {
88 explicit ReleasableMutexLock(Mutex* mu) : mu_(mu->get()) {
89 g_core_codegen_interface->gpr_mu_lock(mu_);
91 explicit ReleasableMutexLock(gpr_mu* mu) : mu_(mu) {
92 g_core_codegen_interface->gpr_mu_lock(mu_);
94 ~ReleasableMutexLock() {
95 if (!released_) g_core_codegen_interface->gpr_mu_unlock(mu_);
98 ReleasableMutexLock(const ReleasableMutexLock&) = delete;
99 ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete;
102 GPR_DEBUG_ASSERT(released_);
103 g_core_codegen_interface->gpr_mu_lock(mu_);
108 GPR_DEBUG_ASSERT(!released_);
110 g_core_codegen_interface->gpr_mu_unlock(mu_);
115 bool released_ = false;
120 CondVar() { g_core_codegen_interface->gpr_cv_init(&cv_); }
121 ~CondVar() { g_core_codegen_interface->gpr_cv_destroy(&cv_); }
123 CondVar(const CondVar&) = delete;
124 CondVar& operator=(const CondVar&) = delete;
126 void Signal() { g_core_codegen_interface->gpr_cv_signal(&cv_); }
127 void Broadcast() { g_core_codegen_interface->gpr_cv_broadcast(&cv_); }
129 int Wait(Mutex* mu) {
131 g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME));
133 int Wait(Mutex* mu, const gpr_timespec& deadline) {
134 return g_core_codegen_interface->gpr_cv_wait(&cv_, mu->get(), deadline);
137 template <typename Predicate>
138 void WaitUntil(Mutex* mu, Predicate pred) {
140 Wait(mu, g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME));
148 } // namespace internal
151 #endif // GRPCPP_IMPL_CODEGEN_SYNC_H