grpc 1.1.2 → 1.2.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 (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
@@ -65,7 +65,8 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
65
65
  should not be NULL. */
66
66
  grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
67
67
  const grpc_channel_args *args,
68
- grpc_pollset_set *pollset_set);
68
+ grpc_pollset_set *pollset_set,
69
+ grpc_combiner *combiner);
69
70
 
70
71
  /** Find a resolver factory given a name and return an (owned-by-the-caller)
71
72
  * reference to it */
@@ -73,10 +74,11 @@ grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name);
73
74
 
74
75
  /** Given a target, return a (freshly allocated with gpr_malloc) string
75
76
  representing the default authority to pass from a client. */
76
- char *grpc_get_default_authority(const char *target);
77
+ char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target);
77
78
 
78
79
  /** Returns a newly allocated string containing \a target, adding the
79
80
  default prefix if needed. */
80
- char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target);
81
+ char *grpc_resolver_factory_add_default_prefix_if_needed(
82
+ grpc_exec_ctx *exec_ctx, const char *target);
81
83
 
82
84
  #endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */
@@ -43,6 +43,7 @@
43
43
  #include "src/core/ext/client_channel/client_channel.h"
44
44
  #include "src/core/ext/client_channel/initial_connect_string.h"
45
45
  #include "src/core/ext/client_channel/parse_address.h"
46
+ #include "src/core/ext/client_channel/proxy_mapper_registry.h"
46
47
  #include "src/core/ext/client_channel/subchannel_index.h"
47
48
  #include "src/core/ext/client_channel/uri_parser.h"
48
49
  #include "src/core/lib/channel/channel_args.h"
@@ -216,7 +217,7 @@ static void subchannel_destroy(grpc_exec_ctx *exec_ctx, void *arg,
216
217
  grpc_slice_unref_internal(exec_ctx, c->initial_connect_string);
217
218
  grpc_connectivity_state_destroy(exec_ctx, &c->state_tracker);
218
219
  grpc_connector_unref(exec_ctx, c->connector);
219
- grpc_pollset_set_destroy(c->pollset_set);
220
+ grpc_pollset_set_destroy(exec_ctx, c->pollset_set);
220
221
  grpc_subchannel_key_destroy(exec_ctx, c->key);
221
222
  gpr_free(c);
222
223
  }
@@ -272,7 +273,8 @@ static void disconnect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
272
273
  gpr_mu_lock(&c->mu);
273
274
  GPR_ASSERT(!c->disconnected);
274
275
  c->disconnected = true;
275
- grpc_connector_shutdown(exec_ctx, c->connector);
276
+ grpc_connector_shutdown(exec_ctx, c->connector,
277
+ GRPC_ERROR_CREATE("Subchannel disconnected"));
276
278
  con = GET_CONNECTED_SUBCHANNEL(c, no_barrier);
277
279
  if (con != NULL) {
278
280
  GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, con, "connection");
@@ -314,8 +316,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
314
316
  return c;
315
317
  }
316
318
 
317
- c = gpr_malloc(sizeof(*c));
318
- memset(c, 0, sizeof(*c));
319
+ c = gpr_zalloc(sizeof(*c));
319
320
  c->key = key;
320
321
  gpr_atm_no_barrier_store(&c->ref_pair, 1 << INTERNAL_REF_BITS);
321
322
  c->connector = connector;
@@ -330,15 +331,26 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
330
331
  }
331
332
  c->pollset_set = grpc_pollset_set_create();
332
333
  grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
333
- grpc_get_subchannel_address_arg(args->args, addr);
334
+ grpc_get_subchannel_address_arg(exec_ctx, args->args, addr);
334
335
  grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
335
- static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
336
- grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
336
+ grpc_resolved_address *new_address = NULL;
337
+ grpc_channel_args *new_args = NULL;
338
+ if (grpc_proxy_mappers_map_address(exec_ctx, addr, args->args, &new_address,
339
+ &new_args)) {
340
+ GPR_ASSERT(new_address != NULL);
341
+ gpr_free(addr);
342
+ addr = new_address;
343
+ if (new_args != NULL) c->args = new_args;
344
+ }
345
+ if (c->args == NULL) {
346
+ static const char *keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
347
+ grpc_arg new_arg = grpc_create_subchannel_address_arg(addr);
348
+ c->args = grpc_channel_args_copy_and_add_and_remove(
349
+ args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg,
350
+ 1);
351
+ gpr_free(new_arg.value.string);
352
+ }
337
353
  gpr_free(addr);
338
- c->args = grpc_channel_args_copy_and_add_and_remove(
339
- args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
340
- gpr_free(new_arg.value.string);
341
-
342
354
  c->root_external_state_watcher.next = c->root_external_state_watcher.prev =
343
355
  &c->root_external_state_watcher;
344
356
  grpc_closure_init(&c->connected, subchannel_connected, c,
@@ -406,7 +418,7 @@ grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c,
406
418
  grpc_error **error) {
407
419
  grpc_connectivity_state state;
408
420
  gpr_mu_lock(&c->mu);
409
- state = grpc_connectivity_state_check(&c->state_tracker, error);
421
+ state = grpc_connectivity_state_get(&c->state_tracker, error);
410
422
  gpr_mu_unlock(&c->mu);
411
423
  return state;
412
424
  }
@@ -425,7 +437,7 @@ static void on_external_state_watcher_done(grpc_exec_ctx *exec_ctx, void *arg,
425
437
  gpr_mu_unlock(&w->subchannel->mu);
426
438
  GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, w->subchannel, "external_state_watcher");
427
439
  gpr_free(w);
428
- follow_up->cb(exec_ctx, follow_up->cb_arg, error);
440
+ grpc_closure_run(exec_ctx, follow_up, GRPC_ERROR_REF(error));
429
441
  }
430
442
 
431
443
  static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
@@ -625,9 +637,8 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
625
637
  grpc_error *error = grpc_channel_stack_builder_finish(
626
638
  exec_ctx, builder, 0, 1, connection_destroy, NULL, (void **)&con);
627
639
  if (error != GRPC_ERROR_NONE) {
628
- const char *msg = grpc_error_string(error);
629
- gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", msg);
630
- grpc_error_free_string(msg);
640
+ gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
641
+ grpc_error_string(error));
631
642
  GRPC_ERROR_UNREF(error);
632
643
  abort(); /* TODO(ctiller): what to do here? */
633
644
  }
@@ -692,7 +703,6 @@ static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *arg,
692
703
 
693
704
  const char *errmsg = grpc_error_string(error);
694
705
  gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
695
- grpc_error_free_string(errmsg);
696
706
 
697
707
  maybe_start_connecting_locked(exec_ctx, c);
698
708
  GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
