grpc 1.18.0 → 1.19.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.

Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +301 -33
  3. data/include/grpc/grpc_security.h +195 -0
  4. data/include/grpc/impl/codegen/grpc_types.h +17 -1
  5. data/include/grpc/impl/codegen/port_platform.h +36 -0
  6. data/include/grpc/impl/codegen/slice.h +1 -1
  7. data/src/core/ext/filters/client_channel/channel_connectivity.cc +2 -0
  8. data/src/core/ext/filters/client_channel/client_channel.cc +74 -69
  9. data/src/core/ext/filters/client_channel/client_channel.h +2 -2
  10. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +5 -6
  11. data/src/core/ext/filters/client_channel/client_channel_channelz.h +5 -4
  12. data/src/core/ext/filters/client_channel/client_channel_factory.cc +2 -2
  13. data/src/core/ext/filters/client_channel/client_channel_factory.h +4 -4
  14. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +3 -3
  15. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +176 -0
  16. data/src/core/ext/filters/client_channel/global_subchannel_pool.h +68 -0
  17. data/src/core/ext/filters/client_channel/health/health_check_client.cc +10 -8
  18. data/src/core/ext/filters/client_channel/health/health_check_client.h +1 -1
  19. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +146 -156
  20. data/src/core/ext/filters/client_channel/lb_policy.cc +30 -1
  21. data/src/core/ext/filters/client_channel/lb_policy.h +29 -1
  22. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +28 -30
  23. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +5 -8
  24. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +5 -8
  25. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +23 -24
  26. data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +80 -15
  27. data/src/core/ext/filters/client_channel/lb_policy_factory.h +6 -1
  28. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +2 -2
  29. data/src/core/ext/filters/client_channel/lb_policy_registry.h +1 -1
  30. data/src/core/ext/filters/client_channel/local_subchannel_pool.cc +96 -0
  31. data/src/core/ext/filters/client_channel/local_subchannel_pool.h +56 -0
  32. data/src/core/ext/filters/client_channel/parse_address.cc +24 -5
  33. data/src/core/ext/filters/client_channel/request_routing.cc +13 -3
  34. data/src/core/ext/filters/client_channel/request_routing.h +5 -1
  35. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +11 -6
  36. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
  37. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +7 -35
  38. data/src/core/ext/filters/client_channel/subchannel.cc +698 -791
  39. data/src/core/ext/filters/client_channel/subchannel.h +213 -123
  40. data/src/core/ext/filters/client_channel/subchannel_pool_interface.cc +97 -0
  41. data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +94 -0
  42. data/src/core/ext/filters/http/client_authority_filter.cc +5 -2
  43. data/src/core/ext/filters/max_age/max_age_filter.cc +1 -1
  44. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +13 -12
  45. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +5 -7
  46. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +19 -27
  47. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +18 -19
  48. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +27 -6
  49. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -1
  50. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +3 -2
  51. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +1 -1
  52. data/src/core/ext/transport/chttp2/transport/writing.cc +8 -5
  53. data/src/core/lib/channel/handshaker.cc +141 -214
  54. data/src/core/lib/channel/handshaker.h +110 -101
  55. data/src/core/lib/channel/handshaker_factory.h +11 -19
  56. data/src/core/lib/channel/handshaker_registry.cc +64 -52
  57. data/src/core/lib/channel/handshaker_registry.h +21 -16
  58. data/src/core/lib/gpr/log_posix.cc +2 -1
  59. data/src/core/lib/gpr/time.cc +8 -0
  60. data/src/core/lib/gpr/time_posix.cc +8 -2
  61. data/src/core/lib/gprpp/optional.h +47 -0
  62. data/src/core/lib/http/httpcli_security_connector.cc +13 -14
  63. data/src/core/lib/iomgr/buffer_list.cc +182 -24
  64. data/src/core/lib/iomgr/buffer_list.h +70 -8
  65. data/src/core/lib/iomgr/combiner.cc +11 -3
  66. data/src/core/lib/iomgr/error.cc +9 -5
  67. data/src/core/lib/iomgr/ev_epoll1_linux.cc +3 -0
  68. data/src/core/lib/iomgr/ev_epollex_linux.cc +136 -162
  69. data/src/core/lib/iomgr/ev_poll_posix.cc +3 -0
  70. data/src/core/lib/iomgr/ev_posix.cc +4 -0
  71. data/src/core/lib/iomgr/ev_posix.h +4 -0
  72. data/src/core/lib/iomgr/exec_ctx.cc +1 -0
  73. data/src/core/lib/iomgr/exec_ctx.h +137 -8
  74. data/src/core/lib/iomgr/executor.cc +122 -87
  75. data/src/core/lib/iomgr/executor.h +53 -48
  76. data/src/core/lib/iomgr/fork_posix.cc +6 -4
  77. data/src/core/lib/iomgr/{network_status_tracker.cc → grpc_if_nametoindex.h} +8 -14
  78. data/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc +42 -0
  79. data/src/core/lib/iomgr/{network_status_tracker.h → grpc_if_nametoindex_unsupported.cc} +15 -9
  80. data/src/core/lib/iomgr/internal_errqueue.h +105 -3
  81. data/src/core/lib/iomgr/iomgr.cc +6 -5
  82. data/src/core/lib/iomgr/iomgr.h +8 -0
  83. data/src/core/lib/iomgr/iomgr_custom.cc +6 -2
  84. data/src/core/lib/iomgr/iomgr_internal.cc +4 -0
  85. data/src/core/lib/iomgr/iomgr_internal.h +4 -0
  86. data/src/core/lib/iomgr/iomgr_posix.cc +10 -1
  87. data/src/core/lib/iomgr/iomgr_windows.cc +8 -1
  88. data/src/core/lib/iomgr/port.h +1 -0
  89. data/src/core/lib/iomgr/resolve_address_posix.cc +4 -3
  90. data/src/core/lib/iomgr/resolve_address_windows.cc +2 -1
  91. data/src/core/lib/iomgr/tcp_custom.cc +0 -4
  92. data/src/core/lib/iomgr/tcp_posix.cc +58 -44
  93. data/src/core/lib/iomgr/tcp_uv.cc +0 -1
  94. data/src/core/lib/iomgr/tcp_windows.cc +0 -4
  95. data/src/core/lib/iomgr/timer_manager.cc +8 -0
  96. data/src/core/lib/iomgr/udp_server.cc +6 -4
  97. data/src/core/lib/json/json.cc +1 -4
  98. data/src/core/lib/security/credentials/alts/alts_credentials.cc +1 -1
  99. data/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc +2 -2
  100. data/src/core/lib/security/credentials/composite/composite_credentials.h +4 -0
  101. data/src/core/lib/security/credentials/credentials.h +9 -1
  102. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +15 -2
  103. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +2 -0
  104. data/src/core/lib/security/credentials/jwt/json_token.cc +1 -1
  105. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -0
  106. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
  107. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +2 -2
  108. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +1 -0
  109. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +192 -0
  110. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +213 -0
  111. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +10 -8
  112. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +6 -10
  113. data/src/core/lib/security/security_connector/local/local_security_connector.cc +10 -8
  114. data/src/core/lib/security/security_connector/security_connector.h +2 -2
  115. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +4 -6
  116. data/src/core/lib/security/security_connector/ssl_utils.h +33 -0
  117. data/src/core/lib/security/transport/security_handshaker.cc +267 -300
  118. data/src/core/lib/security/transport/security_handshaker.h +11 -2
  119. data/src/core/lib/security/transport/server_auth_filter.cc +1 -0
  120. data/src/core/lib/surface/call.cc +5 -1
  121. data/src/core/lib/surface/channel_init.h +5 -0
  122. data/src/core/lib/surface/completion_queue.cc +4 -7
  123. data/src/core/lib/surface/init.cc +5 -3
  124. data/src/core/lib/surface/init_secure.cc +1 -1
  125. data/src/core/lib/surface/server.cc +19 -17
  126. data/src/core/lib/surface/version.cc +1 -1
  127. data/src/core/lib/transport/service_config.h +1 -0
  128. data/src/core/lib/transport/static_metadata.cc +279 -279
  129. data/src/core/lib/transport/transport.cc +5 -3
  130. data/src/core/tsi/ssl_transport_security.cc +10 -4
  131. data/src/ruby/ext/grpc/extconf.rb +12 -4
  132. data/src/ruby/ext/grpc/rb_call_credentials.c +8 -5
  133. data/src/ruby/ext/grpc/rb_channel.c +14 -10
  134. data/src/ruby/ext/grpc/rb_channel_credentials.c +8 -4
  135. data/src/ruby/ext/grpc/rb_compression_options.c +9 -7
  136. data/src/ruby/ext/grpc/rb_event_thread.c +2 -0
  137. data/src/ruby/ext/grpc/rb_grpc.c +22 -23
  138. data/src/ruby/ext/grpc/rb_grpc.h +4 -2
  139. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +18 -0
  140. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +27 -0
  141. data/src/ruby/ext/grpc/rb_server.c +8 -4
  142. data/src/ruby/lib/grpc/version.rb +1 -1
  143. metadata +46 -39
  144. data/src/core/ext/filters/client_channel/subchannel_index.cc +0 -248
  145. data/src/core/ext/filters/client_channel/subchannel_index.h +0 -76
  146. data/src/core/lib/channel/handshaker_factory.cc +0 -42
