grpc 1.1.2 → 1.2.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +1257 -404
  3. data/etc/roots.pem +189 -102
  4. data/include/grpc/census.h +7 -7
  5. data/include/grpc/compression.h +4 -4
  6. data/include/grpc/grpc.h +13 -7
  7. data/include/grpc/impl/codegen/atm_gcc_atomic.h +26 -9
  8. data/include/grpc/impl/codegen/grpc_types.h +39 -30
  9. data/include/grpc/impl/codegen/slice.h +24 -6
  10. data/include/grpc/impl/codegen/sync.h +8 -0
  11. data/include/grpc/load_reporting.h +63 -0
  12. data/include/grpc/slice.h +37 -1
  13. data/include/grpc/slice_buffer.h +7 -0
  14. data/include/grpc/support/alloc.h +3 -0
  15. data/include/grpc/support/useful.h +3 -0
  16. data/src/core/ext/census/gen/census.pb.h +1 -1
  17. data/src/core/ext/census/gen/trace_context.pb.c +9 -36
  18. data/src/core/ext/census/gen/trace_context.pb.h +20 -26
  19. data/src/core/ext/census/grpc_filter.c +3 -5
  20. data/src/core/ext/census/trace_context.c +1 -1
  21. data/src/core/ext/census/trace_context.h +3 -0
  22. data/src/core/ext/census/trace_label.h +61 -0
  23. data/src/core/ext/census/trace_propagation.h +63 -0
  24. data/src/core/ext/census/trace_status.h +45 -0
  25. data/src/core/ext/census/trace_string.h +50 -0
  26. data/src/core/ext/census/tracing.c +31 -11
  27. data/src/core/ext/census/tracing.h +124 -0
  28. data/src/core/ext/client_channel/client_channel.c +456 -368
  29. data/src/core/ext/client_channel/client_channel.h +4 -0
  30. data/src/core/ext/client_channel/client_channel_plugin.c +6 -1
  31. data/src/core/ext/client_channel/connector.c +3 -3
  32. data/src/core/ext/client_channel/connector.h +4 -3
  33. data/src/core/ext/client_channel/http_connect_handshaker.c +62 -72
  34. data/src/core/ext/client_channel/http_connect_handshaker.h +7 -10
  35. data/src/core/ext/client_channel/http_proxy.c +125 -0
  36. data/src/core/ext/client_channel/http_proxy.h +39 -0
  37. data/src/core/ext/client_channel/lb_policy.c +56 -35
  38. data/src/core/ext/client_channel/lb_policy.h +46 -39
  39. data/src/core/ext/client_channel/lb_policy_factory.h +1 -0
  40. data/src/core/ext/client_channel/parse_address.c +32 -6
  41. data/src/core/ext/client_channel/proxy_mapper.c +63 -0
  42. data/src/core/ext/client_channel/proxy_mapper.h +89 -0
  43. data/src/core/ext/client_channel/proxy_mapper_registry.c +133 -0
  44. data/src/core/ext/client_channel/proxy_mapper_registry.h +59 -0
  45. data/src/core/ext/client_channel/resolver.c +16 -9
  46. data/src/core/ext/client_channel/resolver.h +23 -12
  47. data/src/core/ext/client_channel/resolver_factory.h +1 -0
  48. data/src/core/ext/client_channel/resolver_registry.c +15 -11
  49. data/src/core/ext/client_channel/resolver_registry.h +5 -3
  50. data/src/core/ext/client_channel/subchannel.c +44 -27
  51. data/src/core/ext/client_channel/subchannel.h +6 -2
  52. data/src/core/ext/client_channel/uri_parser.c +26 -14
  53. data/src/core/ext/client_channel/uri_parser.h +3 -1
  54. data/src/core/ext/lb_policy/grpclb/grpclb.c +220 -209
  55. data/src/core/ext/lb_policy/grpclb/grpclb_channel.h +56 -0
  56. data/src/core/ext/lb_policy/grpclb/grpclb_channel_secure.c +107 -0
  57. data/src/core/ext/lb_policy/grpclb/load_balancer_api.c +3 -6
  58. data/src/core/ext/lb_policy/pick_first/pick_first.c +71 -116
  59. data/src/core/ext/lb_policy/round_robin/round_robin.c +52 -67
  60. data/src/core/ext/load_reporting/load_reporting.c +20 -0
  61. data/src/core/ext/load_reporting/load_reporting.h +1 -16
  62. data/src/core/ext/load_reporting/load_reporting_filter.c +28 -54
  63. data/src/core/ext/resolver/dns/native/dns_resolver.c +31 -45
  64. data/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +20 -29
  65. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +11 -8
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +11 -2
  67. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +143 -46
  68. data/src/core/ext/transport/chttp2/server/chttp2_server.c +12 -50
  69. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +1 -1
  70. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +1 -1
  71. data/src/core/ext/transport/chttp2/transport/bin_decoder.c +7 -7
  72. data/src/core/ext/transport/chttp2/transport/bin_encoder.c +1 -2
  73. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -2
  74. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +0 -3
  75. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +606 -374
  76. data/src/core/ext/transport/chttp2/transport/frame_ping.c +17 -5
  77. data/src/core/ext/transport/chttp2/transport/frame_ping.h +2 -2
  78. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +9 -13
  79. data/src/core/ext/transport/chttp2/transport/frame_settings.c +12 -11
  80. data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -1
  81. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +5 -6
  82. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +100 -53
  83. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +2 -2
  84. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +126 -70
  85. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +13 -7
  86. data/src/core/ext/transport/chttp2/transport/hpack_table.c +22 -19
  87. data/src/core/ext/transport/chttp2/transport/hpack_table.h +6 -6
  88. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +23 -11
  89. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +6 -2
  90. data/src/core/ext/transport/chttp2/transport/internal.h +169 -42
  91. data/src/core/ext/transport/chttp2/transport/parsing.c +98 -41
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.c +29 -14
  93. data/src/core/ext/transport/chttp2/transport/writing.c +137 -15
  94. data/src/core/lib/channel/channel_stack.c +14 -44
  95. data/src/core/lib/channel/channel_stack.h +10 -17
  96. data/src/core/lib/channel/channel_stack_builder.c +2 -3
  97. data/src/core/lib/channel/compress_filter.c +54 -46
  98. data/src/core/lib/channel/connected_channel.c +4 -4
  99. data/src/core/lib/channel/connected_channel.h +5 -0
  100. data/src/core/lib/channel/context.h +3 -0
  101. data/src/core/lib/channel/deadline_filter.c +61 -61
  102. data/src/core/lib/channel/deadline_filter.h +8 -5
  103. data/src/core/lib/channel/handshaker.c +47 -7
  104. data/src/core/lib/channel/handshaker.h +21 -3
  105. data/src/core/lib/channel/http_client_filter.c +149 -99
  106. data/src/core/lib/channel/http_server_filter.c +163 -147
  107. data/src/core/lib/channel/message_size_filter.c +15 -10
  108. data/src/core/lib/compression/algorithm_metadata.h +4 -4
  109. data/src/core/lib/compression/compression.c +17 -23
  110. data/src/core/lib/http/httpcli.c +3 -2
  111. data/src/core/lib/http/httpcli.h +2 -1
  112. data/src/core/lib/http/httpcli_security_connector.c +2 -3
  113. data/src/core/lib/http/parser.c +2 -2
  114. data/src/core/lib/iomgr/closure.c +6 -3
  115. data/src/core/lib/iomgr/closure.h +4 -2
  116. data/src/core/lib/iomgr/combiner.c +35 -5
  117. data/src/core/lib/iomgr/combiner.h +21 -2
  118. data/src/core/lib/iomgr/endpoint.c +3 -2
  119. data/src/core/lib/iomgr/endpoint.h +3 -2
  120. data/src/core/lib/iomgr/error.c +60 -94
  121. data/src/core/lib/iomgr/error.h +7 -10
  122. data/src/core/lib/iomgr/error_internal.h +54 -0
  123. data/src/core/lib/iomgr/ev_epoll_linux.c +253 -109
  124. data/src/core/lib/iomgr/ev_poll_posix.c +61 -29
  125. data/src/core/lib/iomgr/ev_posix.c +7 -8
  126. data/src/core/lib/iomgr/ev_posix.h +4 -4
  127. data/src/core/lib/iomgr/exec_ctx.c +11 -6
  128. data/src/core/lib/iomgr/exec_ctx.h +11 -14
  129. data/src/core/lib/iomgr/executor.c +2 -2
  130. data/src/core/lib/iomgr/load_file.c +1 -1
  131. data/src/core/lib/iomgr/network_status_tracker.c +5 -81
  132. data/src/core/lib/iomgr/pollset.h +1 -3
  133. data/src/core/lib/iomgr/pollset_set.h +2 -1
  134. data/src/core/lib/iomgr/pollset_set_uv.c +2 -1
  135. data/src/core/lib/iomgr/pollset_set_windows.c +2 -1
  136. data/src/core/lib/iomgr/pollset_uv.c +25 -11
  137. data/src/core/lib/iomgr/pollset_windows.c +0 -11
  138. data/src/core/lib/iomgr/resolve_address_uv.c +50 -2
  139. data/src/core/lib/iomgr/resource_quota.c +41 -11
  140. data/src/core/lib/iomgr/resource_quota.h +6 -0
  141. data/src/core/lib/iomgr/sockaddr_utils.c +33 -17
  142. data/src/core/lib/iomgr/sockaddr_utils.h +4 -0
  143. data/src/core/lib/iomgr/tcp_client_posix.c +2 -3
  144. data/src/core/lib/iomgr/tcp_client_uv.c +1 -3
  145. data/src/core/lib/iomgr/tcp_client_windows.c +21 -6
  146. data/src/core/lib/iomgr/tcp_posix.c +4 -5
  147. data/src/core/lib/iomgr/tcp_server_posix.c +269 -94
  148. data/src/core/lib/iomgr/tcp_server_windows.c +1 -1
  149. data/src/core/lib/iomgr/tcp_uv.c +11 -5
  150. data/src/core/lib/iomgr/tcp_windows.c +20 -7
  151. data/src/core/lib/iomgr/timer_generic.c +15 -22
  152. data/src/core/lib/iomgr/timer_generic.h +1 -1
  153. data/src/core/lib/iomgr/timer_uv.c +10 -6
  154. data/src/core/lib/iomgr/timer_uv.h +1 -1
  155. data/src/core/lib/iomgr/udp_server.c +45 -6
  156. data/src/core/lib/iomgr/udp_server.h +7 -1
  157. data/src/core/lib/iomgr/unix_sockets_posix.c +11 -1
  158. data/src/core/lib/json/json.c +1 -2
  159. data/src/core/lib/profiling/basic_timers.c +17 -3
  160. data/src/core/lib/security/context/security_context.c +3 -10
  161. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -8
  162. data/src/core/lib/security/credentials/credentials.c +48 -2
  163. data/src/core/lib/security/credentials/credentials.h +13 -0
  164. data/src/core/lib/security/credentials/credentials_metadata.c +1 -2
  165. data/src/core/lib/security/credentials/fake/fake_credentials.c +6 -8
  166. data/src/core/lib/security/credentials/fake/fake_credentials.h +15 -0
  167. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +3 -3
  168. data/src/core/lib/security/credentials/iam/iam_credentials.c +1 -2
  169. data/src/core/lib/security/credentials/jwt/jwt_credentials.c +1 -2
  170. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +5 -8
  171. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
  172. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +3 -5
  173. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +15 -13
  174. data/src/core/lib/security/credentials/ssl/ssl_credentials.c +2 -4
  175. data/src/core/lib/security/transport/client_auth_filter.c +72 -47
  176. data/src/core/lib/security/transport/lb_targets_info.c +70 -0
  177. data/src/core/lib/security/transport/lb_targets_info.h +47 -0
  178. data/src/core/lib/security/transport/secure_endpoint.c +3 -3
  179. data/src/core/lib/security/transport/security_connector.c +125 -28
  180. data/src/core/lib/security/transport/security_connector.h +4 -3
  181. data/src/core/lib/security/transport/security_handshaker.c +13 -9
  182. data/src/core/lib/security/transport/server_auth_filter.c +31 -40
  183. data/src/core/lib/security/util/b64.c +1 -1
  184. data/src/core/lib/slice/slice.c +110 -20
  185. data/src/core/lib/slice/slice_buffer.c +92 -39
  186. data/src/core/lib/{transport/mdstr_hash_table.c → slice/slice_hash_table.c} +40 -33
  187. data/src/core/lib/{transport/mdstr_hash_table.h → slice/slice_hash_table.h} +21 -21
  188. data/src/core/lib/slice/slice_intern.c +346 -0
  189. data/src/core/lib/slice/slice_internal.h +15 -0
  190. data/src/core/lib/slice/slice_string_helpers.c +5 -0
  191. data/src/core/lib/slice/slice_string_helpers.h +5 -0
  192. data/src/core/lib/support/alloc.c +26 -1
  193. data/src/core/lib/support/cmdline.c +2 -4
  194. data/src/core/lib/support/cpu_posix.c +2 -7
  195. data/src/core/lib/support/histogram.c +1 -2
  196. data/src/core/lib/support/log_posix.c +8 -4
  197. data/src/core/lib/support/spinlock.h +52 -0
  198. data/src/core/lib/support/subprocess_posix.c +1 -2
  199. data/src/core/lib/support/sync.c +7 -1
  200. data/src/core/lib/support/sync_posix.c +9 -0
  201. data/src/core/lib/support/time_windows.c +7 -1
  202. data/src/core/lib/surface/call.c +647 -629
  203. data/src/core/lib/surface/call.h +4 -1
  204. data/src/core/lib/surface/call_details.c +8 -2
  205. data/src/core/lib/surface/call_log_batch.c +17 -6
  206. data/src/core/lib/surface/channel.c +49 -59
  207. data/src/core/lib/surface/channel.h +5 -6
  208. data/src/core/lib/surface/completion_queue.c +16 -45
  209. data/src/core/lib/surface/completion_queue.h +0 -3
  210. data/src/core/lib/surface/init.c +6 -2
  211. data/src/core/lib/surface/init_secure.c +1 -1
  212. data/src/core/lib/surface/lame_client.c +14 -4
  213. data/src/core/lib/surface/server.c +79 -82
  214. data/src/core/lib/surface/validate_metadata.c +46 -15
  215. data/src/core/lib/surface/validate_metadata.h +43 -0
  216. data/src/core/lib/surface/version.c +2 -2
  217. data/src/core/lib/transport/bdp_estimator.c +104 -0
  218. data/src/core/lib/transport/bdp_estimator.h +76 -0
  219. data/src/core/lib/transport/connectivity_state.c +33 -13
  220. data/src/core/lib/transport/connectivity_state.h +15 -5
  221. data/src/core/lib/transport/error_utils.c +124 -0
  222. data/src/core/lib/transport/error_utils.h +56 -0
  223. data/src/core/{ext/transport/chttp2 → lib}/transport/http2_errors.h +18 -18
  224. data/src/core/lib/transport/metadata.c +259 -503
  225. data/src/core/lib/transport/metadata.h +69 -68
  226. data/src/core/lib/transport/metadata_batch.c +183 -63
  227. data/src/core/lib/transport/metadata_batch.h +50 -26
  228. data/src/core/lib/transport/pid_controller.c +28 -8
  229. data/src/core/lib/transport/pid_controller.h +15 -2
  230. data/src/core/lib/transport/service_config.c +21 -18
  231. data/src/core/lib/transport/service_config.h +5 -5
  232. data/src/core/lib/transport/static_metadata.c +753 -112
  233. data/src/core/lib/transport/static_metadata.h +403 -264
  234. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.c +18 -20
  235. data/src/core/{ext/transport/chttp2 → lib}/transport/status_conversion.h +9 -10
  236. data/src/core/lib/transport/timeout_encoding.c +11 -9
  237. data/src/core/lib/transport/timeout_encoding.h +3 -1
  238. data/src/core/lib/transport/transport.c +47 -87
  239. data/src/core/lib/transport/transport.h +20 -25
  240. data/src/core/lib/transport/transport_op_string.c +7 -19
  241. data/src/core/lib/tsi/fake_transport_security.c +2 -4
  242. data/src/core/lib/tsi/ssl_transport_security.c +7 -16
  243. data/src/core/lib/tsi/transport_security.c +2 -4
  244. data/src/ruby/ext/grpc/extconf.rb +4 -1
  245. data/src/ruby/ext/grpc/rb_byte_buffer.c +7 -0
  246. data/src/ruby/ext/grpc/rb_byte_buffer.h +3 -0
  247. data/src/ruby/ext/grpc/rb_call.c +47 -46
  248. data/src/ruby/ext/grpc/rb_channel.c +21 -6
  249. data/src/ruby/ext/grpc/rb_compression_options.c +9 -6
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +36 -2
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +59 -8
  252. data/src/ruby/ext/grpc/rb_server.c +6 -4
  253. data/src/ruby/lib/grpc/generic/client_stub.rb +1 -1
  254. data/src/ruby/lib/grpc/version.rb +1 -1
  255. metadata +33 -9