@@ -751,10 +761,10 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel(
751
761
 
752
762
  grpc_error *grpc_connected_subchannel_create_call(
753
763
  grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
754
- grpc_polling_entity *pollent, grpc_mdstr *path, gpr_timespec start_time,
764
+ grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
755
765
  gpr_timespec deadline, grpc_subchannel_call **call) {
756
766
  grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
757
- *call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
767
+ *call = gpr_zalloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
758
768
  grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
759
769
  (*call)->connection = con; // Ref is added below.
760
770
  grpc_error *error =
@@ -763,7 +773,7 @@ grpc_error *grpc_connected_subchannel_create_call(
763
773
  if (error != GRPC_ERROR_NONE) {
764
774
  const char *error_string = grpc_error_string(error);
765
775
  gpr_log(GPR_ERROR, "error: %s", error_string);
766
- grpc_error_free_string(error_string);
776
+
767
777
  gpr_free(*call);
768
778
  return error;
769
779
  }
@@ -777,8 +787,9 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
777
787
  return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
778
788
  }
779
789
 
780
- static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
781
- grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
790
+ static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str,
791
+ grpc_resolved_address *addr) {
792
+ grpc_uri *uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */);
782
793
  GPR_ASSERT(uri != NULL);
783
794
  if (strcmp(uri->scheme, "ipv4") == 0) {
784
795
  GPR_ASSERT(parse_ipv4(uri, addr));
@@ -790,16 +801,22 @@ static void grpc_uri_to_sockaddr(char *uri_str, grpc_resolved_address *addr) {
790
801
  grpc_uri_destroy(uri);
791
802
  }
792
803
 
793
- void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
804
+ void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
805
+ const grpc_channel_args *args,
794
806
  grpc_resolved_address *addr) {
807
+ const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
808
+ memset(addr, 0, sizeof(*addr));
809
+ if (*addr_uri_str != '\0') {
810
+ grpc_uri_to_sockaddr(exec_ctx, addr_uri_str, addr);
811
+ }
812
+ }
813
+
814
+ const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args) {
795
815
  const grpc_arg *addr_arg =
796
816
  grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
797
817
  GPR_ASSERT(addr_arg != NULL); // Should have been set by LB policy.
798
818
  GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
799
- memset(addr, 0, sizeof(*addr));
800
- if (*addr_arg->value.string != '\0') {
801
- grpc_uri_to_sockaddr(addr_arg->value.string, addr);
802
- }
819
+ return addr_arg->value.string;
803
820
  }
804
821
 
805
822
  grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr) {
@@ -114,7 +114,7 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx,
114
114
  /** construct a subchannel call */
115
115
  grpc_error *grpc_connected_subchannel_create_call(
116
116
  grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
117
- grpc_polling_entity *pollent, grpc_mdstr *path, gpr_timespec start_time,
117
+ grpc_polling_entity *pollent, grpc_slice path, gpr_timespec start_time,
118
118
  gpr_timespec deadline, grpc_subchannel_call **subchannel_call);
119
119
 
120
120
  /** process a transport level op */
@@ -175,9 +175,13 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
175
175
  const grpc_subchannel_args *args);
176
176
 
177
177
  /// Sets \a addr from \a args.
178
- void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
178
+ void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
179
+ const grpc_channel_args *args,
179
180
  grpc_resolved_address *addr);
180
181
 
182
+ /// Returns the URI string for the address to connect to.
183
+ const char *grpc_get_subchannel_address_uri_arg(const grpc_channel_args *args);
184
+
181
185
  /// Returns a new channel arg encoding the subchannel address as a string.
182
186
  /// Caller is responsible for freeing the string.
183
187
  grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address *addr);
@@ -35,13 +35,15 @@
35
35
 
36
36
  #include <string.h>
37
37
 
38
- #include <grpc/slice.h>
39
38
  #include <grpc/slice_buffer.h>
40
39
  #include <grpc/support/alloc.h>
41
40
  #include <grpc/support/log.h>
42
41
  #include <grpc/support/port_platform.h>
43
42
  #include <grpc/support/string_util.h>
44
43
 
44
+ #include "src/core/lib/slice/percent_encoding.h"
45
+ #include "src/core/lib/slice/slice_internal.h"
46
+ #include "src/core/lib/slice/slice_string_helpers.h"
45
47
  #include "src/core/lib/support/string.h"
46
48
 
47
49
  /** a size_t default value... maps to all 1's */
@@ -68,11 +70,16 @@ static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section,
68
70
  return NULL;
69
71
  }
70
72
 
71
- /** Returns a copy of \a src[begin, end) */
72
- static char *copy_component(const char *src, size_t begin, size_t end) {
73
- char *out = gpr_malloc(end - begin + 1);
74
- memcpy(out, src + begin, end - begin);
75
- out[end - begin] = 0;
73
+ /** Returns a copy of percent decoded \a src[begin, end) */
74
+ static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src,
75
+ size_t begin, size_t end) {
76
+ grpc_slice component =
77
+ grpc_slice_from_copied_buffer(src + begin, end - begin);
78
+ grpc_slice decoded_component =
79
+ grpc_permissive_percent_decode_slice(component);
80
+ char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
81
+ grpc_slice_unref_internal(exec_ctx, component);
82
+ grpc_slice_unref_internal(exec_ctx, decoded_component);
76
83
  return out;
77
84
  }
78
85
 
@@ -175,7 +182,8 @@ static void parse_query_parts(grpc_uri *uri) {
175
182
  }
176
183
  }
177
184
 
178
- grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
185
+ grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
186
+ int suppress_errors) {
179
187
  grpc_uri *uri;
180
188
  size_t scheme_begin = 0;
181
189
  size_t scheme_end = NOT_SET;
@@ -262,13 +270,17 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
262
270
  fragment_end = i;
263
271
  }
264
272
 
265
- uri = gpr_malloc(sizeof(*uri));
266
- memset(uri, 0, sizeof(*uri));
267
- uri->scheme = copy_component(uri_text, scheme_begin, scheme_end);
268
- uri->authority = copy_component(uri_text, authority_begin, authority_end);
269
- uri->path = copy_component(uri_text, path_begin, path_end);
270
- uri->query = copy_component(uri_text, query_begin, query_end);
271
- uri->fragment = copy_component(uri_text, fragment_begin, fragment_end);
273
+ uri = gpr_zalloc(sizeof(*uri));
274
+ uri->scheme =
275
+ decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end);
276
+ uri->authority = decode_and_copy_component(exec_ctx, uri_text,
277
+ authority_begin, authority_end);
278
+ uri->path =
279
+ decode_and_copy_component(exec_ctx, uri_text, path_begin, path_end);
280
+ uri->query =
281
+ decode_and_copy_component(exec_ctx, uri_text, query_begin, query_end);
282
+ uri->fragment = decode_and_copy_component(exec_ctx, uri_text, fragment_begin,
283
+ fragment_end);
272
284
  parse_query_parts(uri);
273
285
 
274
286
  return uri;
@@ -35,6 +35,7 @@
35
35
  #define GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H
36
36
 
37
37
  #include <stddef.h>
38
+ #include "src/core/lib/iomgr/exec_ctx.h"
38
39
 
39
40
  typedef struct {
40
41
  char *scheme;
@@ -51,7 +52,8 @@ typedef struct {
51
52
  } grpc_uri;
52
53
 
53
54
  /** parse a uri, return NULL on failure */
54
- grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors);
55
+ grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
56
+ int suppress_errors);
55
57
 
56
58
  /** return the part of a query string after the '=' in "?key=xxx&...", or NULL
57
59
  * if key is not present */
@@ -112,11 +112,14 @@
112
112
  #include "src/core/ext/client_channel/lb_policy_registry.h"
113
113
  #include "src/core/ext/client_channel/parse_address.h"