@@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() {
1782
1782
  * event engine binding
1783
1783
  */
1784
1784
 
1785
+ static bool is_any_background_poller_thread(void) { return false; }
1786
+
1785
1787
  static void shutdown_background_closure(void) {}
1786
1788
 
1787
1789
  static void shutdown_engine(void) {
@@ -1828,6 +1830,7 @@ static const grpc_event_engine_vtable vtable = {
1828
1830
  pollset_set_add_fd,
1829
1831
  pollset_set_del_fd,
1830
1832
 
1833
+ is_any_background_poller_thread,
1831
1834
  shutdown_background_closure,
1832
1835
  shutdown_engine,
1833
1836
  };
@@ -399,6 +399,10 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
399
399
  g_event_engine->pollset_set_del_fd(pollset_set, fd);
400
400
  }
401
401
 
402
+ bool grpc_is_any_background_poller_thread(void) {
403
+ return g_event_engine->is_any_background_poller_thread();
404
+ }
405
+
402
406
  void grpc_shutdown_background_closure(void) {
403
407
  g_event_engine->shutdown_background_closure();
404
408
  }
@@ -80,6 +80,7 @@ typedef struct grpc_event_engine_vtable {
80
80
  void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
81
81
  void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
82
82
 
83
+ bool (*is_any_background_poller_thread)(void);
83
84
  void (*shutdown_background_closure)(void);
84
85
  void (*shutdown_engine)(void);
85
86
  } grpc_event_engine_vtable;
@@ -181,6 +182,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd);
181
182
  void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
