grpc 1.14.2 → 1.15.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +307 -12
- data/etc/roots.pem +40 -163
- data/include/grpc/grpc.h +49 -0
- data/include/grpc/grpc_security.h +0 -6
- data/include/grpc/grpc_security_constants.h +6 -0
- data/include/grpc/impl/codegen/grpc_types.h +17 -2
- data/include/grpc/impl/codegen/port_platform.h +41 -4
- data/include/grpc/support/sync.h +0 -16
- data/src/{cpp → core}/ext/filters/census/grpc_context.cc +0 -0
- data/src/core/ext/filters/client_channel/client_channel.cc +40 -11
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +11 -9
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +4 -2
- data/src/core/ext/filters/client_channel/lb_policy.h +14 -11
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +67 -90
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +108 -91
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +79 -25
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +40 -0
- data/src/core/ext/filters/client_channel/resolver.h +8 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +11 -3
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +13 -10
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +18 -4
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +13 -5
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +537 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +6 -5
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +11 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +29 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +29 -0
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +9 -0
- data/src/core/ext/filters/client_channel/subchannel.cc +21 -8
- data/src/core/ext/filters/client_channel/subchannel.h +7 -0
- data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +24 -0
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +10 -7
- data/src/core/lib/channel/channel_stack.h +1 -1
- data/src/core/lib/channel/channel_trace.cc +1 -1
- data/src/core/lib/channel/channel_trace.h +1 -1
- data/src/core/lib/channel/channelz.cc +37 -27
- data/src/core/lib/channel/channelz.h +13 -4
- data/src/core/lib/channel/channelz_registry.cc +89 -4
- data/src/core/lib/channel/channelz_registry.h +56 -39
- data/src/core/lib/gpr/arena.cc +33 -40
- data/src/core/lib/gprpp/fork.cc +41 -33
- data/src/core/lib/gprpp/fork.h +13 -4
- data/src/core/lib/gprpp/mutex_lock.h +42 -0
- data/src/core/lib/gprpp/orphanable.h +4 -2
- data/src/core/lib/gprpp/ref_counted.h +4 -2
- data/src/core/lib/gprpp/ref_counted_ptr.h +65 -13
- data/src/core/lib/iomgr/call_combiner.h +4 -1
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +77 -17
- data/src/core/lib/iomgr/ev_epollex_linux.cc +8 -26
- data/src/core/lib/iomgr/ev_epollsig_linux.cc +10 -28
- data/src/core/lib/iomgr/ev_poll_posix.cc +144 -35
- data/src/core/lib/iomgr/ev_posix.cc +58 -9
- data/src/core/lib/iomgr/ev_posix.h +22 -8
- data/src/core/lib/iomgr/exec_ctx.cc +6 -0
- data/src/core/lib/iomgr/exec_ctx.h +2 -0
- data/src/core/lib/iomgr/executor.cc +148 -72
- data/src/core/lib/iomgr/executor.h +39 -6
- data/src/core/lib/iomgr/fork_posix.cc +12 -1
- data/src/core/lib/iomgr/iocp_windows.cc +9 -4
- data/src/core/lib/iomgr/lockfree_event.cc +5 -1
- data/src/core/lib/iomgr/port.h +15 -2
- data/src/core/lib/iomgr/resolve_address_posix.cc +3 -2
- data/src/core/lib/iomgr/resolve_address_windows.cc +3 -2
- data/src/core/lib/iomgr/resource_quota.cc +78 -0
- data/src/core/lib/iomgr/resource_quota.h +16 -0
- data/src/core/lib/iomgr/socket_mutator.cc +1 -1
- data/src/core/lib/iomgr/socket_mutator.h +1 -1
- data/src/core/lib/iomgr/socket_windows.cc +33 -0
- data/src/core/lib/iomgr/socket_windows.h +6 -0
- data/src/core/lib/iomgr/tcp_windows.cc +2 -2
- data/src/core/lib/iomgr/tcp_windows.h +2 -0
- data/src/core/lib/iomgr/timer.h +3 -2
- data/src/core/lib/json/json.cc +2 -1
- data/src/core/lib/security/credentials/jwt/json_token.h +2 -0
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +2 -0
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -1
- data/src/core/lib/security/security_connector/load_system_roots.h +29 -0
- data/src/core/lib/security/security_connector/load_system_roots_fallback.cc +32 -0
- data/src/core/lib/security/security_connector/load_system_roots_linux.cc +165 -0
- data/src/core/lib/security/security_connector/load_system_roots_linux.h +44 -0
- data/src/core/lib/security/security_connector/security_connector.cc +23 -4
- data/src/core/lib/security/transport/client_auth_filter.cc +0 -4
- data/src/core/lib/security/transport/server_auth_filter.cc +0 -2
- data/src/core/lib/surface/call.cc +7 -3
- data/src/core/lib/surface/channel.cc +18 -2
- data/src/core/lib/surface/completion_queue.cc +152 -15
- data/src/core/lib/surface/completion_queue.h +20 -1
- data/src/core/lib/surface/completion_queue_factory.cc +13 -4
- data/src/core/lib/surface/init.cc +2 -2
- data/src/core/lib/surface/init.h +0 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/service_config.cc +2 -2
- data/src/core/lib/transport/service_config.h +3 -3
- data/src/core/lib/transport/transport.h +2 -0
- data/src/core/tsi/alts/crypt/aes_gcm.cc +2 -0
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +8 -0
- data/src/core/tsi/grpc_shadow_boringssl.h +3006 -0
- data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -0
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +5 -5
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +2 -0
- data/src/core/tsi/ssl_transport_security.cc +5 -3
- data/src/core/tsi/ssl_types.h +2 -0
- data/src/ruby/ext/grpc/extconf.rb +1 -26
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +12 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +18 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/generic/client_stub_spec.rb +3 -3
- data/third_party/address_sorting/address_sorting.c +7 -2
- data/third_party/address_sorting/address_sorting_windows.c +43 -3
- data/third_party/address_sorting/include/address_sorting/address_sorting.h +3 -0
- metadata +40 -31
@@ -59,7 +59,14 @@ grpc_core::DebugOnlyTraceFlag grpc_polling_api_trace(false, "polling_api");
|
|
59
59
|
|
60
60
|
/** Default poll() function - a pointer so that it can be overridden by some
|
61
61
|
* tests */
|
62
|
+
#ifndef GPR_AIX
|
62
63
|
grpc_poll_function_type grpc_poll_function = poll;
|
64
|
+
#else
|
65
|
+
int aix_poll(struct pollfd fds[], nfds_t nfds, int timeout) {
|
66
|
+
return poll(fds, nfds, timeout);
|
67
|
+
}
|
68
|
+
grpc_poll_function_type grpc_poll_function = aix_poll;
|
69
|
+
#endif
|
63
70
|
|
64
71
|
grpc_wakeup_fd grpc_global_wakeup_fd;
|
65
72
|
|
@@ -101,10 +108,28 @@ const grpc_event_engine_vtable* init_non_polling(bool explicit_request) {
|
|
101
108
|
}
|
102
109
|
} // namespace
|
103
110
|
|
104
|
-
|
111
|
+
#define ENGINE_HEAD_CUSTOM "head_custom"
|
112
|
+
#define ENGINE_TAIL_CUSTOM "tail_custom"
|
113
|
+
|
114
|
+
// The global array of event-engine factories. Each entry is a pair with a name
|
115
|
+
// and an event-engine generator function (nullptr if there is no generator
|
116
|
+
// registered for this name). The middle entries are the engines predefined by
|
117
|
+
// open-source gRPC. The head entries represent an opportunity for specific
|
118
|
+
// high-priority custom pollers to be added by the initializer plugins of
|
119
|
+
// custom-built gRPC libraries. The tail entries represent the same, but for
|
120
|
+
// low-priority custom pollers. The actual poller selected is either the first
|
121
|
+
// available one in the list if no specific poller is requested, or the first
|
122
|
+
// specific poller that is requested by name in the GRPC_POLL_STRATEGY
|
123
|
+
// environment variable if that variable is set (which should be a
|
124
|
+
// comma-separated list of one or more event engine names)
|
125
|
+
static event_engine_factory g_factories[] = {
|
126
|
+
{ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr},
|
127
|
+
{ENGINE_HEAD_CUSTOM, nullptr}, {ENGINE_HEAD_CUSTOM, nullptr},
|
105
128
|
{"epollex", grpc_init_epollex_linux}, {"epoll1", grpc_init_epoll1_linux},
|
106
129
|
{"epollsig", grpc_init_epollsig_linux}, {"poll", grpc_init_poll_posix},
|
107
130
|
{"poll-cv", grpc_init_poll_cv_posix}, {"none", init_non_polling},
|
131
|
+
{ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr},
|
132
|
+
{ENGINE_TAIL_CUSTOM, nullptr}, {ENGINE_TAIL_CUSTOM, nullptr},
|
108
133
|
};
|
109
134
|
|
110
135
|
static void add(const char* beg, const char* end, char*** ss, size_t* ns) {
|
@@ -138,7 +163,7 @@ static bool is(const char* want, const char* have) {
|
|
138
163
|
|
139
164
|
static void try_engine(const char* engine) {
|
140
165
|
for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) {
|
141
|
-
if (is(engine, g_factories[i].name)) {
|
166
|
+
if (g_factories[i].factory != nullptr && is(engine, g_factories[i].name)) {
|
142
167
|
if ((g_event_engine = g_factories[i].factory(
|
143
168
|
0 == strcmp(engine, g_factories[i].name)))) {
|
144
169
|
g_poll_strategy_name = g_factories[i].name;
|
@@ -149,14 +174,32 @@ static void try_engine(const char* engine) {
|
|
149
174
|
}
|
150
175
|
}
|
151
176
|
|
152
|
-
/*
|
153
|
-
void
|
154
|
-
|
155
|
-
|
156
|
-
|
177
|
+
/* Call this before calling grpc_event_engine_init() */
|
178
|
+
void grpc_register_event_engine_factory(const char* name,
|
179
|
+
event_engine_factory_fn factory,
|
180
|
+
bool add_at_head) {
|
181
|
+
const char* custom_match =
|
182
|
+
add_at_head ? ENGINE_HEAD_CUSTOM : ENGINE_TAIL_CUSTOM;
|
183
|
+
|
184
|
+
// Overwrite an existing registration if already registered
|
185
|
+
for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) {
|
186
|
+
if (0 == strcmp(name, g_factories[i].name)) {
|
187
|
+
g_factories[i].factory = factory;
|
188
|
+
return;
|
189
|
+
}
|
190
|
+
}
|
157
191
|
|
158
|
-
|
159
|
-
|
192
|
+
// Otherwise fill in an available custom slot
|
193
|
+
for (size_t i = 0; i < GPR_ARRAY_SIZE(g_factories); i++) {
|
194
|
+
if (0 == strcmp(g_factories[i].name, custom_match)) {
|
195
|
+
g_factories[i].name = name;
|
196
|
+
g_factories[i].factory = factory;
|
197
|
+
return;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
|
201
|
+
// Otherwise fail
|
202
|
+
GPR_ASSERT(false);
|
160
203
|
}
|
161
204
|
|
162
205
|
/* Call this only after calling grpc_event_engine_init() */
|
@@ -239,6 +282,12 @@ void grpc_fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
|
|
239
282
|
g_event_engine->fd_notify_on_error(fd, closure);
|
240
283
|
}
|
241
284
|
|
285
|
+
void grpc_fd_set_readable(grpc_fd* fd) { g_event_engine->fd_set_readable(fd); }
|
286
|
+
|
287
|
+
void grpc_fd_set_writable(grpc_fd* fd) { g_event_engine->fd_set_writable(fd); }
|
288
|
+
|
289
|
+
void grpc_fd_set_error(grpc_fd* fd) { g_event_engine->fd_set_error(fd); }
|
290
|
+
|
242
291
|
static size_t pollset_size(void) { return g_event_engine->pollset_size; }
|
243
292
|
|
244
293
|
static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) {
|
@@ -51,8 +51,10 @@ typedef struct grpc_event_engine_vtable {
|
|
51
51
|
void (*fd_notify_on_read)(grpc_fd* fd, grpc_closure* closure);
|
52
52
|
void (*fd_notify_on_write)(grpc_fd* fd, grpc_closure* closure);
|
53
53
|
void (*fd_notify_on_error)(grpc_fd* fd, grpc_closure* closure);
|
54
|
+
void (*fd_set_readable)(grpc_fd* fd);
|
55
|
+
void (*fd_set_writable)(grpc_fd* fd);
|
56
|
+
void (*fd_set_error)(grpc_fd* fd);
|
54
57
|
bool (*fd_is_shutdown)(grpc_fd* fd);
|
55
|
-
grpc_pollset* (*fd_get_read_notifier_pollset)(grpc_fd* fd);
|
56
58
|
|
57
59
|
void (*pollset_init)(grpc_pollset* pollset, gpr_mu** mu);
|
58
60
|
void (*pollset_shutdown)(grpc_pollset* pollset, grpc_closure* closure);
|
@@ -80,6 +82,11 @@ typedef struct grpc_event_engine_vtable {
|
|
80
82
|
void (*shutdown_engine)(void);
|
81
83
|
} grpc_event_engine_vtable;
|
82
84
|
|
85
|
+
/* register a new event engine factory */
|
86
|
+
void grpc_register_event_engine_factory(
|
87
|
+
const char* name, const grpc_event_engine_vtable* (*factory)(bool),
|
88
|
+
bool add_at_head);
|
89
|
+
|
83
90
|
void grpc_event_engine_init(void);
|
84
91
|
void grpc_event_engine_shutdown(void);
|
85
92
|
|
@@ -142,8 +149,20 @@ void grpc_fd_notify_on_write(grpc_fd* fd, grpc_closure* closure);
|
|
142
149
|
* needs to have been set on grpc_fd_create */
|
143
150
|
void grpc_fd_notify_on_error(grpc_fd* fd, grpc_closure* closure);
|
144
151
|
|
145
|
-
/*
|
146
|
-
|
152
|
+
/* Forcibly set the fd to be readable, resulting in the closure registered with
|
153
|
+
* grpc_fd_notify_on_read being invoked.
|
154
|
+
*/
|
155
|
+
void grpc_fd_set_readable(grpc_fd* fd);
|
156
|
+
|
157
|
+
/* Forcibly set the fd to be writable, resulting in the closure registered with
|
158
|
+
* grpc_fd_notify_on_write being invoked.
|
159
|
+
*/
|
160
|
+
void grpc_fd_set_writable(grpc_fd* fd);
|
161
|
+
|
162
|
+
/* Forcibly set the fd to have errored, resulting in the closure registered with
|
163
|
+
* grpc_fd_notify_on_error being invoked.
|
164
|
+
*/
|
165
|
+
void grpc_fd_set_error(grpc_fd* fd);
|
147
166
|
|
148
167
|
/* pollset_posix functions */
|
149
168
|
|
@@ -159,9 +178,4 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
|
|
159
178
|
typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int);
|
160
179
|
extern grpc_poll_function_type grpc_poll_function;
|
161
180
|
|
162
|
-
/* WARNING: The following two functions should be used for testing purposes
|
163
|
-
* ONLY */
|
164
|
-
void grpc_set_event_engine_test_only(const grpc_event_engine_vtable*);
|
165
|
-
const grpc_event_engine_vtable* grpc_get_event_engine_test_only();
|
166
|
-
|
167
181
|
#endif /* GRPC_CORE_LIB_IOMGR_EV_POSIX_H */
|
@@ -109,6 +109,12 @@ grpc_closure_scheduler* grpc_schedule_on_exec_ctx = &exec_ctx_scheduler;
|
|
109
109
|
namespace grpc_core {
|
110
110
|
GPR_TLS_CLASS_DEF(ExecCtx::exec_ctx_);
|
111
111
|
|
112
|
+
// WARNING: for testing purposes only!
|
113
|
+
void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) {
|
114
|
+
g_start_time = new_val;
|
115
|
+
gpr_tls_init(&exec_ctx_);
|
116
|
+
}
|
117
|
+
|
112
118
|
void ExecCtx::GlobalInit(void) {
|
113
119
|
g_start_time = gpr_now(GPR_CLOCK_MONOTONIC);
|
114
120
|
gpr_tls_init(&exec_ctx_);
|
@@ -40,19 +40,25 @@
|
|
40
40
|
gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \
|
41
41
|
}
|
42
42
|
|
43
|
+
#define EXECUTOR_TRACE0(str) \
|
44
|
+
if (executor_trace.enabled()) { \
|
45
|
+
gpr_log(GPR_INFO, "EXECUTOR " str); \
|
46
|
+
}
|
47
|
+
|
43
48
|
grpc_core::TraceFlag executor_trace(false, "executor");
|
44
49
|
|
45
50
|
GPR_TLS_DECL(g_this_thread_state);
|
46
51
|
|
47
|
-
GrpcExecutor::GrpcExecutor(const char*
|
52
|
+
GrpcExecutor::GrpcExecutor(const char* name) : name_(name) {
|
48
53
|
adding_thread_lock_ = GPR_SPINLOCK_STATIC_INITIALIZER;
|
49
|
-
|
54
|
+
gpr_atm_rel_store(&num_threads_, 0);
|
50
55
|
max_threads_ = GPR_MAX(1, 2 * gpr_cpu_num_cores());
|
51
56
|
}
|
52
57
|
|
53
58
|
void GrpcExecutor::Init() { SetThreading(true); }
|
54
59
|
|
55
|
-
size_t GrpcExecutor::RunClosures(
|
60
|
+
size_t GrpcExecutor::RunClosures(const char* executor_name,
|
61
|
+
grpc_closure_list list) {
|
56
62
|
size_t n = 0;
|
57
63
|
|
58
64
|
grpc_closure* c = list.head;
|
@@ -60,11 +66,11 @@ size_t GrpcExecutor::RunClosures(grpc_closure_list list) {
|
|
60
66
|
grpc_closure* next = c->next_data.next;
|
61
67
|
grpc_error* error = c->error_data.error;
|
62
68
|
#ifndef NDEBUG
|
63
|
-
EXECUTOR_TRACE("run %p [created by %s:%d]",
|
64
|
-
c->line_created);
|
69
|
+
EXECUTOR_TRACE("(%s) run %p [created by %s:%d]", executor_name, c,
|
70
|
+
c->file_created, c->line_created);
|
65
71
|
c->scheduled = false;
|
66
72
|
#else
|
67
|
-
EXECUTOR_TRACE("run %p", c);
|
73
|
+
EXECUTOR_TRACE("(%s) run %p", executor_name, c);
|
68
74
|
#endif
|
69
75
|
c->cb(c->cb_arg, error);
|
70
76
|
GRPC_ERROR_UNREF(error);
|
@@ -77,17 +83,21 @@ size_t GrpcExecutor::RunClosures(grpc_closure_list list) {
|
|
77
83
|
}
|
78
84
|
|
79
85
|
bool GrpcExecutor::IsThreaded() const {
|
80
|
-
return
|
86
|
+
return gpr_atm_acq_load(&num_threads_) > 0;
|
81
87
|
}
|
82
88
|
|
83
89
|
void GrpcExecutor::SetThreading(bool threading) {
|
84
|
-
gpr_atm curr_num_threads =
|
90
|
+
gpr_atm curr_num_threads = gpr_atm_acq_load(&num_threads_);
|
91
|
+
EXECUTOR_TRACE("(%s) SetThreading(%d) begin", name_, threading);
|
85
92
|
|
86
93
|
if (threading) {
|
87
|
-
if (curr_num_threads > 0)
|
94
|
+
if (curr_num_threads > 0) {
|
95
|
+
EXECUTOR_TRACE("(%s) SetThreading(true). curr_num_threads == 0", name_);
|
96
|
+
return;
|
97
|
+
}
|
88
98
|
|
89
99
|
GPR_ASSERT(num_threads_ == 0);
|
90
|
-
|
100
|
+
gpr_atm_rel_store(&num_threads_, 1);
|
91
101
|
gpr_tls_init(&g_this_thread_state);
|
92
102
|
thd_state_ = static_cast<ThreadState*>(
|
93
103
|
gpr_zalloc(sizeof(ThreadState) * max_threads_));
|
@@ -96,6 +106,7 @@ void GrpcExecutor::SetThreading(bool threading) {
|
|
96
106
|
gpr_mu_init(&thd_state_[i].mu);
|
97
107
|
gpr_cv_init(&thd_state_[i].cv);
|
98
108
|
thd_state_[i].id = i;
|
109
|
+
thd_state_[i].name = name_;
|
99
110
|
thd_state_[i].thd = grpc_core::Thread();
|
100
111
|
thd_state_[i].elems = GRPC_CLOSURE_LIST_INIT;
|
101
112
|
}
|
@@ -104,7 +115,10 @@ void GrpcExecutor::SetThreading(bool threading) {
|
|
104
115
|
grpc_core::Thread(name_, &GrpcExecutor::ThreadMain, &thd_state_[0]);
|
105
116
|
thd_state_[0].thd.Start();
|
106
117
|
} else { // !threading
|
107
|
-
if (curr_num_threads == 0)
|
118
|
+
if (curr_num_threads == 0) {
|
119
|
+
EXECUTOR_TRACE("(%s) SetThreading(false). curr_num_threads == 0", name_);
|
120
|
+
return;
|
121
|
+
}
|
108
122
|
|
109
123
|
for (size_t i = 0; i < max_threads_; i++) {
|
110
124
|
gpr_mu_lock(&thd_state_[i].mu);
|
@@ -121,20 +135,22 @@ void GrpcExecutor::SetThreading(bool threading) {
|
|
121
135
|
curr_num_threads = gpr_atm_no_barrier_load(&num_threads_);
|
122
136
|
for (gpr_atm i = 0; i < curr_num_threads; i++) {
|
123
137
|
thd_state_[i].thd.Join();
|
124
|
-
EXECUTOR_TRACE(" Thread %" PRIdPTR " of %" PRIdPTR " joined",
|
125
|
-
curr_num_threads);
|
138
|
+
EXECUTOR_TRACE("(%s) Thread %" PRIdPTR " of %" PRIdPTR " joined", name_,
|
139
|
+
i + 1, curr_num_threads);
|
126
140
|
}
|
127
141
|
|
128
|
-
|
142
|
+
gpr_atm_rel_store(&num_threads_, 0);
|
129
143
|
for (size_t i = 0; i < max_threads_; i++) {
|
130
144
|
gpr_mu_destroy(&thd_state_[i].mu);
|
131
145
|
gpr_cv_destroy(&thd_state_[i].cv);
|
132
|
-
RunClosures(thd_state_[i].elems);
|
146
|
+
RunClosures(thd_state_[i].name, thd_state_[i].elems);
|
133
147
|
}
|
134
148
|
|
135
149
|
gpr_free(thd_state_);
|
136
150
|
gpr_tls_destroy(&g_this_thread_state);
|
137
151
|
}
|
152
|
+
|
153
|
+
EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading);
|
138
154
|
}
|
139
155
|
|
140
156
|
void GrpcExecutor::Shutdown() { SetThreading(false); }
|
@@ -147,8 +163,8 @@ void GrpcExecutor::ThreadMain(void* arg) {
|
|
147
163
|
|
148
164
|
size_t subtract_depth = 0;
|
149
165
|
for (;;) {
|
150
|
-
EXECUTOR_TRACE("[%" PRIdPTR "]: step (sub_depth=%" PRIdPTR ")",
|
151
|
-
subtract_depth);
|
166
|
+
EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: step (sub_depth=%" PRIdPTR ")",
|
167
|
+
ts->name, ts->id, subtract_depth);
|
152
168
|
|
153
169
|
gpr_mu_lock(&ts->mu);
|
154
170
|
ts->depth -= subtract_depth;
|
@@ -159,7 +175,7 @@ void GrpcExecutor::ThreadMain(void* arg) {
|
|
159
175
|
}
|
160
176
|
|
161
177
|
if (ts->shutdown) {
|
162
|
-
EXECUTOR_TRACE("[%" PRIdPTR "]: shutdown", ts->id);
|
178
|
+
EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: shutdown", ts->name, ts->id);
|
163
179
|
gpr_mu_unlock(&ts->mu);
|
164
180
|
break;
|
165
181
|
}
|
@@ -169,10 +185,10 @@ void GrpcExecutor::ThreadMain(void* arg) {
|
|
169
185
|
ts->elems = GRPC_CLOSURE_LIST_INIT;
|
170
186
|
gpr_mu_unlock(&ts->mu);
|
171
187
|
|
172
|
-
EXECUTOR_TRACE("[%" PRIdPTR "]: execute", ts->id);
|
188
|
+
EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: execute", ts->name, ts->id);
|
173
189
|
|
174
190
|
grpc_core::ExecCtx::Get()->InvalidateNow();
|
175
|
-
subtract_depth = RunClosures(closures);
|
191
|
+
subtract_depth = RunClosures(ts->name, closures);
|
176
192
|
}
|
177
193
|
}
|
178
194
|
|
@@ -188,16 +204,16 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
|
|
188
204
|
do {
|
189
205
|
retry_push = false;
|
190
206
|
size_t cur_thread_count =
|
191
|
-
static_cast<size_t>(
|
207
|
+
static_cast<size_t>(gpr_atm_acq_load(&num_threads_));
|
192
208
|
|
193
209
|
// If the number of threads is zero(i.e either the executor is not threaded
|
194
210
|
// or already shutdown), then queue the closure on the exec context itself
|
195
211
|
if (cur_thread_count == 0) {
|
196
212
|
#ifndef NDEBUG
|
197
|
-
EXECUTOR_TRACE("schedule %p (created %s:%d) inline", closure,
|
213
|
+
EXECUTOR_TRACE("(%s) schedule %p (created %s:%d) inline", name_, closure,
|
198
214
|
closure->file_created, closure->line_created);
|
199
215
|
#else
|
200
|
-
EXECUTOR_TRACE("schedule %p inline", closure);
|
216
|
+
EXECUTOR_TRACE("(%s) schedule %p inline", name_, closure);
|
201
217
|
#endif
|
202
218
|
grpc_closure_list_append(grpc_core::ExecCtx::Get()->closure_list(),
|
203
219
|
closure, error);
|
@@ -213,18 +229,18 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
|
|
213
229
|
}
|
214
230
|
|
215
231
|
ThreadState* orig_ts = ts;
|
216
|
-
|
217
232
|
bool try_new_thread = false;
|
233
|
+
|
218
234
|
for (;;) {
|
219
235
|
#ifndef NDEBUG
|
220
236
|
EXECUTOR_TRACE(
|
221
|
-
"try to schedule %p (%s) (created %s:%d) to thread "
|
237
|
+
"(%s) try to schedule %p (%s) (created %s:%d) to thread "
|
222
238
|
"%" PRIdPTR,
|
223
|
-
closure, is_short ? "short" : "long", closure->file_created,
|
239
|
+
name_, closure, is_short ? "short" : "long", closure->file_created,
|
224
240
|
closure->line_created, ts->id);
|
225
241
|
#else
|
226
|
-
EXECUTOR_TRACE("try to schedule %p (%s) to thread %" PRIdPTR,
|
227
|
-
is_short ? "short" : "long", ts->id);
|
242
|
+
EXECUTOR_TRACE("(%s) try to schedule %p (%s) to thread %" PRIdPTR, name_,
|
243
|
+
closure, is_short ? "short" : "long", ts->id);
|
228
244
|
#endif
|
229
245
|
|
230
246
|
gpr_mu_lock(&ts->mu);
|
@@ -236,18 +252,22 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
|
|
236
252
|
size_t idx = ts->id;
|
237
253
|
ts = &thd_state_[(idx + 1) % cur_thread_count];
|
238
254
|
if (ts == orig_ts) {
|
239
|
-
// We cycled through all the threads. Retry enqueue again
|
240
|
-
// a new thread
|
255
|
+
// We cycled through all the threads. Retry enqueue again by creating
|
256
|
+
// a new thread
|
257
|
+
//
|
258
|
+
// TODO (sreek): There is a potential issue here. We are
|
259
|
+
// unconditionally setting try_new_thread to true here. What if the
|
260
|
+
// executor is shutdown OR if cur_thread_count is already equal to
|
261
|
+
// max_threads ?
|
262
|
+
// (Fortunately, this is not an issue yet (as of july 2018) because
|
263
|
+
// there is only one instance of long job in gRPC and hence we will
|
264
|
+
// not hit this code path)
|
241
265
|
retry_push = true;
|
242
|
-
// TODO (sreek): What if the executor is shutdown OR if
|
243
|
-
// cur_thread_count is already equal to max_threads ? (currently - as
|
244
|
-
// of July 2018, we do not run in to this issue because there is only
|
245
|
-
// one instance of long job in gRPC. This has to be fixed soon)
|
246
266
|
try_new_thread = true;
|
247
267
|
break;
|
248
268
|
}
|
249
269
|
|
250
|
-
continue;
|
270
|
+
continue; // Try the next thread-state
|
251
271
|
}
|
252
272
|
|
253
273
|
// == Found the thread state (i.e thread) to enqueue this closure! ==
|
@@ -277,13 +297,11 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
|
|
277
297
|
}
|
278
298
|
|
279
299
|
if (try_new_thread && gpr_spinlock_trylock(&adding_thread_lock_)) {
|
280
|
-
cur_thread_count =
|
281
|
-
static_cast<size_t>(gpr_atm_no_barrier_load(&num_threads_));
|
300
|
+
cur_thread_count = static_cast<size_t>(gpr_atm_acq_load(&num_threads_));
|
282
301
|
if (cur_thread_count < max_threads_) {
|
283
|
-
// Increment num_threads (
|
284
|
-
//
|
285
|
-
|
286
|
-
gpr_atm_no_barrier_store(&num_threads_, cur_thread_count + 1);
|
302
|
+
// Increment num_threads (safe to do a store instead of a cas because we
|
303
|
+
// always increment num_threads under the 'adding_thread_lock')
|
304
|
+
gpr_atm_rel_store(&num_threads_, cur_thread_count + 1);
|
287
305
|
|
288
306
|
thd_state_[cur_thread_count].thd = grpc_core::Thread(
|
289
307
|
name_, &GrpcExecutor::ThreadMain, &thd_state_[cur_thread_count]);
|
@@ -298,60 +316,118 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
|
|
298
316
|
} while (retry_push);
|
299
317
|
}
|
300
318
|
|
301
|
-
static GrpcExecutor*
|
319
|
+
static GrpcExecutor* executors[GRPC_NUM_EXECUTORS];
|
302
320
|
|
303
|
-
void
|
304
|
-
|
321
|
+
void default_enqueue_short(grpc_closure* closure, grpc_error* error) {
|
322
|
+
executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error,
|
323
|
+
true /* is_short */);
|
305
324
|
}
|
306
325
|
|
307
|
-
void
|
308
|
-
|
326
|
+
void default_enqueue_long(grpc_closure* closure, grpc_error* error) {
|
327
|
+
executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error,
|
328
|
+
false /* is_short */);
|
309
329
|
}
|
310
330
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
&global_executor_vtable_short};
|
331
|
+
void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) {
|
332
|
+
executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error,
|
333
|
+
true /* is_short */);
|
334
|
+
}
|
316
335
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
336
|
+
void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) {
|
337
|
+
executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error,
|
338
|
+
false /* is_short */);
|
339
|
+
}
|
340
|
+
|
341
|
+
static const grpc_closure_scheduler_vtable
|
342
|
+
vtables_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = {
|
343
|
+
{{&default_enqueue_short, &default_enqueue_short, "def-ex-short"},
|
344
|
+
{&default_enqueue_long, &default_enqueue_long, "def-ex-long"}},
|
345
|
+
{{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"},
|
346
|
+
{&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}};
|
347
|
+
|
348
|
+
static grpc_closure_scheduler
|
349
|
+
schedulers_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = {
|
350
|
+
{{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_SHORT]},
|
351
|
+
{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_LONG]}},
|
352
|
+
{{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_SHORT]},
|
353
|
+
{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_LONG]}}};
|
322
354
|
|
323
355
|
// grpc_executor_init() and grpc_executor_shutdown() functions are called in the
|
324
356
|
// the grpc_init() and grpc_shutdown() code paths which are protected by a
|
325
357
|
// global mutex. So it is okay to assume that these functions are thread-safe
|
326
358
|
void grpc_executor_init() {
|
327
|
-
|
328
|
-
|
329
|
-
|
359
|
+
EXECUTOR_TRACE0("grpc_executor_init() enter");
|
360
|
+
|
361
|
+
// Return if grpc_executor_init() is already called earlier
|
362
|
+
if (executors[GRPC_DEFAULT_EXECUTOR] != nullptr) {
|
363
|
+
GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] != nullptr);
|
330
364
|
return;
|
331
365
|
}
|
332
366
|
|
333
|
-
|
334
|
-
|
367
|
+
executors[GRPC_DEFAULT_EXECUTOR] =
|
368
|
+
grpc_core::New<GrpcExecutor>("default-executor");
|
369
|
+
executors[GRPC_RESOLVER_EXECUTOR] =
|
370
|
+
grpc_core::New<GrpcExecutor>("resolver-executor");
|
371
|
+
|
372
|
+
executors[GRPC_DEFAULT_EXECUTOR]->Init();
|
373
|
+
executors[GRPC_RESOLVER_EXECUTOR]->Init();
|
374
|
+
|
375
|
+
EXECUTOR_TRACE0("grpc_executor_init() done");
|
376
|
+
}
|
377
|
+
|
378
|
+
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type,
|
379
|
+
GrpcExecutorJobType job_type) {
|
380
|
+
return &schedulers_[executor_type][job_type];
|
381
|
+
}
|
382
|
+
|
383
|
+
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) {
|
384
|
+
return grpc_executor_scheduler(GRPC_DEFAULT_EXECUTOR, job_type);
|
335
385
|
}
|
336
386
|
|
337
387
|
void grpc_executor_shutdown() {
|
338
|
-
|
339
|
-
|
388
|
+
EXECUTOR_TRACE0("grpc_executor_shutdown() enter");
|
389
|
+
|
390
|
+
// Return if grpc_executor_shutdown() is already called earlier
|
391
|
+
if (executors[GRPC_DEFAULT_EXECUTOR] == nullptr) {
|
392
|
+
GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] == nullptr);
|
340
393
|
return;
|
341
394
|
}
|
342
395
|
|
343
|
-
|
344
|
-
|
345
|
-
|
396
|
+
executors[GRPC_DEFAULT_EXECUTOR]->Shutdown();
|
397
|
+
executors[GRPC_RESOLVER_EXECUTOR]->Shutdown();
|
398
|
+
|
399
|
+
// Delete the executor objects.
|
400
|
+
//
|
401
|
+
// NOTE: It is important to call Shutdown() on all executors first before
|
402
|
+
// calling Delete() because it is possible for one executor (that is not
|
403
|
+
// shutdown yet) to call Enqueue() on a different executor which is already
|
404
|
+
// shutdown. This is legal and in such cases, the Enqueue() operation
|
405
|
+
// effectively "fails" and enqueues that closure on the calling thread's
|
406
|
+
// exec_ctx.
|
407
|
+
//
|
408
|
+
// By ensuring that all executors are shutdown first, we are also ensuring
|
409
|
+
// that no thread is active across all executors.
|
410
|
+
|
411
|
+
grpc_core::Delete<GrpcExecutor>(executors[GRPC_DEFAULT_EXECUTOR]);
|
412
|
+
grpc_core::Delete<GrpcExecutor>(executors[GRPC_RESOLVER_EXECUTOR]);
|
413
|
+
executors[GRPC_DEFAULT_EXECUTOR] = nullptr;
|
414
|
+
executors[GRPC_RESOLVER_EXECUTOR] = nullptr;
|
415
|
+
|
416
|
+
EXECUTOR_TRACE0("grpc_executor_shutdown() done");
|
346
417
|
}
|
347
418
|
|
348
|
-
bool grpc_executor_is_threaded() {
|
419
|
+
bool grpc_executor_is_threaded(GrpcExecutorType executor_type) {
|
420
|
+
GPR_ASSERT(executor_type < GRPC_NUM_EXECUTORS);
|
421
|
+
return executors[executor_type]->IsThreaded();
|
422
|
+
}
|
349
423
|
|
350
|
-
|
351
|
-
|
424
|
+
bool grpc_executor_is_threaded() {
|
425
|
+
return grpc_executor_is_threaded(GRPC_DEFAULT_EXECUTOR);
|
352
426
|
}
|
353
427
|
|
354
|
-
|
355
|
-
|
356
|
-
|
428
|
+
void grpc_executor_set_threading(bool enable) {
|
429
|
+
EXECUTOR_TRACE("grpc_executor_set_threading(%d) called", enable);
|
430
|
+
for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) {
|
431
|
+
executors[i]->SetThreading(enable);
|
432
|
+
}
|
357
433
|
}
|