114
114
  #include "src/core/ext/lb_policy/grpclb/grpclb.h"
115
+ #include "src/core/ext/lb_policy/grpclb/grpclb_channel.h"
115
116
  #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
116
117
  #include "src/core/lib/channel/channel_args.h"
118
+ #include "src/core/lib/iomgr/combiner.h"
117
119
  #include "src/core/lib/iomgr/sockaddr.h"
118
120
  #include "src/core/lib/iomgr/sockaddr_utils.h"
119
121
  #include "src/core/lib/iomgr/timer.h"
122
+ #include "src/core/lib/slice/slice_hash_table.h"
120
123
  #include "src/core/lib/slice/slice_internal.h"
121
124
  #include "src/core/lib/slice/slice_string_helpers.h"
122
125
  #include "src/core/lib/support/backoff.h"
@@ -135,13 +138,13 @@ int grpc_lb_glb_trace = 0;
135
138
 
136
139
  /* add lb_token of selected subchannel (address) to the call's initial
137
140
  * metadata */
138
- static void initial_metadata_add_lb_token(
139
- grpc_metadata_batch *initial_metadata,
140
- grpc_linked_mdelem *lb_token_mdelem_storage, grpc_mdelem *lb_token) {
141
+ static grpc_error *initial_metadata_add_lb_token(
142
+ grpc_exec_ctx *exec_ctx, grpc_metadata_batch *initial_metadata,
143
+ grpc_linked_mdelem *lb_token_mdelem_storage, grpc_mdelem lb_token) {
141
144
  GPR_ASSERT(lb_token_mdelem_storage != NULL);
142
- GPR_ASSERT(lb_token != NULL);
143
- grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
144
- lb_token);
145
+ GPR_ASSERT(!GRPC_MDISNULL(lb_token));
146
+ return grpc_metadata_batch_add_tail(exec_ctx, initial_metadata,
147
+ lb_token_mdelem_storage, lb_token);
145
148
  }
146
149
 