182
183
  void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
183
184
 
185
+ /* Returns true if the caller is a worker thread for any background poller. */
186
+ bool grpc_is_any_background_poller_thread();
187
+
184
188
  /* Shut down all the closures registered in the background poller. */
185
189
  void grpc_shutdown_background_closure();
186
190
 
@@ -115,6 +115,7 @@ grpc_closure_scheduler* grpc_schedule_on_exec_ctx = &exec_ctx_scheduler;
115
115
 
116
116
  namespace grpc_core {
117
117
  GPR_TLS_CLASS_DEF(ExecCtx::exec_ctx_);
118
+ GPR_TLS_CLASS_DEF(ApplicationCallbackExecCtx::callback_exec_ctx_);
118
119
 
119
120
  // WARNING: for testing purposes only!
120
121
  void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) {
@@ -21,6 +21,7 @@
21
21
 
22
22
  #include <grpc/support/port_platform.h>
23
23
 
24
+ #include <grpc/impl/codegen/grpc_types.h>
24
25
  #include <grpc/support/atm.h>
25
26
  #include <grpc/support/cpu.h>
26
27
  #include <grpc/support/log.h>
@@ -34,9 +35,8 @@ typedef int64_t grpc_millis;
34
35
  #define GRPC_MILLIS_INF_FUTURE INT64_MAX
35
36
  #define GRPC_MILLIS_INF_PAST INT64_MIN
36
37
 
37
- /** A workqueue represents a list of work to be executed asynchronously.
38
- Forward declared here to avoid a circular dependency with workqueue.h. */
39
- typedef struct grpc_workqueue grpc_workqueue;
38
+ /** A combiner represents a list of work to be executed later.
39
+ Forward declared here to avoid a circular dependency with combiner.h. */
40
40
  typedef struct grpc_combiner grpc_combiner;
41
41
 
42
42
  /* This exec_ctx is ready to return: either pre-populated, or cached as soon as
@@ -49,6 +49,10 @@ typedef struct grpc_combiner grpc_combiner;
49
49
  be counted by fork handlers */
50
50
  #define GRPC_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 4
51
51
 
52
+ /* This application callback exec ctx was initialized by an internal thread, and
53
+ should not be counted by fork handlers */
54
+ #define GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD 1
55
+
52
56
  extern grpc_closure_scheduler* grpc_schedule_on_exec_ctx;
53
57
 
54
58
  gpr_timespec grpc_millis_to_timespec(grpc_millis millis, gpr_clock_type clock);
@@ -58,8 +62,8 @@ grpc_millis grpc_timespec_to_millis_round_up(gpr_timespec timespec);
58
62
  namespace grpc_core {
59
63
  /** Execution context.
60
64
  * A bag of data that collects information along a callstack.
61
- * It is created on the stack at public API entry points, and stored internally
62
- * as a thread-local variable.
65
+ * It is created on the stack at core entry points (public API or iomgr), and
66
+ * stored internally as a thread-local variable.
63
67
  *
64
68
  * Generally, to create an exec_ctx instance, add the following line at the top
65
69
  * of the public API entry point or at the start of a thread's work function :
@@ -70,7 +74,7 @@ namespace grpc_core {
70
74
  * grpc_core::ExecCtx::Get()
71
75
  *
72
76
  * Specific responsibilities (this may grow in the future):
73
- * - track a list of work that needs to be delayed until the top of the
77
+ * - track a list of core work that needs to be delayed until the base of the
74
78
  * call stack (this provides a convenient mechanism to run callbacks
75
79
  * without worrying about locking issues)
76
80
  * - provide a decision maker (via IsReadyToFinish) that provides a
@@ -80,10 +84,19 @@ namespace grpc_core {
80
84
  * CONVENTIONS:
81
85
  * - Instance of this must ALWAYS be constructed on the stack, never
82
86
  * heap allocated.
83
- * - Exactly one instance of ExecCtx must be created per thread. Instances must
84
- * always be called exec_ctx.
85
87
  * - Do not pass exec_ctx as a parameter to a function. Always access it using
86
88
  * grpc_core::ExecCtx::Get().
89
+ * - NOTE: In the future, the convention is likely to change to allow only one
90
+ * ExecCtx on a thread's stack at the same time. The TODO below
91
+ * discusses this plan in more detail.
92
+ *
93
+ * TODO(yashykt): Only allow one "active" ExecCtx on a thread at the same time.
94
+ * Stage 1: If a new one is created on the stack, it should just
95
+ * pass-through to the underlying ExecCtx deeper in the thread's
96
+ * stack.
97
+ * Stage 2: Assert if a 2nd one is ever created on the stack
98
+ * since that implies a core re-entry outside of application
99
+ * callbacks.
87
100
  */
88
101
  class ExecCtx {
89
102
  public:
@@ -226,6 +239,122 @@ class ExecCtx {
226
239
  GPR_TLS_CLASS_DECL(exec_ctx_);
227
240
  ExecCtx* last_exec_ctx_ = Get();
228
241
  };
242
+
243
+ /** Application-callback execution context.
244
+ * A bag of data that collects information along a callstack.
245
+ * It is created on the stack at core entry points, and stored internally
246
+ * as a thread-local variable.
247
+ *
248
+ * There are three key differences between this structure and ExecCtx:
249
+ * 1. ApplicationCallbackExecCtx builds a list of application-level
250
+ * callbacks, but ExecCtx builds a list of internal callbacks to invoke.
251
+ * 2. ApplicationCallbackExecCtx invokes its callbacks only at destruction;
252
+ * there is no explicit Flush method.
253
+ * 3. If more than one ApplicationCallbackExecCtx is created on the thread's
254
+ * stack, only the one closest to the base of the stack is actually
255
+ * active and this is the only one that enqueues application callbacks.
256
+ * (Unlike ExecCtx, it is not feasible to prevent multiple of these on the
257
+ * stack since the executing application callback may itself enter core.
258
+ * However, the new one created will just pass callbacks through to the
259
+ * base one and those will not be executed until the return to the
260
+ * destructor of the base one, preventing unlimited stack growth.)
261
+ *
262
+ * This structure exists because application callbacks may themselves cause a
263
+ * core re-entry (e.g., through a public API call) and if that call in turn
264
+ * causes another application-callback, there could be arbitrarily growing
265
+ * stacks of core re-entries. Instead, any application callbacks instead should
266
+ * not be invoked until other core work is done and other application callbacks
267
+ * have completed. To accomplish this, any application callback should be
268
+ * enqueued using grpc_core::ApplicationCallbackExecCtx::Enqueue .
269
+ *
270
+ * CONVENTIONS:
271
+ * - Instances of this must ALWAYS be constructed on the stack, never
272
+ * heap allocated.
273
+ * - Instances of this are generally constructed before ExecCtx when needed.
274
+ * The only exception is for ExecCtx's that are explicitly flushed and
275
+ * that survive beyond the scope of the function that can cause application
276
+ * callbacks to be invoked (e.g., in the timer thread).
277
+ *
278
+ * Generally, core entry points that may trigger application-level callbacks
279
+ * will have the following declarations:
280
+ *
281
+ * grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
282
+ * grpc_core::ExecCtx exec_ctx;
283
+ *
284
+ * This ordering is important to make sure that the ApplicationCallbackExecCtx
285
+ * is destroyed after the ExecCtx (to prevent the re-entry problem described
286
+ * above, as well as making sure that ExecCtx core callbacks are invoked first)
287
+ *
288
+ */
289
+
290
+ class ApplicationCallbackExecCtx {
291
+ public:
292
+ /** Default Constructor */
293
+ ApplicationCallbackExecCtx() { Set(this, flags_); }
294
+
295
+ /** Parameterised Constructor */
296
+ ApplicationCallbackExecCtx(uintptr_t fl) : flags_(fl) { Set(this, flags_); }
297
+
298
+ ~ApplicationCallbackExecCtx() {
299
+ if (reinterpret_cast<ApplicationCallbackExecCtx*>(
300
+ gpr_tls_get(&callback_exec_ctx_)) == this) {
301
+ while (head_ != nullptr) {
302
+ auto* f = head_;
303
+ head_ = f->internal_next;
304
+ if (f->internal_next == nullptr) {
305
+ tail_ = nullptr;
306
+ }
307
+ (*f->functor_run)(f, f->internal_success);
308
+ }
309
+ gpr_tls_set(&callback_exec_ctx_, reinterpret_cast<intptr_t>(nullptr));
310
+ if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags_)) {
311
+ grpc_core::Fork::DecExecCtxCount();
312
+ }
313
+ } else {
314
+ GPR_DEBUG_ASSERT(head_ == nullptr);
315
+ GPR_DEBUG_ASSERT(tail_ == nullptr);
316
+ }
317
+ }
318
+
319
+ static void Set(ApplicationCallbackExecCtx* exec_ctx, uintptr_t flags) {
320
+ if (reinterpret_cast<ApplicationCallbackExecCtx*>(
321
+ gpr_tls_get(&callback_exec_ctx_)) == nullptr) {
322
+ if (!(GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD & flags)) {
323
+ grpc_core::Fork::IncExecCtxCount();
324
+ }
325
+ gpr_tls_set(&callback_exec_ctx_, reinterpret_cast<intptr_t>(exec_ctx));
326
+ }
327
+ }
328
+
329
+ static void Enqueue(grpc_experimental_completion_queue_functor* functor,
330
+ int is_success) {
331
+ functor->internal_success = is_success;
332
+ functor->internal_next = nullptr;
333
+
334
+ auto* ctx = reinterpret_cast<ApplicationCallbackExecCtx*>(
335
+ gpr_tls_get(&callback_exec_ctx_));
336
+
337
+ if (ctx->head_ == nullptr) {
338
+ ctx->head_ = functor;
339
+ }
340
+ if (ctx->tail_ != nullptr) {
341
+ ctx->tail_->internal_next = functor;
342
+ }
343
+ ctx->tail_ = functor;
344
+ }
345
+
346
+ /** Global initialization for ApplicationCallbackExecCtx. Called by init. */
347
+ static void GlobalInit(void) { gpr_tls_init(&callback_exec_ctx_); }
348
+
349
+ /** Global shutdown for ApplicationCallbackExecCtx. Called by init. */
350
+ static void GlobalShutdown(void) { gpr_tls_destroy(&callback_exec_ctx_); }
351
+
352
+ private:
353
+ uintptr_t flags_{0u};
354
+ grpc_experimental_completion_queue_functor* head_{nullptr};
355
+ grpc_experimental_completion_queue_functor* tail_{nullptr};
356
+ GPR_TLS_CLASS_DECL(callback_exec_ctx_);
357
+ };
229
358
  } // namespace grpc_core