@@ -82,6 +82,7 @@ struct grpc_fd {
82
82
  int shutdown;
83
83
  int closed;
84
84
  int released;
85
+ grpc_error *shutdown_error;
85
86
 
86
87
  /* The watcher list.
87
88
 
@@ -148,7 +149,7 @@ static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec,
148
149
  static bool fd_is_orphaned(grpc_fd *fd);
149
150
 
150
151
  /* Reference counting for fds */
151
- /*#define GRPC_FD_REF_COUNT_DEBUG*/
152
+ //#define GRPC_FD_REF_COUNT_DEBUG
152
153
  #ifdef GRPC_FD_REF_COUNT_DEBUG
153
154
  static void fd_ref(grpc_fd *fd, const char *reason, const char *file, int line);
154
155
  static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
@@ -190,6 +191,7 @@ struct grpc_pollset {
190
191
  int kicked_without_pollers;
191
192
  grpc_closure *shutdown_done;
192
193
  grpc_closure_list idle_jobs;
194
+ int pollset_set_count;
193
195
  /* all polled fds */
194
196
  size_t fd_count;
195
197
  size_t fd_capacity;
@@ -227,7 +229,7 @@ static grpc_error *pollset_kick_ext(grpc_pollset *p,
227
229
 
228
230
  /* Return 1 if the pollset has active threads in pollset_work (pollset must
229
231
  * be locked) */
230
- static int pollset_has_workers(grpc_pollset *pollset);
232
+ static bool pollset_has_workers(grpc_pollset *pollset);
231
233
 
232
234
  /*******************************************************************************
233
235
  * pollset_set definitions
@@ -281,8 +283,8 @@ cv_fd_table g_cvfds;
281
283
  static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file,
282
284
  int line) {
283
285
  gpr_log(GPR_DEBUG, "FD %d %p ref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
284
- gpr_atm_no_barrier_load(&fd->refst),
285
- gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
286
+ (int)gpr_atm_no_barrier_load(&fd->refst),
287
+ (int)gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
286
288
  #else
287
289
  #define REF_BY(fd, n, reason) ref_by(fd, n)
288
290
  #define UNREF_BY(fd, n, reason) unref_by(fd, n)
@@ -296,8 +298,8 @@ static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file,
296
298
  int line) {
297
299
  gpr_atm old;
298
300
  gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
299
- gpr_atm_no_barrier_load(&fd->refst),
300
- gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
301
+ (int)gpr_atm_no_barrier_load(&fd->refst),
302
+ (int)gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
301
303
  #else
302
304
  static void unref_by(grpc_fd *fd, int n) {
303
305
  gpr_atm old;
@@ -306,6 +308,7 @@ static void unref_by(grpc_fd *fd, int n) {
306
308
  if (old == n) {
307
309
  gpr_mu_destroy(&fd->mu);
308
310
  grpc_iomgr_unregister_object(&fd->iomgr_object);
311
+ if (fd->shutdown) GRPC_ERROR_UNREF(fd->shutdown_error);
309
312
  gpr_free(fd);
310
313
  } else {
311
314
  GPR_ASSERT(old > n);
@@ -444,11 +447,11 @@ static void fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
444
447
  static void fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
445
448
  #endif
446
449
 
447
- static grpc_error *fd_shutdown_error(bool shutdown) {
448
- if (!shutdown) {
450
+ static grpc_error *fd_shutdown_error(grpc_fd *fd) {
451
+ if (!fd->shutdown) {
449
452
  return GRPC_ERROR_NONE;
450
453
  } else {
451
- return GRPC_ERROR_CREATE("FD shutdown");
454
+ return GRPC_ERROR_CREATE_REFERENCING("FD shutdown", &fd->shutdown_error, 1);
452
455
  }
453
456
  }
454
457
 
@@ -462,7 +465,7 @@ static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
462
465
  } else if (*st == CLOSURE_READY) {
463
466
  /* already ready ==> queue the closure to run immediately */
464
467
  *st = CLOSURE_NOT_READY;
465
- grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd->shutdown));
468
+ grpc_closure_sched(exec_ctx, closure, fd_shutdown_error(fd));
466
469
  maybe_wake_one_watcher_locked(fd);
467
470
  } else {
468
471
  /* upcallptr was set to a different closure. This is an error! */
@@ -485,7 +488,7 @@ static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
485
488
  return 0;
486
489
  } else {
487
490
  /* waiting ==> queue closure */
488
- grpc_closure_sched(exec_ctx, *st, fd_shutdown_error(fd->shutdown));
491
+ grpc_closure_sched(exec_ctx, *st, fd_shutdown_error(fd));
489
492
  *st = CLOSURE_NOT_READY;
490
493
  return 1;
491
494
  }