147
150
  typedef struct wrapped_rr_closure_arg {
@@ -161,7 +164,7 @@ typedef struct wrapped_rr_closure_arg {
161
164
  grpc_connected_subchannel **target;
162
165
 
163
166
  /* the LB token associated with the pick */
164
- grpc_mdelem *lb_token;
167
+ grpc_mdelem lb_token;
165
168
 
166
169
  /* storage for the lb token initial metadata mdelem */
167
170
  grpc_linked_mdelem *lb_token_mdelem_storage;
@@ -188,8 +191,8 @@ static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg,
188
191
  * addresses failed to connect). There won't be any user_data/token
189
192
  * available */
190
193
  if (*wc_arg->target != NULL) {
191
- if (wc_arg->lb_token != NULL) {
192
- initial_metadata_add_lb_token(wc_arg->initial_metadata,
194
+ if (!GRPC_MDISNULL(wc_arg->lb_token)) {
195
+ initial_metadata_add_lb_token(exec_ctx, wc_arg->initial_metadata,
193
196
  wc_arg->lb_token_mdelem_storage,
194
197
  GRPC_MDELEM_REF(wc_arg->lb_token));
195
198
  } else {
@@ -235,9 +238,7 @@ static void add_pending_pick(pending_pick **root,
235
238
  const grpc_lb_policy_pick_args *pick_args,
236
239
  grpc_connected_subchannel **target,
237
240
  grpc_closure *on_complete) {
238
- pending_pick *pp = gpr_malloc(sizeof(*pp));
239
- memset(pp, 0, sizeof(pending_pick));
240
- memset(&pp->wrapped_on_complete_arg, 0, sizeof(wrapped_rr_closure_arg));
241
+ pending_pick *pp = gpr_zalloc(sizeof(*pp));
241
242
  pp->next = *root;
242
243
  pp->pick_args = *pick_args;
243
244
  pp->target = target;
@@ -262,9 +263,7 @@ typedef struct pending_ping {
262
263
  } pending_ping;
263
264
 
264
265
  static void add_pending_ping(pending_ping **root, grpc_closure *notify) {
265
- pending_ping *pping = gpr_malloc(sizeof(*pping));
266
- memset(pping, 0, sizeof(pending_ping));
267
- memset(&pping->wrapped_notify_arg, 0, sizeof(wrapped_rr_closure_arg));
266
+ pending_ping *pping = gpr_zalloc(sizeof(*pping));
268
267
  pping->wrapped_notify_arg.wrapped_closure = notify;
269
268
  pping->wrapped_notify_arg.free_when_done = pping;
270
269
  pping->next = *root;
@@ -283,9 +282,6 @@ typedef struct glb_lb_policy {
283
282
  /** base policy: must be first */
284
283
  grpc_lb_policy base;
285
284
 
286
- /** mutex protecting remaining members */
287
- gpr_mu mu;
288
-
289
285
  /** who the client is trying to communicate with */
290
286
  const char *server_name;
291
287
  grpc_client_channel_factory *cc_factory;
@@ -345,8 +341,7 @@ typedef struct glb_lb_policy {
345
341
 
346
342
  /* call status code and details, set in lb_on_server_status_received() */
347
343
  grpc_status_code lb_call_status;
348
- char *lb_call_status_details;
349
- size_t lb_call_status_details_capacity;
344
+ grpc_slice lb_call_status_details;
350
345
 
351
346
  /** LB call retry backoff state */
352
347
  gpr_backoff lb_call_backoff_state;
@@ -388,10 +383,14 @@ static bool is_server_valid(const grpc_grpclb_server *server, size_t idx,
388
383
 
389
384
  /* vtable for LB tokens in grpc_lb_addresses. */
390
385
  static void *lb_token_copy(void *token) {
391
- return token == NULL ? NULL : GRPC_MDELEM_REF(token);
386
+ return token == NULL
387
+ ? NULL
388
+ : (void *)GRPC_MDELEM_REF((grpc_mdelem){(uintptr_t)token}).payload;
392
389
  }
393
390
  static void lb_token_destroy(grpc_exec_ctx *exec_ctx, void *token) {
394
- if (token != NULL) GRPC_MDELEM_UNREF(exec_ctx, token);
391
+ if (token != NULL) {
392
+ GRPC_MDELEM_UNREF(exec_ctx, (grpc_mdelem){(uintptr_t)token});
393
+ }
395
394
  }
396
395
  static int lb_token_cmp(void *token1, void *token2) {
397
396
  if (token1 > token2) return 1;
@@ -459,10 +458,11 @@ static grpc_lb_addresses *process_serverlist_locked(
459
458
  GPR_ARRAY_SIZE(server->load_balance_token);
460
459
  const size_t lb_token_length =
461
460
  strnlen(server->load_balance_token, lb_token_max_length);
462
- grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer(
463
- (uint8_t *)server->load_balance_token, lb_token_length);
464
- user_data = grpc_mdelem_from_metadata_strings(
465
- exec_ctx, GRPC_MDSTR_LB_TOKEN, lb_token_mdstr);
461
+ grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
462
+ server->load_balance_token, lb_token_length);
463
+ user_data = (void *)grpc_mdelem_from_slices(exec_ctx, GRPC_MDSTR_LB_TOKEN,
464
+ lb_token_mdstr)
465
+ .payload;
466
466
  } else {
467
467
  char *uri = grpc_sockaddr_to_uri(&addr);
468
468
  gpr_log(GPR_INFO,
@@ -470,7 +470,7 @@ static grpc_lb_addresses *process_serverlist_locked(
470
470
  "be used instead",
471
471
  uri);
472
472
  gpr_free(uri);
473
- user_data = GRPC_MDELEM_LB_TOKEN_EMPTY;
473
+ user_data = (void *)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
474
474
  }
475
475
 
476
476
  grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
@@ -486,9 +486,8 @@ static grpc_lb_addresses *process_serverlist_locked(
486
486
  static bool update_lb_connectivity_status_locked(
487
487
  grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy,
488
488
  grpc_connectivity_state new_rr_state, grpc_error *new_rr_state_error) {
489
- grpc_error *curr_state_error;
490
- const grpc_connectivity_state curr_glb_state = grpc_connectivity_state_check(
491
- &glb_policy->state_tracker, &curr_state_error);
489
+ const grpc_connectivity_state curr_glb_state =
490
+ grpc_connectivity_state_check(&glb_policy->state_tracker);
492
491
 
493
492
  /* The new connectivity status is a function of the previous one and the new
494
493
  * input coming from the status of the RR policy.
@@ -552,9 +551,9 @@ static bool pick_from_internal_rr_locked(
552
551
  const grpc_lb_policy_pick_args *pick_args,
553
552
  grpc_connected_subchannel **target, wrapped_rr_closure_arg *wc_arg) {
554
553
  GPR_ASSERT(rr_policy != NULL);
555
- const bool pick_done =
556
- grpc_lb_policy_pick(exec_ctx, rr_policy, pick_args, target,
557
- (void **)&wc_arg->lb_token, &wc_arg->wrapper_closure);
554
+ const bool pick_done = grpc_lb_policy_pick_locked(
555
+ exec_ctx, rr_policy, pick_args, target, (void **)&wc_arg->lb_token,
556
+ &wc_arg->wrapper_closure);
558
557
  if (pick_done) {
559
558
  /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */
560
559
  if (grpc_lb_glb_trace) {
@@ -564,7 +563,7 @@ static bool pick_from_internal_rr_locked(
564
563
  GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "glb_pick_sync");
565
564
 
566
565
  /* add the load reporting initial metadata */
567
- initial_metadata_add_lb_token(pick_args->initial_metadata,
566
+ initial_metadata_add_lb_token(exec_ctx, pick_args->initial_metadata,
568
567
  pick_args->lb_token_mdelem_storage,
569
568
  GRPC_MDELEM_REF(wc_arg->lb_token));
570
569
 
@@ -585,6 +584,7 @@ static grpc_lb_policy *create_rr_locked(
585
584
  grpc_lb_policy_args args;
586
585
  memset(&args, 0, sizeof(args));
587
586
  args.client_channel_factory = glb_policy->cc_factory;
587
+ args.combiner = glb_policy->base.combiner;
588
588
  grpc_lb_addresses *addresses =
589
589
  process_serverlist_locked(exec_ctx, serverlist);
590
590
 
@@ -603,8 +603,8 @@ static grpc_lb_policy *create_rr_locked(
603
603
  return rr;
604
604
  }
605
605
 
606
- static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
607
- grpc_error *error);
606
+ static void glb_rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx,
607
+ void *arg, grpc_error *error);
608
608
  /* glb_policy->rr_policy may be NULL (initial handover) */
609
609
  static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
610
610
  glb_lb_policy *glb_policy) {
@@ -628,8 +628,8 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
628
628
 
629
629
  grpc_error *new_rr_state_error = NULL;
630
630
  const grpc_connectivity_state new_rr_state =
631
- grpc_lb_policy_check_connectivity(exec_ctx, new_rr_policy,
632
- &new_rr_state_error);
631
+ grpc_lb_policy_check_connectivity_locked(exec_ctx, new_rr_policy,
632
+ &new_rr_state_error);
633
633
  /* Connectivity state is a function of the new RR policy just created */
634
634
  const bool replace_old_rr = update_lb_connectivity_status_locked(
635
635
  exec_ctx, glb_policy, new_rr_state, new_rr_state_error);
@@ -670,19 +670,19 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
670
670
  /* Allocate the data for the tracking of the new RR policy's connectivity.
671
671
  * It'll be deallocated in glb_rr_connectivity_changed() */
672
672
  rr_connectivity_data *rr_connectivity =
673
- gpr_malloc(sizeof(rr_connectivity_data));
674
- memset(rr_connectivity, 0, sizeof(rr_connectivity_data));
675
- grpc_closure_init(&rr_connectivity->on_change, glb_rr_connectivity_changed,
676
- rr_connectivity, grpc_schedule_on_exec_ctx);
673
+ gpr_zalloc(sizeof(rr_connectivity_data));
674
+ grpc_closure_init(&rr_connectivity->on_change,
675
+ glb_rr_connectivity_changed_locked, rr_connectivity,
676
+ grpc_combiner_scheduler(glb_policy->base.combiner, false));
677
677
  rr_connectivity->glb_policy = glb_policy;
678
678
  rr_connectivity->state = new_rr_state;
679
679
 
680
680
  /* Subscribe to changes to the connectivity of the new RR */
681
681
  GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "rr_connectivity_cb");
682
- grpc_lb_policy_notify_on_state_change(exec_ctx, glb_policy->rr_policy,
683
- &rr_connectivity->state,
684
- &rr_connectivity->on_change);
685
- grpc_lb_policy_exit_idle(exec_ctx, glb_policy->rr_policy);
682
+ grpc_lb_policy_notify_on_state_change_locked(exec_ctx, glb_policy->rr_policy,
683
+ &rr_connectivity->state,
684
+ &rr_connectivity->on_change);
685
+ grpc_lb_policy_exit_idle_locked(exec_ctx, glb_policy->rr_policy);
686
686
 
687
687
  /* Update picks and pings in wait */
688
688
  pending_pick *pp;
@@ -708,17 +708,16 @@ static void rr_handover_locked(grpc_exec_ctx *exec_ctx,
708
708
  gpr_log(GPR_INFO, "Pending ping about to PING from 0x%" PRIxPTR "",
709
709
  (intptr_t)glb_policy->rr_policy);
710
710
  }
711
- grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy,
712
- &pping->wrapped_notify_arg.wrapper_closure);
711
+ grpc_lb_policy_ping_one_locked(exec_ctx, glb_policy->rr_policy,
712
+ &pping->wrapped_notify_arg.wrapper_closure);
713
713
  }
714
714
  }
715
715
 
716
- static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
717
- grpc_error *error) {
716
+ static void glb_rr_connectivity_changed_locked(grpc_exec_ctx *exec_ctx,
717
+ void *arg, grpc_error *error) {
718
718
  rr_connectivity_data *rr_connectivity = arg;
719
719
  glb_lb_policy *glb_policy = rr_connectivity->glb_policy;
720
720
 
721
- gpr_mu_lock(&glb_policy->mu);
722
721
  const bool shutting_down = glb_policy->shutting_down;
723
722
  bool unref_needed = false;
724
723
  GRPC_ERROR_REF(error);
@@ -735,11 +734,10 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
735
734
  update_lb_connectivity_status_locked(exec_ctx, glb_policy,
736
735
  rr_connectivity->state, error);
737
736
  /* Resubscribe. Reuse the "rr_connectivity_cb" weak ref. */
738
- grpc_lb_policy_notify_on_state_change(exec_ctx, glb_policy->rr_policy,
739
- &rr_connectivity->state,
740
- &rr_connectivity->on_change);
737
+ grpc_lb_policy_notify_on_state_change_locked(
738
+ exec_ctx, glb_policy->rr_policy, &rr_connectivity->state,
739
+ &rr_connectivity->on_change);
741
740
  }
742
- gpr_mu_unlock(&glb_policy->mu);
743
741
  if (unref_needed) {
744
742
  GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
745
743
  "rr_connectivity_cb");
@@ -747,6 +745,96 @@ static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
747
745
  GRPC_ERROR_UNREF(error);
748
746
  }
749
747
 
748
+ static void destroy_balancer_name(grpc_exec_ctx *exec_ctx,
749
+ void *balancer_name) {
750
+ gpr_free(balancer_name);
751
+ }
752
+
753
+ static void *copy_balancer_name(void *balancer_name) {
754
+ return gpr_strdup(balancer_name);
755
+ }
756
+
757
+ static grpc_slice_hash_table_entry targets_info_entry_create(
758
+ const char *address, const char *balancer_name) {
759
+ static const grpc_slice_hash_table_vtable vtable = {destroy_balancer_name,
760
+ copy_balancer_name};
761
+ grpc_slice_hash_table_entry entry;
762
+ entry.key = grpc_slice_from_copied_string(address);
763
+ entry.value = (void *)balancer_name;
764
+ entry.vtable = &vtable;
765
+ return entry;
766
+ }
767
+
768
+ /* Returns the target URI for the LB service whose addresses are in \a
769
+ * addresses. Using this URI, a bidirectional streaming channel will be created
770
+ * for the reception of load balancing updates.
771
+ *
772
+ * The output argument \a targets_info will be updated to contain a mapping of
773
+ * "LB server address" to "balancer name", as reported by the naming system.
774
+ * This mapping will be propagated via the channel arguments of the
775
+ * aforementioned LB streaming channel, to be used by the security connector for
776
+ * secure naming checks. The user is responsible for freeing \a targets_info. */
777
+ static char *get_lb_uri_target_addresses(grpc_exec_ctx *exec_ctx,
778
+ const grpc_lb_addresses *addresses,
779
+ grpc_slice_hash_table **targets_info) {
780
+ size_t num_grpclb_addrs = 0;
781
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
782
+ if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
783
+ }
784
+ /* All input addresses come from a resolver that claims they are LB services.
785
+ * It's the resolver's responsibility to make sure this policy is only
786
+ * instantiated and used in that case. Otherwise, something has gone wrong. */
787
+ GPR_ASSERT(num_grpclb_addrs > 0);
788
+
789
+ grpc_slice_hash_table_entry *targets_info_entries =
790
+ gpr_malloc(sizeof(*targets_info_entries) * num_grpclb_addrs);
791
+
792
+ /* construct a target ipvX://ip1:port1,ip2:port2,... from the addresses in \a
793
+ * addresses */
794
+ /* TODO(dgq): support mixed ip version */
795
+ char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs);
796
+ size_t addr_index = 0;
797
+
798
+ for (size_t i = 0; i < addresses->num_addresses; i++) {
799
+ if (addresses->addresses[i].user_data != NULL) {
800
+ gpr_log(GPR_ERROR,
801
+ "This LB policy doesn't support user data. It will be ignored");
802
+ }
803
+ if (addresses->addresses[i].is_balancer) {
804
+ char *addr_str;
805
+ GPR_ASSERT(grpc_sockaddr_to_string(
806
+ &addr_str, &addresses->addresses[i].address, true) > 0);
807
+ targets_info_entries[addr_index] = targets_info_entry_create(
808
+ addr_str, addresses->addresses[i].balancer_name);
809
+ addr_strs[addr_index++] = addr_str;
810
+ }
811
+ }
812
+ GPR_ASSERT(addr_index == num_grpclb_addrs);
813
+
814
+ size_t uri_path_len;
815
+ char *uri_path = gpr_strjoin_sep((const char **)addr_strs, num_grpclb_addrs,
816
+ ",", &uri_path_len);
817
+ for (size_t i = 0; i < num_grpclb_addrs; i++) gpr_free(addr_strs[i]);
818
+ gpr_free(addr_strs);
819
+
820
+ char *target_uri_str = NULL;
821
+ /* TODO(dgq): Don't assume all addresses will share the scheme of the first
822
+ * one */
823
+ gpr_asprintf(&target_uri_str, "%s:%s",
824
+ grpc_sockaddr_get_uri_scheme(&addresses->addresses[0].address),
825
+ uri_path);
826
+ gpr_free(uri_path);
827
+
828
+ *targets_info =
829
+ grpc_slice_hash_table_create(num_grpclb_addrs, targets_info_entries);
830
+ for (size_t i = 0; i < num_grpclb_addrs; i++) {
831
+ grpc_slice_unref_internal(exec_ctx, targets_info_entries[i].key);
832
+ }
833
+ gpr_free(targets_info_entries);
834
+
835
+ return target_uri_str;
836
+ }
837
+
750
838
  static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
751
839
  grpc_lb_policy_factory *factory,
752
840
  grpc_lb_policy_args *args) {
@@ -767,14 +855,13 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
767
855
  }
768
856
  if (num_grpclb_addrs == 0) return NULL;
769
857
 
770
- glb_lb_policy *glb_policy = gpr_malloc(sizeof(*glb_policy));
771
- memset(glb_policy, 0, sizeof(*glb_policy));
858
+ glb_lb_policy *glb_policy = gpr_zalloc(sizeof(*glb_policy));
772
859
 
773
860
  /* Get server name. */
774
861
  arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
775
862
  GPR_ASSERT(arg != NULL);
776
863
  GPR_ASSERT(arg->type == GRPC_ARG_STRING);
777
- grpc_uri *uri = grpc_uri_parse(arg->value.string, true);
864
+ grpc_uri *uri = grpc_uri_parse(exec_ctx, arg->value.string, true);
778
865
  GPR_ASSERT(uri->path[0] != '\0');
779
866
  glb_policy->server_name =
780
867
  gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
@@ -784,85 +871,29 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
784
871
  }
785
872
  grpc_uri_destroy(uri);
786
873
 
787
- /* All input addresses in addresses come from a resolver that claims
788
- * they are LB services. It's the resolver's responsibility to make sure
789
- * this policy is only instantiated and used in that case.
790
- *
791
- * Create a client channel over them to communicate with a LB service */
792
874
  glb_policy->cc_factory = args->client_channel_factory;
793
875
  glb_policy->args = grpc_channel_args_copy(args->args);
794
876
  GPR_ASSERT(glb_policy->cc_factory != NULL);
795
877
 
796
- /* construct a target from the addresses in args, given in the form
797
- * ipvX://ip1:port1,ip2:port2,...
798
- * TODO(dgq): support mixed ip version */
799
- char **addr_strs = gpr_malloc(sizeof(char *) * num_grpclb_addrs);
800
- size_t addr_index = 0;
801
- for (size_t i = 0; i < addresses->num_addresses; i++) {
802
- if (addresses->addresses[i].user_data != NULL) {
803
- gpr_log(GPR_ERROR,
804
- "This LB policy doesn't support user data. It will be ignored");
805
- }
806
- if (addresses->addresses[i].is_balancer) {
807
- if (addr_index == 0) {
808
- addr_strs[addr_index++] =
809
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
810
- } else {
811
- GPR_ASSERT(grpc_sockaddr_to_string(&addr_strs[addr_index++],
812
- &addresses->addresses[i].address,
813
- true) > 0);
814
- }
815
- }
816
- }
817
- size_t uri_path_len;
818
- char *target_uri_str = gpr_strjoin_sep((const char **)addr_strs,
819
- num_grpclb_addrs, ",", &uri_path_len);
820
-
821
- /* Create a channel to talk to the LBs.
822
- *
823
- * We strip out the channel arg for the LB policy name, since we want
824
- * to use the default (pick_first) in this case.
825
- *
826
- * We also strip out the channel arg for the resolved addresses, since
827
- * that will be generated by the name resolver used in the LB channel.
828
- * Note that the LB channel will use the sockaddr resolver, so this
829
- * won't actually generate a query to DNS (or some other name service).
830
- * However, the addresses returned by the sockaddr resolver will have
831
- * is_balancer=false, whereas our own addresses have is_balancer=true.
832
- * We need the LB channel to return addresses with is_balancer=false
833
- * so that it does not wind up recursively using the grpclb LB policy,
834
- * as per the special case logic in client_channel.c.
835
- *
836
- * Finally, we also strip out the channel arg for the server URI,
837
- * since that will be different for the LB channel than for the parent
838
- * channel. (The client channel factory will re-add this arg with
839
- * the right value.)
840
- */
841
- static const char *keys_to_remove[] = {
842
- GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI};
843
- grpc_channel_args *new_args = grpc_channel_args_copy_and_remove(
844
- args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove));
845
- glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
846
- exec_ctx, glb_policy->cc_factory, target_uri_str,
847
- GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
848
- grpc_channel_args_destroy(exec_ctx, new_args);
849
-
850
- gpr_free(target_uri_str);
851
- for (size_t i = 0; i < num_grpclb_addrs; i++) {
852
- gpr_free(addr_strs[i]);
853
- }
854
- gpr_free(addr_strs);
855
-
878
+ grpc_slice_hash_table *targets_info = NULL;
879
+ /* Create a client channel over them to communicate with a LB service */
880
+ char *lb_service_target_addresses =
881
+ get_lb_uri_target_addresses(exec_ctx, addresses, &targets_info);
882
+ grpc_channel_args *lb_channel_args =
883
+ get_lb_channel_args(exec_ctx, targets_info, args->args);
884
+ glb_policy->lb_channel = grpc_lb_policy_grpclb_create_lb_channel(
885
+ exec_ctx, lb_service_target_addresses, args->client_channel_factory,
886
+ lb_channel_args);
887
+ grpc_slice_hash_table_unref(exec_ctx, targets_info);
888
+ grpc_channel_args_destroy(exec_ctx, lb_channel_args);
889
+ gpr_free(lb_service_target_addresses);
856
890
  if (glb_policy->lb_channel == NULL) {
857
891
  gpr_free(glb_policy);
858
892
  return NULL;
859
893
  }
860
-
861
- grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable);
862
- gpr_mu_init(&glb_policy->mu);
894
+ grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable, args->combiner);
863
895
  grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
864
896
  "grpclb");
865
-
866
897
  return &glb_policy->base;
867
898
  }