230
359
 
231
360
  #endif /* GRPC_CORE_LIB_IOMGR_EXEC_CTX_H */
@@ -45,22 +45,80 @@
45
45
  gpr_log(GPR_INFO, "EXECUTOR " str); \
46
46
  }
47
47
 
48
- grpc_core::TraceFlag executor_trace(false, "executor");
48
+ namespace grpc_core {
49
+ namespace {
49
50
 
50
51
  GPR_TLS_DECL(g_this_thread_state);
51
52
 
52
- GrpcExecutor::GrpcExecutor(const char* name) : name_(name) {
53
+ Executor* executors[static_cast<size_t>(ExecutorType::NUM_EXECUTORS)];
54
+
55
+ void default_enqueue_short(grpc_closure* closure, grpc_error* error) {
56
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)]->Enqueue(
57
+ closure, error, true /* is_short */);
58
+ }
59
+
60
+ void default_enqueue_long(grpc_closure* closure, grpc_error* error) {
61
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)]->Enqueue(
62
+ closure, error, false /* is_short */);
63
+ }
64
+
65
+ void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) {
66
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)]->Enqueue(
67
+ closure, error, true /* is_short */);
68
+ }
69
+
70
+ void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) {
71
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)]->Enqueue(
72
+ closure, error, false /* is_short */);
73
+ }
74
+
75
+ const grpc_closure_scheduler_vtable
76
+ vtables_[static_cast<size_t>(ExecutorType::NUM_EXECUTORS)]
77
+ [static_cast<size_t>(ExecutorJobType::NUM_JOB_TYPES)] = {
78
+ {{&default_enqueue_short, &default_enqueue_short,
79
+ "def-ex-short"},
80
+ {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}},
81
+ {{&resolver_enqueue_short, &resolver_enqueue_short,
82
+ "res-ex-short"},
83
+ {&resolver_enqueue_long, &resolver_enqueue_long,
84
+ "res-ex-long"}}};
85
+
86
+ grpc_closure_scheduler
87
+ schedulers_[static_cast<size_t>(ExecutorType::NUM_EXECUTORS)]
88
+ [static_cast<size_t>(ExecutorJobType::NUM_JOB_TYPES)] = {
89
+ {{&vtables_[static_cast<size_t>(ExecutorType::DEFAULT)]
90
+ [static_cast<size_t>(ExecutorJobType::SHORT)]},
91
+ {&vtables_[static_cast<size_t>(ExecutorType::DEFAULT)]
92
+ [static_cast<size_t>(ExecutorJobType::LONG)]}},
93
+ {{&vtables_[static_cast<size_t>(ExecutorType::RESOLVER)]
94
+ [static_cast<size_t>(ExecutorJobType::SHORT)]},
95
+ {&vtables_[static_cast<size_t>(ExecutorType::RESOLVER)]
96
+ [static_cast<size_t>(ExecutorJobType::LONG)]}}};
97
+
98
+ } // namespace
99
+
100
+ TraceFlag executor_trace(false, "executor");
101
+
102
+ Executor::Executor(const char* name) : name_(name) {
53
103
  adding_thread_lock_ = GPR_SPINLOCK_STATIC_INITIALIZER;
54
104
  gpr_atm_rel_store(&num_threads_, 0);
55
105
  max_threads_ = GPR_MAX(1, 2 * gpr_cpu_num_cores());
56
106
  }