@@ -496,15 +499,18 @@ static void set_read_notifier_pollset_locked(
496
499
  fd->read_notifier_pollset = read_notifier_pollset;
497
500
  }
498
501
 
499
- static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
502
+ static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why) {
500
503
  gpr_mu_lock(&fd->mu);
501
504
  /* only shutdown once */
502
505
  if (!fd->shutdown) {
503
506
  fd->shutdown = 1;
507
+ fd->shutdown_error = why;
504
508
  /* signal read/write closed to OS so that future operations fail */
505
509
  shutdown(fd->fd, SHUT_RDWR);
506
510
  set_ready_locked(exec_ctx, fd, &fd->read_closure);
507
511
  set_ready_locked(exec_ctx, fd, &fd->write_closure);
512
+ } else {
513
+ GRPC_ERROR_UNREF(why);
508
514
  }
509
515
  gpr_mu_unlock(&fd->mu);
510
516
  }
@@ -653,10 +659,18 @@ static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
653
659
  worker->next->prev = worker->prev;
654
660
  }
655
661
 
656
- static int pollset_has_workers(grpc_pollset *p) {
662
+ static bool pollset_has_workers(grpc_pollset *p) {
657
663
  return p->root_worker.next != &p->root_worker;
658
664
  }
659
665
 
666
+ static bool pollset_in_pollset_sets(grpc_pollset *p) {
667
+ return p->pollset_set_count;
668
+ }
669
+
670
+ static bool pollset_has_observers(grpc_pollset *p) {
671
+ return pollset_has_workers(p) || pollset_in_pollset_sets(p);
672
+ }
673
+
660
674
  static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) {
661
675
  if (pollset_has_workers(p)) {
662
676
  grpc_pollset_worker *w = p->root_worker.next;
@@ -795,6 +809,7 @@ static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
795
809
  pollset->fd_count = 0;
796
810
  pollset->fd_capacity = 0;
797
811
  pollset->fds = NULL;
812
+ pollset->pollset_set_count = 0;
798
813
  }
799
814
 
800
815
  static void pollset_destroy(grpc_pollset *pollset) {
@@ -810,16 +825,6 @@ static void pollset_destroy(grpc_pollset *pollset) {
810
825
  gpr_mu_destroy(&pollset->mu);
811
826
  }
812
827
 
813
- static void pollset_reset(grpc_pollset *pollset) {
814
- GPR_ASSERT(pollset->shutting_down);
815
- GPR_ASSERT(!pollset_has_workers(pollset));
816
- GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
817
- GPR_ASSERT(pollset->fd_count == 0);
818
- pollset->shutting_down = 0;
819
- pollset->called_shutdown = 0;
820
- pollset->kicked_without_pollers = 0;
821
- }
822
-
823
828
  static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
824
829
  grpc_fd *fd) {
825
830
  gpr_mu_lock(&pollset->mu);
@@ -1066,7 +1071,7 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1066
1071
  if (pollset->shutting_down) {
1067
1072
  if (pollset_has_workers(pollset)) {
1068
1073
  pollset_kick(pollset, NULL);
1069
- } else if (!pollset->called_shutdown) {
1074
+ } else if (!pollset->called_shutdown && !pollset_has_observers(pollset)) {
1070
1075
  pollset->called_shutdown = 1;
1071
1076
  gpr_mu_unlock(&pollset->mu);
1072
1077
  finish_shutdown(exec_ctx, pollset);
@@ -1098,7 +1103,7 @@ static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
1098
1103
  if (!pollset_has_workers(pollset)) {
1099
1104
  grpc_closure_list_sched(exec_ctx, &pollset->idle_jobs);
1100
1105
  }
1101
- if (!pollset->called_shutdown && !pollset_has_workers(pollset)) {
1106
+ if (!pollset->called_shutdown && !pollset_has_observers(pollset)) {
1102
1107
  pollset->called_shutdown = 1;
1103
1108
  finish_shutdown(exec_ctx, pollset);
1104
1109
  }
@@ -1126,18 +1131,32 @@ static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
1126
1131
  */
1127
1132
 
1128
1133
  static grpc_pollset_set *pollset_set_create(void) {
1129
- grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set));
1130
- memset(pollset_set, 0, sizeof(*pollset_set));
1134
+ grpc_pollset_set *pollset_set = gpr_zalloc(sizeof(*pollset_set));
1131
1135
  gpr_mu_init(&pollset_set->mu);
1132
1136
  return pollset_set;
1133
1137
  }
1134
1138
 
1135
- static void pollset_set_destroy(grpc_pollset_set *pollset_set) {
1139
+ static void pollset_set_destroy(grpc_exec_ctx *exec_ctx,
1140
+ grpc_pollset_set *pollset_set) {
1136
1141
  size_t i;
1137
1142
  gpr_mu_destroy(&pollset_set->mu);
1138
1143
  for (i = 0; i < pollset_set->fd_count; i++) {
1139
1144
  GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
1140
1145
  }
1146
+ for (i = 0; i < pollset_set->pollset_count; i++) {
1147
+ grpc_pollset *pollset = pollset_set->pollsets[i];
1148
+ gpr_mu_lock(&pollset->mu);
1149
+ pollset->pollset_set_count--;
1150
+ /* check shutdown */
1151
+ if (pollset->shutting_down && !pollset->called_shutdown &&
1152
+ !pollset_has_observers(pollset)) {
1153
+ pollset->called_shutdown = 1;
1154
+ gpr_mu_unlock(&pollset->mu);
1155
+ finish_shutdown(exec_ctx, pollset);
1156
+ } else {
1157
+ gpr_mu_unlock(&pollset->mu);
1158
+ }
1159
+ }
1141
1160
  gpr_free(pollset_set->pollsets);
1142
1161
  gpr_free(pollset_set->pollset_sets);
1143
1162
  gpr_free(pollset_set->fds);
@@ -1148,6 +1167,9 @@ static void pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
1148
1167
  grpc_pollset_set *pollset_set,
1149
1168
  grpc_pollset *pollset) {
1150
1169
  size_t i, j;
1170
+ gpr_mu_lock(&pollset->mu);
1171
+ pollset->pollset_set_count++;
1172
+ gpr_mu_unlock(&pollset->mu);
1151
1173
  gpr_mu_lock(&pollset_set->mu);
1152
1174
  if (pollset_set->pollset_count == pollset_set->pollset_capacity) {
1153
1175
  pollset_set->pollset_capacity =
@@ -1183,6 +1205,17 @@ static void pollset_set_del_pollset(grpc_exec_ctx *exec_ctx,
1183
1205
  }
1184
1206
  }
1185
1207
  gpr_mu_unlock(&pollset_set->mu);
1208
+ gpr_mu_lock(&pollset->mu);
1209
+ pollset->pollset_set_count--;
1210
+ /* check shutdown */
1211
+ if (pollset->shutting_down && !pollset->called_shutdown &&
1212
+ !pollset_has_observers(pollset)) {
1213
+ pollset->called_shutdown = 1;
1214
+ gpr_mu_unlock(&pollset->mu);
1215
+ finish_shutdown(exec_ctx, pollset);
1216
+ } else {
1217
+ gpr_mu_unlock(&pollset->mu);
1218
+ }
1186
1219
  }
1187
1220
 
1188
1221
  static void pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx,
@@ -1509,7 +1542,6 @@ static const grpc_event_engine_vtable vtable = {
1509
1542
 
1510
1543
  .pollset_init = pollset_init,
1511
1544
  .pollset_shutdown = pollset_shutdown,
1512
- .pollset_reset = pollset_reset,
1513
1545
  .pollset_destroy = pollset_destroy,
1514
1546
  .pollset_work = pollset_work,
1515
1547
  .pollset_kick = pollset_kick,
@@ -52,6 +52,8 @@
52
52
  * tests */
53
53
  grpc_poll_function_type grpc_poll_function = poll;
54
54
 
55
+ grpc_wakeup_fd grpc_global_wakeup_fd;
56
+
55
57
  static const grpc_event_engine_vtable *g_event_engine;
56
58
  static const char *g_poll_strategy_name = NULL;
57
59
 
@@ -160,8 +162,8 @@ void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
160
162
  g_event_engine->fd_orphan(exec_ctx, fd, on_done, release_fd, reason);
161
163
  }
162
164
 
163
- void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
164
- g_event_engine->fd_shutdown(exec_ctx, fd);
165
+ void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why) {
166
+ g_event_engine->fd_shutdown(exec_ctx, fd, why);
165
167
  }
166
168
 
167
169
  bool grpc_fd_is_shutdown(grpc_fd *fd) {
@@ -189,10 +191,6 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
189
191
  g_event_engine->pollset_shutdown(exec_ctx, pollset, closure);
190
192
  }
191
193
 
192
- void grpc_pollset_reset(grpc_pollset *pollset) {
193
- g_event_engine->pollset_reset(pollset);
194
- }
195
-
196
194
  void grpc_pollset_destroy(grpc_pollset *pollset) {
197
195
  g_event_engine->pollset_destroy(pollset);
198
196
  }
@@ -217,8 +215,9 @@ grpc_pollset_set *grpc_pollset_set_create(void) {
217
215
  return g_event_engine->pollset_set_create();
218
216
  }
219
217
 
220
- void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) {
221
- g_event_engine->pollset_set_destroy(pollset_set);
218
+ void grpc_pollset_set_destroy(grpc_exec_ctx *exec_ctx,
219
+ grpc_pollset_set *pollset_set) {
220
+ g_event_engine->pollset_set_destroy(exec_ctx, pollset_set);
222
221
  }
223
222
 
224
223
  void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
@@ -51,7 +51,7 @@ typedef struct grpc_event_engine_vtable {
51
51
  int (*fd_wrapped_fd)(grpc_fd *fd);
52
52
  void (*fd_orphan)(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
53
53
  int *release_fd, const char *reason);
54
- void (*fd_shutdown)(grpc_exec_ctx *exec_ctx, grpc_fd *fd);
54
+ void (*fd_shutdown)(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why);
55
55
  void (*fd_notify_on_read)(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
56
56
  grpc_closure *closure);
57
57
  void (*fd_notify_on_write)(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
@@ -64,7 +64,6 @@ typedef struct grpc_event_engine_vtable {
64
64
  void (*pollset_init)(grpc_pollset *pollset, gpr_mu **mu);
65
65
  void (*pollset_shutdown)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
66
66
  grpc_closure *closure);
67
- void (*pollset_reset)(grpc_pollset *pollset);
68
67
  void (*pollset_destroy)(grpc_pollset *pollset);
69
68
  grpc_error *(*pollset_work)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
70
69
  grpc_pollset_worker **worker, gpr_timespec now,
@@ -75,7 +74,8 @@ typedef struct grpc_event_engine_vtable {
75
74
  struct grpc_fd *fd);
76
75
 
77
76
  grpc_pollset_set *(*pollset_set_create)(void);
78
- void (*pollset_set_destroy)(grpc_pollset_set *pollset_set);
77
+ void (*pollset_set_destroy)(grpc_exec_ctx *exec_ctx,
78
+ grpc_pollset_set *pollset_set);
79
79
  void (*pollset_set_add_pollset)(grpc_exec_ctx *exec_ctx,
80
80
  grpc_pollset_set *pollset_set,
81
81
  grpc_pollset *pollset);
@@ -140,7 +140,7 @@ void grpc_fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure *on_done,
140
140
  bool grpc_fd_is_shutdown(grpc_fd *fd);
141
141
 
142
142
  /* Cause any current and future callbacks to fail. */
143
- void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd);
143
+ void grpc_fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_error *why);
144
144
 
145
145
  /* Register read interest, causing read_cb to be called once when fd becomes
146
146
  readable, on deadline specified by deadline, or on shutdown triggered by
@@ -42,11 +42,16 @@
42
42
  #include "src/core/lib/profiling/timers.h"
43
43
 
44
44
  bool grpc_exec_ctx_ready_to_finish(grpc_exec_ctx *exec_ctx) {
45
- if (!exec_ctx->cached_ready_to_finish) {
46
- exec_ctx->cached_ready_to_finish = exec_ctx->check_ready_to_finish(
47
- exec_ctx, exec_ctx->check_ready_to_finish_arg);
45
+ if ((exec_ctx->flags & GRPC_EXEC_CTX_FLAG_IS_FINISHED) == 0) {
46
+ if (exec_ctx->check_ready_to_finish(exec_ctx,
47
+ exec_ctx->check_ready_to_finish_arg)) {
48
+ exec_ctx->flags |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
49
+ return true;
50
+ }
51
+ return false;
52
+ } else {
53
+ return true;
48
54
  }
49
- return exec_ctx->cached_ready_to_finish;
50
55
  }
51
56
 
52
57
  bool grpc_never_ready_to_finish(grpc_exec_ctx *exec_ctx, void *arg_ignored) {
@@ -82,7 +87,7 @@ bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
82
87
  }
83
88
 
84
89
  void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {
85
- exec_ctx->cached_ready_to_finish = true;
90
+ exec_ctx->flags |= GRPC_EXEC_CTX_FLAG_IS_FINISHED;
86
91
  grpc_exec_ctx_flush(exec_ctx);
87
92
  }
88
93
 
@@ -101,6 +106,6 @@ void grpc_exec_ctx_global_init(void) {}
101
106
  void grpc_exec_ctx_global_shutdown(void) {}
102
107
 
103
108
  static const grpc_closure_scheduler_vtable exec_ctx_scheduler_vtable = {
104
- exec_ctx_run, exec_ctx_sched};
109
+ exec_ctx_run, exec_ctx_sched, "exec_ctx"};
105
110
  static grpc_closure_scheduler exec_ctx_scheduler = {&exec_ctx_scheduler_vtable};
106
111
  grpc_closure_scheduler *grpc_schedule_on_exec_ctx = &exec_ctx_scheduler;
@@ -43,6 +43,13 @@
43
43
  typedef struct grpc_workqueue grpc_workqueue;
44
44
  typedef struct grpc_combiner grpc_combiner;
45
45
 
46
+ /* This exec_ctx is ready to return: either pre-populated, or cached as soon as
47
+ the finish_check returns true */
48
+ #define GRPC_EXEC_CTX_FLAG_IS_FINISHED 1
49
+ /* The exec_ctx's thread is (potentially) owned by a call or channel: care
50
+ should be given to not delete said call/channel from this exec_ctx */
51
+ #define GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP 2
52
+
46
53
  /** Execution context.
47
54
  * A bag of data that collects information along a callstack.
48
55
  * Generally created at public API entry points, and passed down as
@@ -63,36 +70,26 @@ typedef struct grpc_combiner grpc_combiner;
63
70
  * - Instances are always passed as the first argument to a function that
64
71
  * takes it, and always as a pointer (grpc_exec_ctx is never copied).
65
72
  */
66
- #ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
67
73
  struct grpc_exec_ctx {
68
74
  grpc_closure_list closure_list;
69
75
  /** currently active combiner: updated only via combiner.c */
70
76
  grpc_combiner *active_combiner;
71
77
  /** last active combiner in the active combiner list */
72
78
  grpc_combiner *last_combiner;
73
- bool cached_ready_to_finish;
79
+ uintptr_t flags;
74
80
  void *check_ready_to_finish_arg;
75
81
  bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg);
76
82
  };
77
83
 
78
84
  /* initializer for grpc_exec_ctx:
79
85
  prefer to use GRPC_EXEC_CTX_INIT whenever possible */
80
- #define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \
81
- { GRPC_CLOSURE_LIST_INIT, NULL, NULL, false, finish_check_arg, finish_check }
82
- #else
83
- struct grpc_exec_ctx {
84
- bool cached_ready_to_finish;
85
- void *check_ready_to_finish_arg;
86
- bool (*check_ready_to_finish)(grpc_exec_ctx *exec_ctx, void *arg);
87
- };
88
- #define GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(finish_check, finish_check_arg) \
89
- { false, finish_check_arg, finish_check }
90
- #endif
86
+ #define GRPC_EXEC_CTX_INITIALIZER(flags, finish_check, finish_check_arg) \
87
+ { GRPC_CLOSURE_LIST_INIT, NULL, NULL, flags, finish_check_arg, finish_check }
91
88
 
92
89
  /* initialize an execution context at the top level of an API call into grpc
93
90
  (this is safe to use elsewhere, though possibly not as efficient) */
94
91
  #define GRPC_EXEC_CTX_INIT \
95
- GRPC_EXEC_CTX_INIT_WITH_FINISH_CHECK(grpc_always_ready_to_finish, NULL)
92
+ GRPC_EXEC_CTX_INITIALIZER(GRPC_EXEC_CTX_FLAG_IS_FINISHED, NULL, NULL)
96
93
 
97
94
  extern grpc_closure_scheduler *grpc_schedule_on_exec_ctx;
98
95
 
@@ -158,7 +158,7 @@ void grpc_executor_shutdown(grpc_exec_ctx *exec_ctx) {
158
158
  gpr_mu_destroy(&g_executor.mu);
159
159
  }
160
160
 
161
- static const grpc_closure_scheduler_vtable executor_vtable = {executor_push,
162
- executor_push};
161
+ static const grpc_closure_scheduler_vtable executor_vtable = {
162
+ executor_push, executor_push, "executor"};
163
163
  static grpc_closure_scheduler executor_scheduler = {&executor_vtable};
164
164
  grpc_closure_scheduler *grpc_executor_scheduler = &executor_scheduler;
@@ -47,7 +47,7 @@ grpc_error *grpc_load_file(const char *filename, int add_null_terminator,
47
47
  grpc_slice *output) {
48
48
  unsigned char *contents = NULL;
49
49
  size_t contents_size = 0;
50
- grpc_slice result = gpr_empty_slice();
50
+ grpc_slice result = grpc_empty_slice();
51
51
  FILE *file;
52
52
  size_t bytes_read = 0;
53
53
  grpc_error *error = GRPC_ERROR_NONE;
@@ -31,94 +31,18 @@
31
31
  *
32
32
  */
33
33
 
34
- #include <grpc/support/alloc.h>
35
- #include <grpc/support/log.h>
36
34
  #include "src/core/lib/iomgr/endpoint.h"
37
35
 
38
- typedef struct endpoint_ll_node {
39
- grpc_endpoint *ep;
40
- struct endpoint_ll_node *next;
41
- } endpoint_ll_node;
42
-
43
- static endpoint_ll_node *head = NULL;
44
- static gpr_mu g_endpoint_mutex;
45
-
46
- void grpc_network_status_shutdown(void) {
47
- if (head != NULL) {
48
- gpr_log(GPR_ERROR,
49
- "Memory leaked as not all network endpoints were shut down");
50
- }
51
- gpr_mu_destroy(&g_endpoint_mutex);
52
- }
36
+ void grpc_network_status_shutdown(void) {}
53
37
 
54
38
  void grpc_network_status_init(void) {
55
- gpr_mu_init(&g_endpoint_mutex);
56
39
  // TODO(makarandd): Install callback with OS to monitor network status.
57
40
  }
58
41
 
59
- void grpc_destroy_network_status_monitor() {
60
- for (endpoint_ll_node *curr = head; curr != NULL;) {
61
- endpoint_ll_node *next = curr->next;
62
- gpr_free(curr);
63
- curr = next;
64
- }
65
- gpr_mu_destroy(&g_endpoint_mutex);
66
- }
67
-
68
- void grpc_network_status_register_endpoint(grpc_endpoint *ep) {
69
- gpr_mu_lock(&g_endpoint_mutex);
70
- if (head == NULL) {
71
- head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node));
72
- head->ep = ep;
73
- head->next = NULL;
74
- } else {
75
- endpoint_ll_node *prev_head = head;
76
- head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node));
77
- head->ep = ep;
78
- head->next = prev_head;
79
- }
80
- gpr_mu_unlock(&g_endpoint_mutex);
81
- }
42
+ void grpc_destroy_network_status_monitor() {}
82
43
 