868
899
 
@@ -878,13 +909,11 @@ static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
878
909
  if (glb_policy->serverlist != NULL) {
879
910
  grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
880
911
  }
881
- gpr_mu_destroy(&glb_policy->mu);
882
912
  gpr_free(glb_policy);
883
913
  }
884
914
 
885
- static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
915
+ static void glb_shutdown_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
886
916
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
887
- gpr_mu_lock(&glb_policy->mu);
888
917
  glb_policy->shutting_down = true;
889
918
 
890
919
  pending_pick *pp = glb_policy->pending_picks;
@@ -901,7 +930,6 @@ static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
901
930
  * while holding glb_policy->mu: lb_on_server_status_received, invoked due to
902
931
  * the cancel, needs to acquire that same lock */
903
932
  grpc_call *lb_call = glb_policy->lb_call;
904
- gpr_mu_unlock(&glb_policy->mu);
905
933
 
906
934
  /* glb_policy->lb_call and this local lb_call must be consistent at this point
907
935
  * because glb_policy->lb_call is only assigned in lb_call_init_locked as part
@@ -927,11 +955,10 @@ static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
927
955
  }
928
956
  }
929
957
 
930
- static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
931
- grpc_connected_subchannel **target,
932
- grpc_error *error) {
958
+ static void glb_cancel_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
959
+ grpc_connected_subchannel **target,
960
+ grpc_error *error) {
933
961
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
934
- gpr_mu_lock(&glb_policy->mu);
935
962
  pending_pick *pp = glb_policy->pending_picks;
936
963
  glb_policy->pending_picks = NULL;
937
964
  while (pp != NULL) {
@@ -947,16 +974,15 @@ static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
947
974
  }
948
975
  pp = next;
949
976
  }
950
- gpr_mu_unlock(&glb_policy->mu);
951
977
  GRPC_ERROR_UNREF(error);
952
978
  }
953
979
 
954
- static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
955
- uint32_t initial_metadata_flags_mask,
956
- uint32_t initial_metadata_flags_eq,
957
- grpc_error *error) {
980
+ static void glb_cancel_picks_locked(grpc_exec_ctx *exec_ctx,
981
+ grpc_lb_policy *pol,
982
+ uint32_t initial_metadata_flags_mask,
983
+ uint32_t initial_metadata_flags_eq,
984
+ grpc_error *error) {
958
985
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
959
- gpr_mu_lock(&glb_policy->mu);
960
986
  pending_pick *pp = glb_policy->pending_picks;
961
987
  glb_policy->pending_picks = NULL;
962
988
  while (pp != NULL) {
@@ -972,7 +998,6 @@ static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
972
998
  }
973
999
  pp = next;
974
1000
  }
975
- gpr_mu_unlock(&glb_policy->mu);
976
1001
  GRPC_ERROR_UNREF(error);
977
1002
  }
978
1003
 
@@ -985,19 +1010,17 @@ static void start_picking_locked(grpc_exec_ctx *exec_ctx,
985
1010
  query_for_backends_locked(exec_ctx, glb_policy);
986
1011
  }
987
1012
 
988
- static void glb_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
1013
+ static void glb_exit_idle_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
989
1014
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
990
- gpr_mu_lock(&glb_policy->mu);
991
1015
  if (!glb_policy->started_picking) {
992
1016
  start_picking_locked(exec_ctx, glb_policy);
993
1017
  }
994
- gpr_mu_unlock(&glb_policy->mu);
995
1018
  }
996
1019
 
997
- static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
998
- const grpc_lb_policy_pick_args *pick_args,
999
- grpc_connected_subchannel **target, void **user_data,
1000
- grpc_closure *on_complete) {
1020
+ static int glb_pick_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1021
+ const grpc_lb_policy_pick_args *pick_args,
1022
+ grpc_connected_subchannel **target, void **user_data,
1023
+ grpc_closure *on_complete) {
1001
1024
  if (pick_args->lb_token_mdelem_storage == NULL) {
1002
1025
  *target = NULL;
1003
1026
  grpc_closure_sched(
@@ -1008,7 +1031,6 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1008
1031
  }
1009
1032
 
1010
1033
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
1011
- gpr_mu_lock(&glb_policy->mu);
1012
1034
  glb_policy->deadline = pick_args->deadline;
1013
1035
  bool pick_done;
1014
1036
 
@@ -1019,8 +1041,7 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1019
1041
  }
1020
1042
  GRPC_LB_POLICY_REF(glb_policy->rr_policy, "glb_pick");
1021
1043
 
1022
- wrapped_rr_closure_arg *wc_arg = gpr_malloc(sizeof(wrapped_rr_closure_arg));
1023
- memset(wc_arg, 0, sizeof(wrapped_rr_closure_arg));
1044
+ wrapped_rr_closure_arg *wc_arg = gpr_zalloc(sizeof(wrapped_rr_closure_arg));
1024
1045
 
1025
1046
  grpc_closure_init(&wc_arg->wrapper_closure, wrapped_rr_closure, wc_arg,
1026
1047
  grpc_schedule_on_exec_ctx);
@@ -1047,53 +1068,43 @@ static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1047
1068
  }
1048
1069
  pick_done = false;
1049
1070
  }
1050
- gpr_mu_unlock(&glb_policy->mu);
1051
1071
  return pick_done;
1052
1072
  }
1053
1073
 
1054
- static grpc_connectivity_state glb_check_connectivity(
1074
+ static grpc_connectivity_state glb_check_connectivity_locked(
1055
1075
  grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1056
1076
  grpc_error **connectivity_error) {
1057
1077
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
1058
- grpc_connectivity_state st;
1059
- gpr_mu_lock(&glb_policy->mu);
1060
- st = grpc_connectivity_state_check(&glb_policy->state_tracker,
1078
+ return grpc_connectivity_state_get(&glb_policy->state_tracker,
1061
1079
  connectivity_error);
1062
- gpr_mu_unlock(&glb_policy->mu);
1063
- return st;
1064
1080
  }
1065
1081
 
1066
- static void glb_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1067
- grpc_closure *closure) {
1082
+ static void glb_ping_one_locked(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
1083
+ grpc_closure *closure) {
1068
1084
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
1069
- gpr_mu_lock(&glb_policy->mu);
1070
1085
  if (glb_policy->rr_policy) {
1071
- grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy, closure);
1086
+ grpc_lb_policy_ping_one_locked(exec_ctx, glb_policy->rr_policy, closure);
1072
1087
  } else {
1073
1088
  add_pending_ping(&glb_policy->pending_pings, closure);
1074
1089
  if (!glb_policy->started_picking) {
1075
1090
  start_picking_locked(exec_ctx, glb_policy);
1076
1091
  }
1077
1092
  }
1078
- gpr_mu_unlock(&glb_policy->mu);
1079
1093
  }
1080
1094
 
1081
- static void glb_notify_on_state_change(grpc_exec_ctx *exec_ctx,
1082
- grpc_lb_policy *pol,
1083
- grpc_connectivity_state *current,
1084
- grpc_closure *notify) {
1095
+ static void glb_notify_on_state_change_locked(grpc_exec_ctx *exec_ctx,
1096
+ grpc_lb_policy *pol,
1097
+ grpc_connectivity_state *current,
1098
+ grpc_closure *notify) {
1085
1099
  glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
1086
- gpr_mu_lock(&glb_policy->mu);
1087
1100
  grpc_connectivity_state_notify_on_state_change(
1088
1101
  exec_ctx, &glb_policy->state_tracker, current, notify);
1089
-
1090
- gpr_mu_unlock(&glb_policy->mu);
1091
1102
  }
1092
1103
 
1093
- static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
1094
- grpc_error *error);
1095
- static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
1096
- grpc_error *error);
1104
+ static void lb_on_server_status_received_locked(grpc_exec_ctx *exec_ctx,
1105
+ void *arg, grpc_error *error);
1106
+ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
1107
+ grpc_error *error);
1097
1108
  static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
1098
1109
  glb_lb_policy *glb_policy) {
1099
1110
  GPR_ASSERT(glb_policy->server_name != NULL);
@@ -1103,11 +1114,12 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
1103
1114
  /* Note the following LB call progresses every time there's activity in \a
1104
1115
  * glb_policy->base.interested_parties, which is comprised of the polling
1105
1116
  * entities from \a client_channel. */