57
107
 
58
- void GrpcExecutor::Init() { SetThreading(true); }
108
+ void Executor::Init() { SetThreading(true); }
59
109
 
60
- size_t GrpcExecutor::RunClosures(const char* executor_name,
61
- grpc_closure_list list) {
110
+ size_t Executor::RunClosures(const char* executor_name,
111
+ grpc_closure_list list) {
62
112
  size_t n = 0;
63
113
 
114
+ // In the executor, the ExecCtx for the thread is declared in the executor
115
+ // thread itself, but this is the point where we could start seeing
116
+ // application-level callbacks. No need to create a new ExecCtx, though,
117
+ // since there already is one and it is flushed (but not destructed) in this
118
+ // function itself.
119
+ grpc_core::ApplicationCallbackExecCtx callback_exec_ctx(
120
+ GRPC_APP_CALLBACK_EXEC_CTX_FLAG_IS_INTERNAL_THREAD);
121
+
64
122
  grpc_closure* c = list.head;
65
123
  while (c != nullptr) {
66
124
  grpc_closure* next = c->next_data.next;
@@ -82,11 +140,11 @@ size_t GrpcExecutor::RunClosures(const char* executor_name,
82
140
  return n;
83
141
  }
84
142
 
85
- bool GrpcExecutor::IsThreaded() const {
143
+ bool Executor::IsThreaded() const {
86
144
  return gpr_atm_acq_load(&num_threads_) > 0;
87
145
  }
88
146
 
89
- void GrpcExecutor::SetThreading(bool threading) {
147
+ void Executor::SetThreading(bool threading) {
90
148
  gpr_atm curr_num_threads = gpr_atm_acq_load(&num_threads_);
91
149
  EXECUTOR_TRACE("(%s) SetThreading(%d) begin", name_, threading);
92
150
 
@@ -112,7 +170,7 @@ void GrpcExecutor::SetThreading(bool threading) {
112
170
  }
113
171
 
114
172
  thd_state_[0].thd =
115
- grpc_core::Thread(name_, &GrpcExecutor::ThreadMain, &thd_state_[0]);
173
+ grpc_core::Thread(name_, &Executor::ThreadMain, &thd_state_[0]);
116
174
  thd_state_[0].thd.Start();
117
175
  } else { // !threading
118
176
  if (curr_num_threads == 0) {
@@ -153,9 +211,9 @@ void GrpcExecutor::SetThreading(bool threading) {
153
211
  EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading);
154
212
  }
155
213
 
156
- void GrpcExecutor::Shutdown() { SetThreading(false); }
214
+ void Executor::Shutdown() { SetThreading(false); }
157
215
 
158
- void GrpcExecutor::ThreadMain(void* arg) {
216
+ void Executor::ThreadMain(void* arg) {
159
217
  ThreadState* ts = static_cast<ThreadState*>(arg);
160
218
  gpr_tls_set(&g_this_thread_state, reinterpret_cast<intptr_t>(ts));
161
219
 
@@ -192,8 +250,8 @@ void GrpcExecutor::ThreadMain(void* arg) {
192
250
  }
193
251
  }
194
252
 
195
- void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
196
- bool is_short) {
253
+ void Executor::Enqueue(grpc_closure* closure, grpc_error* error,
254
+ bool is_short) {
197
255
  bool retry_push;
198
256
  if (is_short) {
199
257
  GRPC_STATS_INC_EXECUTOR_SCHEDULED_SHORT_ITEMS();
@@ -304,7 +362,7 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
304
362
  gpr_atm_rel_store(&num_threads_, cur_thread_count + 1);
305
363
 
306
364
  thd_state_[cur_thread_count].thd = grpc_core::Thread(
307
- name_, &GrpcExecutor::ThreadMain, &thd_state_[cur_thread_count]);
365
+ name_, &Executor::ThreadMain, &thd_state_[cur_thread_count]);
308
366
  thd_state_[cur_thread_count].thd.Start();
309
367
  }
310
368
  gpr_spinlock_unlock(&adding_thread_lock_);
@@ -316,85 +374,52 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
316
374
  } while (retry_push);
317
375
  }
318
376
 
319
- static GrpcExecutor* executors[GRPC_NUM_EXECUTORS];
320
-
321
- void default_enqueue_short(grpc_closure* closure, grpc_error* error) {
322
- executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error,
323
- true /* is_short */);
324
- }
325
-
326
- void default_enqueue_long(grpc_closure* closure, grpc_error* error) {
327
- executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error,
328
- false /* is_short */);
329
- }
330
-
331
- void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) {
332
- executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error,
333
- true /* is_short */);
334
- }
335
-
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]}}};
354
-
355
- // grpc_executor_init() and grpc_executor_shutdown() functions are called in the
377
+ // Executor::InitAll() and Executor::ShutdownAll() functions are called in the
356
378
  // the grpc_init() and grpc_shutdown() code paths which are protected by a
