backup_poller.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2017 gRPC authors.
4  *
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
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  */
18 
20 
22 
23 #include <inttypes.h>
24 
25 #include "absl/status/status.h"
26 
27 #include <grpc/support/alloc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/sync.h>
30 
41 
42 #define DEFAULT_POLL_INTERVAL_MS 5000
43 
44 namespace {
45 struct backup_poller {
46  grpc_timer polling_timer;
47  grpc_closure run_poller_closure;
48  grpc_closure shutdown_closure;
49  gpr_mu* pollset_mu;
50  grpc_pollset* pollset; // guarded by pollset_mu
51  bool shutting_down; // guarded by pollset_mu
53  gpr_refcount shutdown_refs;
54 };
55 } // namespace
56 
59 static backup_poller* g_poller = nullptr; // guarded by g_poller_mu
60 // g_poll_interval_ms is set only once at the first time
61 // grpc_client_channel_start_backup_polling() is called, after that it is
62 // treated as const.
65 
67  grpc_client_channel_backup_poll_interval_ms, DEFAULT_POLL_INTERVAL_MS,
68  "Declares the interval in ms between two backup polls on client channels. "
69  "These polls are run in the timer thread so that gRPC can process "
70  "connection failures while there is no active polling thread. "
71  "They help reconnect disconnected client channels (mostly due to "
72  "idleness), so that the next RPC on this channel won't fail. Set to 0 to "
73  "turn off the backup polls.");
74 
77  int32_t poll_interval_ms =
78  GPR_GLOBAL_CONFIG_GET(grpc_client_channel_backup_poll_interval_ms);
79  if (poll_interval_ms < 0) {
81  "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %d, "
82  "default value %" PRId64 " will be used.",
83  poll_interval_ms, g_poll_interval.millis());
84  } else {
86  }
87 }
88 
89 static void backup_poller_shutdown_unref(backup_poller* p) {
90  if (gpr_unref(&p->shutdown_refs)) {
91  grpc_pollset_destroy(p->pollset);
92  gpr_free(p->pollset);
93  gpr_free(p);
94  }
95 }
96 
97 static void done_poller(void* arg, grpc_error_handle /*error*/) {
98  backup_poller_shutdown_unref(static_cast<backup_poller*>(arg));
99 }
100 
101 static void g_poller_unref() {
103  if (gpr_unref(&g_poller->refs)) {
104  backup_poller* p = g_poller;
105  g_poller = nullptr;
107  gpr_mu_lock(p->pollset_mu);
108  p->shutting_down = true;
110  p->pollset, GRPC_CLOSURE_INIT(&p->shutdown_closure, done_poller, p,
111  grpc_schedule_on_exec_ctx));
112  gpr_mu_unlock(p->pollset_mu);
113  grpc_timer_cancel(&p->polling_timer);
115  } else {
117  }
118 }
119 
120 static void run_poller(void* arg, grpc_error_handle error) {
121  backup_poller* p = static_cast<backup_poller*>(arg);
122  if (!GRPC_ERROR_IS_NONE(error)) {
123  if (error != GRPC_ERROR_CANCELLED) {
124  GRPC_LOG_IF_ERROR("run_poller", GRPC_ERROR_REF(error));
125  }
127  return;
128  }
129  gpr_mu_lock(p->pollset_mu);
130  if (p->shutting_down) {
131  gpr_mu_unlock(p->pollset_mu);
133  return;
134  }
136  grpc_pollset_work(p->pollset, nullptr, grpc_core::ExecCtx::Get()->Now());
137  gpr_mu_unlock(p->pollset_mu);
138  GRPC_LOG_IF_ERROR("Run client channel backup poller", err);
139  grpc_timer_init(&p->polling_timer,
141  &p->run_poller_closure);
142 }
143 
144 static void g_poller_init_locked() {
145  if (g_poller == nullptr) {
146  g_poller = grpc_core::Zalloc<backup_poller>();
147  g_poller->pollset =
148  static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
149  g_poller->shutting_down = false;
150  grpc_pollset_init(g_poller->pollset, &g_poller->pollset_mu);
151  gpr_ref_init(&g_poller->refs, 0);
152  // one for timer cancellation, one for pollset shutdown, one for g_poller
153  gpr_ref_init(&g_poller->shutdown_refs, 3);
154  GRPC_CLOSURE_INIT(&g_poller->run_poller_closure, run_poller, g_poller,
155  grpc_schedule_on_exec_ctx);
156  grpc_timer_init(&g_poller->polling_timer,
158  &g_poller->run_poller_closure);
159  }
160 }
161 
163  grpc_pollset_set* interested_parties) {
166  return;
167  }
170  gpr_ref(&g_poller->refs);
171  /* Get a reference to g_poller->pollset before releasing g_poller_mu to make
172  * TSAN happy. Otherwise, reading from g_poller (i.e g_poller->pollset) after
173  * releasing the lock and setting g_poller to NULL in g_poller_unref() is
174  * being flagged as a data-race by TSAN */
175  grpc_pollset* pollset = g_poller->pollset;
177 
178  grpc_pollset_set_add_pollset(interested_parties, pollset);
179 }
180 
182  grpc_pollset_set* interested_parties) {
185  return;
186  }
187  grpc_pollset_set_del_pollset(interested_parties, g_poller->pollset);
188  g_poller_unref();
189 }
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
grpc_pollset_size
size_t grpc_pollset_size(void)
Definition: pollset.cc:56
iomgr.h
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
pollset.h
log.h
gpr_once
pthread_once_t gpr_once
Definition: impl/codegen/sync_posix.h:50
GPR_GLOBAL_CONFIG_GET
#define GPR_GLOBAL_CONFIG_GET(name)
Definition: global_config_generic.h:24
g_poller_unref
static void g_poller_unref()
Definition: backup_poller.cc:101
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
g_poller
static backup_poller * g_poller
Definition: backup_poller.cc:59
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
g_once
static gpr_once g_once
Definition: backup_poller.cc:57
error
grpc_error_handle error
Definition: retry_filter.cc:499
error_ref_leak.err
err
Definition: error_ref_leak.py:35
g_poll_interval
static grpc_core::Duration g_poll_interval
Definition: backup_poller.cc:63
closure.h
GPR_ONCE_INIT
#define GPR_ONCE_INIT
Definition: impl/codegen/sync_posix.h:52
grpc_pollset_work
grpc_error_handle grpc_pollset_work(grpc_pollset *pollset, grpc_pollset_worker **worker, grpc_core::Timestamp deadline)
Definition: pollset.cc:45
GRPC_LOG_IF_ERROR
#define GRPC_LOG_IF_ERROR(what, error)
Definition: error.h:398
xds_manager.p
p
Definition: xds_manager.py:60
GRPC_ERROR_CANCELLED
#define GRPC_ERROR_CANCELLED
Definition: error.h:238
grpc_timer
Definition: iomgr/timer.h:33
run_poller
static void run_poller(void *arg, grpc_error_handle error)
Definition: backup_poller.cc:120
gpr_refcount
Definition: impl/codegen/sync_generic.h:39
grpc_pollset_init
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu)
Definition: pollset.cc:33
gpr_once_init
GPRAPI void gpr_once_init(gpr_once *once, void(*init_function)(void))
grpc_client_channel_stop_backup_polling
void grpc_client_channel_stop_backup_polling(grpc_pollset_set *interested_parties)
Definition: backup_poller.cc:181
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
memory.h
grpc_iomgr_run_in_background
bool grpc_iomgr_run_in_background()
refs
std::vector< CordRep * > refs
Definition: cordz_info_statistics_test.cc:81
backup_poller_shutdown_unref
static void backup_poller_shutdown_unref(backup_poller *p)
Definition: backup_poller.cc:89
grpc_pollset_set_del_pollset
void grpc_pollset_set_del_pollset(grpc_pollset_set *pollset_set, grpc_pollset *pollset)
Definition: pollset_set.cc:42
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
gpr_mu_init
GPRAPI void gpr_mu_init(gpr_mu *mu)
done_poller
static void done_poller(void *arg, grpc_error_handle)
Definition: backup_poller.cc:97
pollset_set.h
arg
Definition: cmdline.cc:40
time.h
backup_poller.h
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
error.h
DEFAULT_POLL_INTERVAL_MS
#define DEFAULT_POLL_INTERVAL_MS
Definition: backup_poller.cc:42
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc_core::Duration::Zero
static constexpr Duration Zero()
Definition: src/core/lib/gprpp/time.h:130
grpc_client_channel_start_backup_polling
void grpc_client_channel_start_backup_polling(grpc_pollset_set *interested_parties)
Definition: backup_poller.cc:162
grpc_timer_cancel
void grpc_timer_cancel(grpc_timer *timer)
Definition: iomgr/timer.cc:36
grpc_core::Duration::Milliseconds
static constexpr Duration Milliseconds(int64_t millis)
Definition: src/core/lib/gprpp/time.h:155
grpc_core::Duration::millis
constexpr int64_t millis() const
Definition: src/core/lib/gprpp/time.h:208
global_config.h
GRPC_ERROR_REF
#define GRPC_ERROR_REF(err)
Definition: error.h:261
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
grpc_pollset_shutdown
void grpc_pollset_shutdown(grpc_pollset *pollset, grpc_closure *closure)
Definition: pollset.cc:37
alloc.h
g_poller_init_locked
static void g_poller_init_locked()
Definition: backup_poller.cc:144
arg
struct arg arg
exec_ctx.h
grpc_timer_init
void grpc_timer_init(grpc_timer *timer, grpc_core::Timestamp deadline, grpc_closure *closure)
Definition: iomgr/timer.cc:31
GPR_GLOBAL_CONFIG_DEFINE_INT32
GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, DEFAULT_POLL_INTERVAL_MS, "Declares the interval in ms between two backup polls on client channels. " "These polls are run in the timer thread so that gRPC can process " "connection failures while there is no active polling thread. " "They help reconnect disconnected client channels (mostly due to " "idleness), so that the next RPC on this channel won't fail. Set to 0 to " "turn off the backup polls.")
timer.h
gpr_ref_init
GPRAPI void gpr_ref_init(gpr_refcount *r, int n)
Definition: sync.cc:86
grpc_core::ExecCtx::Now
Timestamp Now()
Definition: exec_ctx.cc:90
gpr_unref
GPRAPI int gpr_unref(gpr_refcount *r)
Definition: sync.cc:103
grpc_error
Definition: error_internal.h:42
grpc_core::Duration
Definition: src/core/lib/gprpp/time.h:122
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
g_poller_mu
static gpr_mu g_poller_mu
Definition: backup_poller.cc:58
grpc_pollset
Definition: bm_cq_multiple_threads.cc:37
grpc_pollset_destroy
void grpc_pollset_destroy(grpc_pollset *pollset)
Definition: pollset.cc:41
sync.h
grpc_closure
Definition: closure.h:56
grpc_pollset_set_add_pollset
void grpc_pollset_set_add_pollset(grpc_pollset_set *pollset_set, grpc_pollset *pollset)
Definition: pollset_set.cc:37
gpr_ref
GPRAPI void gpr_ref(gpr_refcount *r)
Definition: sync.cc:88
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
grpc_client_channel_global_init_backup_polling
void grpc_client_channel_global_init_backup_polling()
Definition: backup_poller.cc:75
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:45