1117
+ grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
1106
1118
  glb_policy->lb_call = grpc_channel_create_pollset_set_call(
1107
1119
  exec_ctx, glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS,
1108
1120
  glb_policy->base.interested_parties,
1109
- "/grpc.lb.v1.LoadBalancer/BalanceLoad", glb_policy->server_name,
1110
- glb_policy->deadline, NULL);
1121
+ GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
1122
+ &host, glb_policy->deadline, NULL);
1111
1123
 
1112
1124
  grpc_metadata_array_init(&glb_policy->lb_initial_metadata_recv);
1113
1125
  grpc_metadata_array_init(&glb_policy->lb_trailing_metadata_recv);
@@ -1120,15 +1132,12 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
1120
1132
  grpc_slice_unref_internal(exec_ctx, request_payload_slice);
1121
1133
  grpc_grpclb_request_destroy(request);
1122
1134
 
1123
- glb_policy->lb_call_status_details = NULL;
1124
- glb_policy->lb_call_status_details_capacity = 0;
1125
-
1126
1135
  grpc_closure_init(&glb_policy->lb_on_server_status_received,
1127
- lb_on_server_status_received, glb_policy,
1128
- grpc_schedule_on_exec_ctx);
1136
+ lb_on_server_status_received_locked, glb_policy,
1137
+ grpc_combiner_scheduler(glb_policy->base.combiner, false));
1129
1138
  grpc_closure_init(&glb_policy->lb_on_response_received,
1130
- lb_on_response_received, glb_policy,
1131
- grpc_schedule_on_exec_ctx);
1139
+ lb_on_response_received_locked, glb_policy,
1140
+ grpc_combiner_scheduler(glb_policy->base.combiner, false));
1132
1141
 