357
379
  // global mutex. So it is okay to assume that these functions are thread-safe
358
- void grpc_executor_init() {
359
- EXECUTOR_TRACE0("grpc_executor_init() enter");
380
+ void Executor::InitAll() {
381
+ EXECUTOR_TRACE0("Executor::InitAll() enter");
360
382
 
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);
383
+ // Return if Executor::InitAll() is already called earlier
384
+ if (executors[static_cast<size_t>(ExecutorType::DEFAULT)] != nullptr) {
385
+ GPR_ASSERT(executors[static_cast<size_t>(ExecutorType::RESOLVER)] !=
386
+ nullptr);
364
387
  return;
365
388
  }
366
389
 
367
- executors[GRPC_DEFAULT_EXECUTOR] =
368
- grpc_core::New<GrpcExecutor>("default-executor");
369
- executors[GRPC_RESOLVER_EXECUTOR] =
370
- grpc_core::New<GrpcExecutor>("resolver-executor");
390
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)] =
391
+ grpc_core::New<Executor>("default-executor");
392
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)] =
393
+ grpc_core::New<Executor>("resolver-executor");
371
394
 
372
- executors[GRPC_DEFAULT_EXECUTOR]->Init();
373
- executors[GRPC_RESOLVER_EXECUTOR]->Init();
395
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)]->Init();
396
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)]->Init();
374
397
 