83
- void grpc_network_status_unregister_endpoint(grpc_endpoint *ep) {
84
- gpr_mu_lock(&g_endpoint_mutex);
85
- GPR_ASSERT(head);
86
- bool found = false;
87
- endpoint_ll_node *prev = head;
88
- // if we're unregistering the head, just move head to the next
89
- if (ep == head->ep) {
90
- head = head->next;
91
- gpr_free(prev);
92
- found = true;
93
- } else {
94
- for (endpoint_ll_node *curr = head->next; curr != NULL; curr = curr->next) {
95
- if (ep == curr->ep) {
96
- prev->next = curr->next;
97
- gpr_free(curr);
98
- found = true;
99
- break;
100
- }
101
- prev = curr;
102
- }
103
- }
104
- gpr_mu_unlock(&g_endpoint_mutex);
105
- GPR_ASSERT(found);
106
- }
44
+ void grpc_network_status_register_endpoint(grpc_endpoint *ep) { (void)ep; }
107
45
 
108
- // Walk the linked-list from head and execute shutdown. It is possible that
109
- // other threads might be in the process of shutdown as well, but that has
110
- // no side effect since endpoint shutdown is idempotent.
111
- void grpc_network_status_shutdown_all_endpoints() {
112
- gpr_mu_lock(&g_endpoint_mutex);
113
- if (head == NULL) {
114
- gpr_mu_unlock(&g_endpoint_mutex);
115
- return;
116
- }
117
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
46
+ void grpc_network_status_unregister_endpoint(grpc_endpoint *ep) { (void)ep; }
118
47
 
119
- for (endpoint_ll_node *curr = head; curr != NULL; curr = curr->next) {
120
- curr->ep->vtable->shutdown(&exec_ctx, curr->ep);
121
- }
122
- gpr_mu_unlock(&g_endpoint_mutex);
123
- grpc_exec_ctx_finish(&exec_ctx);
124
- }
48
+ void grpc_network_status_shutdown_all_endpoints() {}