1133
1142
  gpr_backoff_init(&glb_policy->lb_call_backoff_state,
1134
1143
  GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS,
@@ -1138,7 +1147,8 @@ static void lb_call_init_locked(grpc_exec_ctx *exec_ctx,
1138
1147
  GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
1139
1148
  }
1140
1149
 
1141
- static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
1150
+ static void lb_call_destroy_locked(grpc_exec_ctx *exec_ctx,
1151
+ glb_lb_policy *glb_policy) {
1142
1152
  GPR_ASSERT(glb_policy->lb_call != NULL);
1143
1153
  grpc_call_destroy(glb_policy->lb_call);
1144
1154
  glb_policy->lb_call = NULL;
@@ -1147,7 +1157,7 @@ static void lb_call_destroy_locked(glb_lb_policy *glb_policy) {
1147
1157
  grpc_metadata_array_destroy(&glb_policy->lb_trailing_metadata_recv);
1148
1158
 
1149
1159
  grpc_byte_buffer_destroy(glb_policy->lb_request_payload);
1150
- gpr_free(glb_policy->lb_call_status_details);
1160
+ grpc_slice_unref_internal(exec_ctx, glb_policy->lb_call_status_details);
1151
1161
  }
1152
1162
 
1153
1163
  /*
@@ -1197,8 +1207,6 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
1197
1207
  op->data.recv_status_on_client.status = &glb_policy->lb_call_status;
1198
1208
  op->data.recv_status_on_client.status_details =
1199
1209
  &glb_policy->lb_call_status_details;
1200
- op->data.recv_status_on_client.status_details_capacity =
1201
- &glb_policy->lb_call_status_details_capacity;
1202
1210
  op->flags = 0;
1203
1211
  op->reserved = NULL;
1204
1212
  op++;
@@ -1224,14 +1232,13 @@ static void query_for_backends_locked(grpc_exec_ctx *exec_ctx,
1224
1232
  GPR_ASSERT(GRPC_CALL_OK == call_error);
1225
1233
  }
1226
1234
 
1227
- static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
1228
- grpc_error *error) {
1235
+ static void lb_on_response_received_locked(grpc_exec_ctx *exec_ctx, void *arg,
1236
+ grpc_error *error) {
1229
1237
  glb_lb_policy *glb_policy = arg;
1230
1238
 
1231
1239
  grpc_op ops[2];
1232
1240
  memset(ops, 0, sizeof(ops));
1233
1241
  grpc_op *op = ops;
1234
- gpr_mu_lock(&glb_policy->mu);
1235
1242
  if (glb_policy->lb_response_payload != NULL) {
1236
1243
  gpr_backoff_reset(&glb_policy->lb_call_backoff_state);
1237
1244
  /* Received data from the LB server. Look inside
@@ -1305,20 +1312,17 @@ static void lb_on_response_received(grpc_exec_ctx *exec_ctx, void *arg,
1305
1312
  &glb_policy->lb_on_response_received); /* loop */
1306
1313
  GPR_ASSERT(GRPC_CALL_OK == call_error);
1307
1314
  }
1308
- gpr_mu_unlock(&glb_policy->mu);
1309
1315
  } else { /* empty payload: call cancelled. */
1310
1316
  /* dispose of the "lb_on_response_received" weak ref taken in
1311
1317
  * query_for_backends_locked() and reused in every reception loop */
1312
- gpr_mu_unlock(&glb_policy->mu);
1313
1318
  GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
1314
1319
  "lb_on_response_received_empty_payload");