375
- EXECUTOR_TRACE0("grpc_executor_init() done");
398
+ EXECUTOR_TRACE0("Executor::InitAll() done");
376
399
  }
377
400
 
378
- grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type,
379
- GrpcExecutorJobType job_type) {
380
- return &schedulers_[executor_type][job_type];
401
+ grpc_closure_scheduler* Executor::Scheduler(ExecutorType executor_type,
402
+ ExecutorJobType job_type) {
403
+ return &schedulers_[static_cast<size_t>(executor_type)]
404
+ [static_cast<size_t>(job_type)];
381
405
  }
382
406
 
383
- grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) {
384
- return grpc_executor_scheduler(GRPC_DEFAULT_EXECUTOR, job_type);
407
+ grpc_closure_scheduler* Executor::Scheduler(ExecutorJobType job_type) {
408
+ return Executor::Scheduler(ExecutorType::DEFAULT, job_type);
385
409
  }
386
410
 
387
- void grpc_executor_shutdown() {
388
- EXECUTOR_TRACE0("grpc_executor_shutdown() enter");
411
+ void Executor::ShutdownAll() {
412
+ EXECUTOR_TRACE0("Executor::ShutdownAll() enter");
389
413
 
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);
414
+ // Return if Executor:SshutdownAll() is already called earlier
415
+ if (executors[static_cast<size_t>(ExecutorType::DEFAULT)] == nullptr) {
416
+ GPR_ASSERT(executors[static_cast<size_t>(ExecutorType::RESOLVER)] ==
417
+ nullptr);
393
418
  return;
394
419
  }
395
420
 
396
- executors[GRPC_DEFAULT_EXECUTOR]->Shutdown();
397
- executors[GRPC_RESOLVER_EXECUTOR]->Shutdown();
421
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)]->Shutdown();
422
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)]->Shutdown();
398
423
 