1315
1320
  }
1316
1321
  }
1317
1322
 
1318
- static void lb_call_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg,
1319
- grpc_error *error) {
1323
+ static void lb_call_on_retry_timer_locked(grpc_exec_ctx *exec_ctx, void *arg,
1324
+ grpc_error *error) {
1320
1325
  glb_lb_policy *glb_policy = arg;
1321
- gpr_mu_lock(&glb_policy->mu);
1322
1326
 
1323
1327
  if (!glb_policy->shutting_down) {
1324
1328
  if (grpc_lb_glb_trace) {
@@ -1328,28 +1332,29 @@ static void lb_call_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg,
1328
1332
  GPR_ASSERT(glb_policy->lb_call == NULL);
1329
1333
  query_for_backends_locked(exec_ctx, glb_policy);
1330
1334
  }
1331
- gpr_mu_unlock(&glb_policy->mu);
1332
1335
  GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
1333
1336
  "grpclb_on_retry_timer");
1334
1337
  }
1335
1338
 
1336
- static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
1337
- grpc_error *error) {
1339
+ static void lb_on_server_status_received_locked(grpc_exec_ctx *exec_ctx,
1340
+ void *arg, grpc_error *error) {
1338
1341
  glb_lb_policy *glb_policy = arg;
1339
- gpr_mu_lock(&glb_policy->mu);
1340
1342
 
1341
1343
  GPR_ASSERT(glb_policy->lb_call != NULL);
1342
1344
 
1343
1345
  if (grpc_lb_glb_trace) {
1346
+ char *status_details =
1347
+ grpc_slice_to_c_string(glb_policy->lb_call_status_details);
1344
1348
  gpr_log(GPR_DEBUG,
1345
1349
  "Status from LB server received. Status = %d, Details = '%s', "
1346
1350
  "(call: %p)",
1347
- glb_policy->lb_call_status, glb_policy->lb_call_status_details,
1351
+ glb_policy->lb_call_status, status_details,
1348
1352
  (void *)glb_policy->lb_call);
1353
+ gpr_free(status_details);
1349
1354
  }
1350
1355
 
1351
- /* We need to performe cleanups no matter what. */
1352
- lb_call_destroy_locked(glb_policy);
1356
+ /* We need to perform cleanups no matter what. */
1357
+ lb_call_destroy_locked(exec_ctx, glb_policy);
1353
1358
 
1354
1359
  if (!glb_policy->shutting_down) {
1355
1360
  /* if we aren't shutting down, restart the LB client call after some time */
@@ -1368,21 +1373,27 @@ static void lb_on_server_status_received(grpc_exec_ctx *exec_ctx, void *arg,
1368
1373
  }
1369
1374
  }
1370
1375
  GRPC_LB_POLICY_WEAK_REF(&glb_policy->base, "grpclb_retry_timer");
1371
- grpc_closure_init(&glb_policy->lb_on_call_retry, lb_call_on_retry_timer,
1372
- glb_policy, grpc_schedule_on_exec_ctx);
1376
+ grpc_closure_init(
1377
+ &glb_policy->lb_on_call_retry, lb_call_on_retry_timer_locked,
1378
+ glb_policy, grpc_combiner_scheduler(glb_policy->base.combiner, false));
1373
1379
  grpc_timer_init(exec_ctx, &glb_policy->lb_call_retry_timer, next_try,
1374
1380
  &glb_policy->lb_on_call_retry, now);
1375
1381
  }
1376
- gpr_mu_unlock(&glb_policy->mu);
1377
1382
  GRPC_LB_POLICY_WEAK_UNREF(exec_ctx, &glb_policy->base,
1378
1383
  "lb_on_server_status_received");
1379
1384
  }
1380
1385
 
1381
1386
  /* Code wiring the policy with the rest of the core */
1382
1387
  static const grpc_lb_policy_vtable glb_lb_policy_vtable = {
1383
- glb_destroy, glb_shutdown, glb_pick,
1384
- glb_cancel_pick, glb_cancel_picks, glb_ping_one,
1385
- glb_exit_idle, glb_check_connectivity, glb_notify_on_state_change};
1388
+ glb_destroy,
1389
+ glb_shutdown_locked,
1390
+ glb_pick_locked,
1391
+ glb_cancel_pick_locked,
1392
+ glb_cancel_picks_locked,
1393
+ glb_ping_one_locked,
1394
+ glb_exit_idle_locked,
1395
+ glb_check_connectivity_locked,
1396
+ glb_notify_on_state_change_locked};
1386
1397
 
1387
1398
  static void glb_factory_ref(grpc_lb_policy_factory *factory) {}
1388
1399