399
424
  // Delete the executor objects.
400
425
  //
@@ -408,26 +433,36 @@ void grpc_executor_shutdown() {
408
433
  // By ensuring that all executors are shutdown first, we are also ensuring
409
434
  // that no thread is active across all executors.
410
435
 
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;
436
+ grpc_core::Delete<Executor>(
437
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)]);
438
+ grpc_core::Delete<Executor>(
439
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)]);
440
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)] = nullptr;
441
+ executors[static_cast<size_t>(ExecutorType::RESOLVER)] = nullptr;
415
442
 
416
- EXECUTOR_TRACE0("grpc_executor_shutdown() done");
443
+ EXECUTOR_TRACE0("Executor::ShutdownAll() done");
417
444
  }
418
445
 
419
- bool grpc_executor_is_threaded(GrpcExecutorType executor_type) {
420
- GPR_ASSERT(executor_type < GRPC_NUM_EXECUTORS);
421
- return executors[executor_type]->IsThreaded();
446
+ bool Executor::IsThreaded(ExecutorType executor_type) {
447
+ GPR_ASSERT(executor_type < ExecutorType::NUM_EXECUTORS);
448
+ return executors[static_cast<size_t>(executor_type)]->IsThreaded();
422
449
  }
423
450
 
424
- bool grpc_executor_is_threaded() {
425
- return grpc_executor_is_threaded(GRPC_DEFAULT_EXECUTOR);
451
+ bool Executor::IsThreadedDefault() {
452
+ return Executor::IsThreaded(ExecutorType::DEFAULT);
426
453
  }
427
454
 
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++) {
455
+ void Executor::SetThreadingAll(bool enable) {
456
+ EXECUTOR_TRACE("Executor::SetThreadingAll(%d) called", enable);
457
+ for (size_t i = 0; i < static_cast<size_t>(ExecutorType::NUM_EXECUTORS);
458
+ i++) {
431
459
  executors[i]->SetThreading(enable);
432
460
  }
433
461
  }
462
+
463
+ void Executor::SetThreadingDefault(bool enable) {
464
+ EXECUTOR_TRACE("Executor::SetThreadingDefault(%d) called", enable);
465
+ executors[static_cast<size_t>(ExecutorType::DEFAULT)]->SetThreading(enable);
466
+ }
467
+
468
+ } // namespace grpc_core