grpc-z 1.11.1

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 (1318) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/Makefile +23896 -0
  4. data/etc/roots.pem +4475 -0
  5. data/include/grpc/byte_buffer.h +27 -0
  6. data/include/grpc/byte_buffer_reader.h +26 -0
  7. data/include/grpc/census.h +40 -0
  8. data/include/grpc/compression.h +75 -0
  9. data/include/grpc/fork.h +26 -0
  10. data/include/grpc/grpc.h +469 -0
  11. data/include/grpc/grpc_cronet.h +38 -0
  12. data/include/grpc/grpc_posix.h +67 -0
  13. data/include/grpc/grpc_security.h +495 -0
  14. data/include/grpc/grpc_security_constants.h +107 -0
  15. data/include/grpc/impl/codegen/atm.h +95 -0
  16. data/include/grpc/impl/codegen/atm_gcc_atomic.h +91 -0
  17. data/include/grpc/impl/codegen/atm_gcc_sync.h +83 -0
  18. data/include/grpc/impl/codegen/atm_windows.h +126 -0
  19. data/include/grpc/impl/codegen/byte_buffer.h +88 -0
  20. data/include/grpc/impl/codegen/byte_buffer_reader.h +42 -0
  21. data/include/grpc/impl/codegen/compression_types.h +107 -0
  22. data/include/grpc/impl/codegen/connectivity_state.h +44 -0
  23. data/include/grpc/impl/codegen/fork.h +48 -0
  24. data/include/grpc/impl/codegen/gpr_slice.h +69 -0
  25. data/include/grpc/impl/codegen/gpr_types.h +59 -0
  26. data/include/grpc/impl/codegen/grpc_types.h +669 -0
  27. data/include/grpc/impl/codegen/port_platform.h +507 -0
  28. data/include/grpc/impl/codegen/propagation_bits.h +52 -0
  29. data/include/grpc/impl/codegen/slice.h +147 -0
  30. data/include/grpc/impl/codegen/status.h +153 -0
  31. data/include/grpc/impl/codegen/sync.h +63 -0
  32. data/include/grpc/impl/codegen/sync_custom.h +38 -0
  33. data/include/grpc/impl/codegen/sync_generic.h +48 -0
  34. data/include/grpc/impl/codegen/sync_posix.h +34 -0
  35. data/include/grpc/impl/codegen/sync_windows.h +36 -0
  36. data/include/grpc/load_reporting.h +48 -0
  37. data/include/grpc/module.modulemap +74 -0
  38. data/include/grpc/slice.h +172 -0
  39. data/include/grpc/slice_buffer.h +84 -0
  40. data/include/grpc/status.h +26 -0
  41. data/include/grpc/support/alloc.h +68 -0
  42. data/include/grpc/support/atm.h +26 -0
  43. data/include/grpc/support/atm_gcc_atomic.h +26 -0
  44. data/include/grpc/support/atm_gcc_sync.h +26 -0
  45. data/include/grpc/support/atm_windows.h +26 -0
  46. data/include/grpc/support/cpu.h +44 -0
  47. data/include/grpc/support/log.h +104 -0
  48. data/include/grpc/support/log_windows.h +38 -0
  49. data/include/grpc/support/port_platform.h +24 -0
  50. data/include/grpc/support/string_util.h +49 -0
  51. data/include/grpc/support/sync.h +298 -0
  52. data/include/grpc/support/sync_custom.h +26 -0
  53. data/include/grpc/support/sync_generic.h +26 -0
  54. data/include/grpc/support/sync_posix.h +26 -0
  55. data/include/grpc/support/sync_windows.h +26 -0
  56. data/include/grpc/support/thd_id.h +44 -0
  57. data/include/grpc/support/time.h +92 -0
  58. data/include/grpc/support/workaround_list.h +31 -0
  59. data/src/boringssl/err_data.c +1348 -0
  60. data/src/core/ext/census/grpc_context.cc +38 -0
  61. data/src/core/ext/filters/client_channel/backup_poller.cc +174 -0
  62. data/src/core/ext/filters/client_channel/backup_poller.h +35 -0
  63. data/src/core/ext/filters/client_channel/channel_connectivity.cc +248 -0
  64. data/src/core/ext/filters/client_channel/client_channel.cc +3209 -0
  65. data/src/core/ext/filters/client_channel/client_channel.h +57 -0
  66. data/src/core/ext/filters/client_channel/client_channel_factory.cc +67 -0
  67. data/src/core/ext/filters/client_channel/client_channel_factory.h +74 -0
  68. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +62 -0
  69. data/src/core/ext/filters/client_channel/connector.cc +41 -0
  70. data/src/core/ext/filters/client_channel/connector.h +73 -0
  71. data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +370 -0
  72. data/src/core/ext/filters/client_channel/http_connect_handshaker.h +34 -0
  73. data/src/core/ext/filters/client_channel/http_proxy.cc +195 -0
  74. data/src/core/ext/filters/client_channel/http_proxy.h +24 -0
  75. data/src/core/ext/filters/client_channel/lb_policy.cc +59 -0
  76. data/src/core/ext/filters/client_channel/lb_policy.h +201 -0
  77. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +138 -0
  78. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h +29 -0
  79. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +1906 -0
  80. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +36 -0
  81. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +108 -0
  82. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +152 -0
  83. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +67 -0
  84. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +304 -0
  85. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +88 -0
  86. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +102 -0
  87. data/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +190 -0
  88. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +591 -0
  89. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +687 -0
  90. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc +253 -0
  91. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +136 -0
  92. data/src/core/ext/filters/client_channel/lb_policy_factory.cc +155 -0
  93. data/src/core/ext/filters/client_channel/lb_policy_factory.h +127 -0
  94. data/src/core/ext/filters/client_channel/lb_policy_registry.cc +97 -0
  95. data/src/core/ext/filters/client_channel/lb_policy_registry.h +54 -0
  96. data/src/core/ext/filters/client_channel/method_params.cc +178 -0
  97. data/src/core/ext/filters/client_channel/method_params.h +74 -0
  98. data/src/core/ext/filters/client_channel/parse_address.cc +192 -0
  99. data/src/core/ext/filters/client_channel/parse_address.h +50 -0
  100. data/src/core/ext/filters/client_channel/proxy_mapper.cc +48 -0
  101. data/src/core/ext/filters/client_channel/proxy_mapper.h +74 -0
  102. data/src/core/ext/filters/client_channel/proxy_mapper_registry.cc +122 -0
  103. data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +44 -0
  104. data/src/core/ext/filters/client_channel/resolver.cc +35 -0
  105. data/src/core/ext/filters/client_channel/resolver.h +134 -0
  106. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +493 -0
  107. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +53 -0
  108. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +351 -0
  109. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +593 -0
  110. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +74 -0
  111. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +59 -0
  112. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +340 -0
  113. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +297 -0
  114. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +83 -0
  115. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +214 -0
  116. data/src/core/ext/filters/client_channel/resolver_factory.h +71 -0
  117. data/src/core/ext/filters/client_channel/resolver_registry.cc +178 -0
  118. data/src/core/ext/filters/client_channel/resolver_registry.h +83 -0
  119. data/src/core/ext/filters/client_channel/retry_throttle.cc +191 -0
  120. data/src/core/ext/filters/client_channel/retry_throttle.h +77 -0
  121. data/src/core/ext/filters/client_channel/subchannel.cc +815 -0
  122. data/src/core/ext/filters/client_channel/subchannel.h +183 -0
  123. data/src/core/ext/filters/client_channel/subchannel_index.cc +254 -0
  124. data/src/core/ext/filters/client_channel/subchannel_index.h +79 -0
  125. data/src/core/ext/filters/client_channel/uri_parser.cc +314 -0
  126. data/src/core/ext/filters/client_channel/uri_parser.h +50 -0
  127. data/src/core/ext/filters/deadline/deadline_filter.cc +386 -0
  128. data/src/core/ext/filters/deadline/deadline_filter.h +93 -0
  129. data/src/core/ext/filters/http/client/http_client_filter.cc +558 -0
  130. data/src/core/ext/filters/http/client/http_client_filter.h +31 -0
  131. data/src/core/ext/filters/http/client_authority_filter.cc +156 -0
  132. data/src/core/ext/filters/http/client_authority_filter.h +34 -0
  133. data/src/core/ext/filters/http/http_filters_plugin.cc +89 -0
  134. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +499 -0
  135. data/src/core/ext/filters/http/message_compress/message_compress_filter.h +53 -0
  136. data/src/core/ext/filters/http/server/http_server_filter.cc +434 -0
  137. data/src/core/ext/filters/http/server/http_server_filter.h +29 -0
  138. data/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc +222 -0
  139. data/src/core/ext/filters/load_reporting/server_load_reporting_filter.h +30 -0
  140. data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.cc +71 -0
  141. data/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h +61 -0
  142. data/src/core/ext/filters/max_age/max_age_filter.cc +543 -0
  143. data/src/core/ext/filters/max_age/max_age_filter.h +26 -0
  144. data/src/core/ext/filters/message_size/message_size_filter.cc +324 -0
  145. data/src/core/ext/filters/message_size/message_size_filter.h +26 -0
  146. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc +208 -0
  147. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h +27 -0
  148. data/src/core/ext/filters/workarounds/workaround_utils.cc +53 -0
  149. data/src/core/ext/filters/workarounds/workaround_utils.h +39 -0
  150. data/src/core/ext/transport/chttp2/alpn/alpn.cc +44 -0
  151. data/src/core/ext/transport/chttp2/alpn/alpn.h +36 -0
  152. data/src/core/ext/transport/chttp2/client/authority.cc +42 -0
  153. data/src/core/ext/transport/chttp2/client/authority.h +36 -0
  154. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +229 -0
  155. data/src/core/ext/transport/chttp2/client/chttp2_connector.h +28 -0
  156. data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +110 -0
  157. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc +79 -0
  158. data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +230 -0
  159. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +353 -0
  160. data/src/core/ext/transport/chttp2/server/chttp2_server.h +33 -0
  161. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +45 -0
  162. data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +74 -0
  163. data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +89 -0
  164. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +249 -0
  165. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +56 -0
  166. data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +231 -0
  167. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +41 -0
  168. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +35 -0
  169. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3102 -0
  170. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +45 -0
  171. data/src/core/ext/transport/chttp2/transport/flow_control.cc +405 -0
  172. data/src/core/ext/transport/chttp2/transport/flow_control.h +482 -0
  173. data/src/core/ext/transport/chttp2/transport/frame.h +47 -0
  174. data/src/core/ext/transport/chttp2/transport/frame_data.cc +314 -0
  175. data/src/core/ext/transport/chttp2/transport/frame_data.h +84 -0
  176. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +186 -0
  177. data/src/core/ext/transport/chttp2/transport/frame_goaway.h +62 -0
  178. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +131 -0
  179. data/src/core/ext/transport/chttp2/transport/frame_ping.h +45 -0
  180. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +112 -0
  181. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +43 -0
  182. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +238 -0
  183. data/src/core/ext/transport/chttp2/transport/frame_settings.h +60 -0
  184. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +122 -0
  185. data/src/core/ext/transport/chttp2/transport/frame_window_update.h +45 -0
  186. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +699 -0
  187. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +95 -0
  188. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1680 -0
  189. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +109 -0
  190. data/src/core/ext/transport/chttp2/transport/hpack_table.cc +368 -0
  191. data/src/core/ext/transport/chttp2/transport/hpack_table.h +95 -0
  192. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +62 -0
  193. data/src/core/ext/transport/chttp2/transport/http2_settings.h +62 -0
  194. data/src/core/ext/transport/chttp2/transport/huffsyms.cc +92 -0
  195. data/src/core/ext/transport/chttp2/transport/huffsyms.h +33 -0
  196. data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +73 -0
  197. data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +49 -0
  198. data/src/core/ext/transport/chttp2/transport/internal.h +799 -0
  199. data/src/core/ext/transport/chttp2/transport/parsing.cc +745 -0
  200. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +216 -0
  201. data/src/core/ext/transport/chttp2/transport/stream_map.cc +167 -0
  202. data/src/core/ext/transport/chttp2/transport/stream_map.h +68 -0
  203. data/src/core/ext/transport/chttp2/transport/varint.cc +56 -0
  204. data/src/core/ext/transport/chttp2/transport/varint.h +60 -0
  205. data/src/core/ext/transport/chttp2/transport/writing.cc +641 -0
  206. data/src/core/ext/transport/inproc/inproc_plugin.cc +28 -0
  207. data/src/core/ext/transport/inproc/inproc_transport.cc +1240 -0
  208. data/src/core/ext/transport/inproc/inproc_transport.h +35 -0
  209. data/src/core/lib/avl/avl.cc +306 -0
  210. data/src/core/lib/avl/avl.h +94 -0
  211. data/src/core/lib/backoff/backoff.cc +78 -0
  212. data/src/core/lib/backoff/backoff.h +89 -0
  213. data/src/core/lib/channel/channel_args.cc +413 -0
  214. data/src/core/lib/channel/channel_args.h +127 -0
  215. data/src/core/lib/channel/channel_stack.cc +258 -0
  216. data/src/core/lib/channel/channel_stack.h +280 -0
  217. data/src/core/lib/channel/channel_stack_builder.cc +314 -0
  218. data/src/core/lib/channel/channel_stack_builder.h +160 -0
  219. data/src/core/lib/channel/channel_trace.cc +239 -0
  220. data/src/core/lib/channel/channel_trace.h +133 -0
  221. data/src/core/lib/channel/channel_trace_registry.cc +80 -0
  222. data/src/core/lib/channel/channel_trace_registry.h +43 -0
  223. data/src/core/lib/channel/connected_channel.cc +236 -0
  224. data/src/core/lib/channel/connected_channel.h +34 -0
  225. data/src/core/lib/channel/context.h +49 -0
  226. data/src/core/lib/channel/handshaker.cc +259 -0
  227. data/src/core/lib/channel/handshaker.h +166 -0
  228. data/src/core/lib/channel/handshaker_factory.cc +41 -0
  229. data/src/core/lib/channel/handshaker_factory.h +50 -0
  230. data/src/core/lib/channel/handshaker_registry.cc +97 -0
  231. data/src/core/lib/channel/handshaker_registry.h +48 -0
  232. data/src/core/lib/channel/status_util.cc +100 -0
  233. data/src/core/lib/channel/status_util.h +58 -0
  234. data/src/core/lib/compression/algorithm_metadata.h +61 -0
  235. data/src/core/lib/compression/compression.cc +174 -0
  236. data/src/core/lib/compression/compression_internal.cc +276 -0
  237. data/src/core/lib/compression/compression_internal.h +88 -0
  238. data/src/core/lib/compression/message_compress.cc +187 -0
  239. data/src/core/lib/compression/message_compress.h +40 -0
  240. data/src/core/lib/compression/stream_compression.cc +79 -0
  241. data/src/core/lib/compression/stream_compression.h +116 -0
  242. data/src/core/lib/compression/stream_compression_gzip.cc +230 -0
  243. data/src/core/lib/compression/stream_compression_gzip.h +28 -0
  244. data/src/core/lib/compression/stream_compression_identity.cc +94 -0
  245. data/src/core/lib/compression/stream_compression_identity.h +29 -0
  246. data/src/core/lib/debug/stats.cc +178 -0
  247. data/src/core/lib/debug/stats.h +61 -0
  248. data/src/core/lib/debug/stats_data.cc +682 -0
  249. data/src/core/lib/debug/stats_data.h +435 -0
  250. data/src/core/lib/debug/trace.cc +144 -0
  251. data/src/core/lib/debug/trace.h +104 -0
  252. data/src/core/lib/gpr/alloc.cc +99 -0
  253. data/src/core/lib/gpr/arena.cc +152 -0
  254. data/src/core/lib/gpr/arena.h +41 -0
  255. data/src/core/lib/gpr/atm.cc +35 -0
  256. data/src/core/lib/gpr/cpu_iphone.cc +36 -0
  257. data/src/core/lib/gpr/cpu_linux.cc +82 -0
  258. data/src/core/lib/gpr/cpu_posix.cc +81 -0
  259. data/src/core/lib/gpr/cpu_windows.cc +33 -0
  260. data/src/core/lib/gpr/env.h +43 -0
  261. data/src/core/lib/gpr/env_linux.cc +82 -0
  262. data/src/core/lib/gpr/env_posix.cc +47 -0
  263. data/src/core/lib/gpr/env_windows.cc +72 -0
  264. data/src/core/lib/gpr/fork.cc +78 -0
  265. data/src/core/lib/gpr/fork.h +35 -0
  266. data/src/core/lib/gpr/host_port.cc +98 -0
  267. data/src/core/lib/gpr/host_port.h +43 -0
  268. data/src/core/lib/gpr/log.cc +96 -0
  269. data/src/core/lib/gpr/log_android.cc +72 -0
  270. data/src/core/lib/gpr/log_linux.cc +93 -0
  271. data/src/core/lib/gpr/log_posix.cc +90 -0
  272. data/src/core/lib/gpr/log_windows.cc +97 -0
  273. data/src/core/lib/gpr/mpscq.cc +117 -0
  274. data/src/core/lib/gpr/mpscq.h +86 -0
  275. data/src/core/lib/gpr/murmur_hash.cc +80 -0
  276. data/src/core/lib/gpr/murmur_hash.h +29 -0
  277. data/src/core/lib/gpr/spinlock.h +46 -0
  278. data/src/core/lib/gpr/string.cc +319 -0
  279. data/src/core/lib/gpr/string.h +109 -0
  280. data/src/core/lib/gpr/string_posix.cc +72 -0
  281. data/src/core/lib/gpr/string_util_windows.cc +82 -0
  282. data/src/core/lib/gpr/string_windows.cc +69 -0
  283. data/src/core/lib/gpr/string_windows.h +32 -0
  284. data/src/core/lib/gpr/sync.cc +124 -0
  285. data/src/core/lib/gpr/sync_posix.cc +107 -0
  286. data/src/core/lib/gpr/sync_windows.cc +118 -0
  287. data/src/core/lib/gpr/time.cc +251 -0
  288. data/src/core/lib/gpr/time_posix.cc +167 -0
  289. data/src/core/lib/gpr/time_precise.cc +78 -0
  290. data/src/core/lib/gpr/time_precise.h +29 -0
  291. data/src/core/lib/gpr/time_windows.cc +98 -0
  292. data/src/core/lib/gpr/tls.h +68 -0
  293. data/src/core/lib/gpr/tls_gcc.h +52 -0
  294. data/src/core/lib/gpr/tls_msvc.h +52 -0
  295. data/src/core/lib/gpr/tls_pthread.cc +30 -0
  296. data/src/core/lib/gpr/tls_pthread.h +56 -0
  297. data/src/core/lib/gpr/tmpfile.h +32 -0
  298. data/src/core/lib/gpr/tmpfile_msys.cc +58 -0
  299. data/src/core/lib/gpr/tmpfile_posix.cc +70 -0
  300. data/src/core/lib/gpr/tmpfile_windows.cc +69 -0
  301. data/src/core/lib/gpr/useful.h +65 -0
  302. data/src/core/lib/gpr/wrap_memcpy.cc +42 -0
  303. data/src/core/lib/gprpp/abstract.h +34 -0
  304. data/src/core/lib/gprpp/atomic.h +30 -0
  305. data/src/core/lib/gprpp/atomic_with_atm.h +57 -0
  306. data/src/core/lib/gprpp/atomic_with_std.h +35 -0
  307. data/src/core/lib/gprpp/debug_location.h +52 -0
  308. data/src/core/lib/gprpp/inlined_vector.h +136 -0
  309. data/src/core/lib/gprpp/manual_constructor.h +213 -0
  310. data/src/core/lib/gprpp/memory.h +111 -0
  311. data/src/core/lib/gprpp/orphanable.h +199 -0
  312. data/src/core/lib/gprpp/ref_counted.h +169 -0
  313. data/src/core/lib/gprpp/ref_counted_ptr.h +112 -0
  314. data/src/core/lib/gprpp/thd.h +135 -0
  315. data/src/core/lib/gprpp/thd_posix.cc +209 -0
  316. data/src/core/lib/gprpp/thd_windows.cc +162 -0
  317. data/src/core/lib/http/format_request.cc +122 -0
  318. data/src/core/lib/http/format_request.h +34 -0
  319. data/src/core/lib/http/httpcli.cc +303 -0
  320. data/src/core/lib/http/httpcli.h +127 -0
  321. data/src/core/lib/http/httpcli_security_connector.cc +202 -0
  322. data/src/core/lib/http/parser.cc +371 -0
  323. data/src/core/lib/http/parser.h +113 -0
  324. data/src/core/lib/iomgr/block_annotate.h +57 -0
  325. data/src/core/lib/iomgr/call_combiner.cc +212 -0
  326. data/src/core/lib/iomgr/call_combiner.h +112 -0
  327. data/src/core/lib/iomgr/closure.h +351 -0
  328. data/src/core/lib/iomgr/combiner.cc +358 -0
  329. data/src/core/lib/iomgr/combiner.h +66 -0
  330. data/src/core/lib/iomgr/endpoint.cc +63 -0
  331. data/src/core/lib/iomgr/endpoint.h +98 -0
  332. data/src/core/lib/iomgr/endpoint_pair.h +34 -0
  333. data/src/core/lib/iomgr/endpoint_pair_posix.cc +73 -0
  334. data/src/core/lib/iomgr/endpoint_pair_uv.cc +40 -0
  335. data/src/core/lib/iomgr/endpoint_pair_windows.cc +87 -0
  336. data/src/core/lib/iomgr/error.cc +793 -0
  337. data/src/core/lib/iomgr/error.h +207 -0
  338. data/src/core/lib/iomgr/error_internal.h +63 -0
  339. data/src/core/lib/iomgr/ev_epoll1_linux.cc +1248 -0
  340. data/src/core/lib/iomgr/ev_epoll1_linux.h +31 -0
  341. data/src/core/lib/iomgr/ev_epollex_linux.cc +1494 -0
  342. data/src/core/lib/iomgr/ev_epollex_linux.h +30 -0
  343. data/src/core/lib/iomgr/ev_epollsig_linux.cc +1735 -0
  344. data/src/core/lib/iomgr/ev_epollsig_linux.h +35 -0
  345. data/src/core/lib/iomgr/ev_poll_posix.cc +1758 -0
  346. data/src/core/lib/iomgr/ev_poll_posix.h +29 -0
  347. data/src/core/lib/iomgr/ev_posix.cc +330 -0
  348. data/src/core/lib/iomgr/ev_posix.h +145 -0
  349. data/src/core/lib/iomgr/ev_windows.cc +30 -0
  350. data/src/core/lib/iomgr/exec_ctx.cc +147 -0
  351. data/src/core/lib/iomgr/exec_ctx.h +210 -0
  352. data/src/core/lib/iomgr/executor.cc +301 -0
  353. data/src/core/lib/iomgr/executor.h +50 -0
  354. data/src/core/lib/iomgr/fork_posix.cc +89 -0
  355. data/src/core/lib/iomgr/fork_windows.cc +41 -0
  356. data/src/core/lib/iomgr/gethostname.h +26 -0
  357. data/src/core/lib/iomgr/gethostname_fallback.cc +30 -0
  358. data/src/core/lib/iomgr/gethostname_host_name_max.cc +40 -0
  359. data/src/core/lib/iomgr/gethostname_sysconf.cc +40 -0
  360. data/src/core/lib/iomgr/iocp_windows.cc +152 -0
  361. data/src/core/lib/iomgr/iocp_windows.h +48 -0
  362. data/src/core/lib/iomgr/iomgr.cc +178 -0
  363. data/src/core/lib/iomgr/iomgr.h +36 -0
  364. data/src/core/lib/iomgr/iomgr_custom.cc +63 -0
  365. data/src/core/lib/iomgr/iomgr_custom.h +47 -0
  366. data/src/core/lib/iomgr/iomgr_internal.cc +43 -0
  367. data/src/core/lib/iomgr/iomgr_internal.h +57 -0
  368. data/src/core/lib/iomgr/iomgr_posix.cc +67 -0
  369. data/src/core/lib/iomgr/iomgr_posix.h +26 -0
  370. data/src/core/lib/iomgr/iomgr_uv.cc +40 -0
  371. data/src/core/lib/iomgr/iomgr_windows.cc +87 -0
  372. data/src/core/lib/iomgr/is_epollexclusive_available.cc +104 -0
  373. data/src/core/lib/iomgr/is_epollexclusive_available.h +36 -0
  374. data/src/core/lib/iomgr/load_file.cc +80 -0
  375. data/src/core/lib/iomgr/load_file.h +35 -0
  376. data/src/core/lib/iomgr/lockfree_event.cc +250 -0
  377. data/src/core/lib/iomgr/lockfree_event.h +72 -0
  378. data/src/core/lib/iomgr/nameser.h +106 -0
  379. data/src/core/lib/iomgr/network_status_tracker.cc +36 -0
  380. data/src/core/lib/iomgr/network_status_tracker.h +32 -0
  381. data/src/core/lib/iomgr/polling_entity.cc +87 -0
  382. data/src/core/lib/iomgr/polling_entity.h +68 -0
  383. data/src/core/lib/iomgr/pollset.cc +56 -0
  384. data/src/core/lib/iomgr/pollset.h +99 -0
  385. data/src/core/lib/iomgr/pollset_custom.cc +106 -0
  386. data/src/core/lib/iomgr/pollset_custom.h +35 -0
  387. data/src/core/lib/iomgr/pollset_set.cc +55 -0
  388. data/src/core/lib/iomgr/pollset_set.h +55 -0
  389. data/src/core/lib/iomgr/pollset_set_custom.cc +48 -0
  390. data/src/core/lib/iomgr/pollset_set_custom.h +26 -0
  391. data/src/core/lib/iomgr/pollset_set_windows.cc +51 -0
  392. data/src/core/lib/iomgr/pollset_set_windows.h +26 -0
  393. data/src/core/lib/iomgr/pollset_uv.cc +93 -0
  394. data/src/core/lib/iomgr/pollset_windows.cc +229 -0
  395. data/src/core/lib/iomgr/pollset_windows.h +70 -0
  396. data/src/core/lib/iomgr/port.h +147 -0
  397. data/src/core/lib/iomgr/resolve_address.cc +50 -0
  398. data/src/core/lib/iomgr/resolve_address.h +83 -0
  399. data/src/core/lib/iomgr/resolve_address_custom.cc +187 -0
  400. data/src/core/lib/iomgr/resolve_address_custom.h +43 -0
  401. data/src/core/lib/iomgr/resolve_address_posix.cc +180 -0
  402. data/src/core/lib/iomgr/resolve_address_windows.cc +165 -0
  403. data/src/core/lib/iomgr/resource_quota.cc +871 -0
  404. data/src/core/lib/iomgr/resource_quota.h +142 -0
  405. data/src/core/lib/iomgr/sockaddr.h +32 -0
  406. data/src/core/lib/iomgr/sockaddr_custom.h +54 -0
  407. data/src/core/lib/iomgr/sockaddr_posix.h +55 -0
  408. data/src/core/lib/iomgr/sockaddr_utils.cc +298 -0
  409. data/src/core/lib/iomgr/sockaddr_utils.h +84 -0
  410. data/src/core/lib/iomgr/sockaddr_windows.h +55 -0
  411. data/src/core/lib/iomgr/socket_factory_posix.cc +94 -0
  412. data/src/core/lib/iomgr/socket_factory_posix.h +69 -0
  413. data/src/core/lib/iomgr/socket_mutator.cc +83 -0
  414. data/src/core/lib/iomgr/socket_mutator.h +61 -0
  415. data/src/core/lib/iomgr/socket_utils.h +38 -0
  416. data/src/core/lib/iomgr/socket_utils_common_posix.cc +327 -0
  417. data/src/core/lib/iomgr/socket_utils_linux.cc +43 -0
  418. data/src/core/lib/iomgr/socket_utils_posix.cc +59 -0
  419. data/src/core/lib/iomgr/socket_utils_posix.h +134 -0
  420. data/src/core/lib/iomgr/socket_utils_uv.cc +45 -0
  421. data/src/core/lib/iomgr/socket_utils_windows.cc +43 -0
  422. data/src/core/lib/iomgr/socket_windows.cc +151 -0
  423. data/src/core/lib/iomgr/socket_windows.h +113 -0
  424. data/src/core/lib/iomgr/sys_epoll_wrapper.h +30 -0
  425. data/src/core/lib/iomgr/tcp_client.cc +36 -0
  426. data/src/core/lib/iomgr/tcp_client.h +52 -0
  427. data/src/core/lib/iomgr/tcp_client_custom.cc +151 -0
  428. data/src/core/lib/iomgr/tcp_client_posix.cc +359 -0
  429. data/src/core/lib/iomgr/tcp_client_posix.h +68 -0
  430. data/src/core/lib/iomgr/tcp_client_windows.cc +231 -0
  431. data/src/core/lib/iomgr/tcp_custom.cc +365 -0
  432. data/src/core/lib/iomgr/tcp_custom.h +81 -0
  433. data/src/core/lib/iomgr/tcp_posix.cc +814 -0
  434. data/src/core/lib/iomgr/tcp_posix.h +57 -0
  435. data/src/core/lib/iomgr/tcp_server.cc +73 -0
  436. data/src/core/lib/iomgr/tcp_server.h +122 -0
  437. data/src/core/lib/iomgr/tcp_server_custom.cc +472 -0
  438. data/src/core/lib/iomgr/tcp_server_posix.cc +582 -0
  439. data/src/core/lib/iomgr/tcp_server_utils_posix.h +122 -0
  440. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +208 -0
  441. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +184 -0
  442. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc +36 -0
  443. data/src/core/lib/iomgr/tcp_server_windows.cc +559 -0
  444. data/src/core/lib/iomgr/tcp_uv.cc +417 -0
  445. data/src/core/lib/iomgr/tcp_windows.cc +455 -0
  446. data/src/core/lib/iomgr/tcp_windows.h +51 -0
  447. data/src/core/lib/iomgr/time_averaged_stats.cc +64 -0
  448. data/src/core/lib/iomgr/time_averaged_stats.h +73 -0
  449. data/src/core/lib/iomgr/timer.cc +45 -0
  450. data/src/core/lib/iomgr/timer.h +125 -0
  451. data/src/core/lib/iomgr/timer_custom.cc +93 -0
  452. data/src/core/lib/iomgr/timer_custom.h +43 -0
  453. data/src/core/lib/iomgr/timer_generic.cc +663 -0
  454. data/src/core/lib/iomgr/timer_heap.cc +135 -0
  455. data/src/core/lib/iomgr/timer_heap.h +44 -0
  456. data/src/core/lib/iomgr/timer_manager.cc +347 -0
  457. data/src/core/lib/iomgr/timer_manager.h +39 -0
  458. data/src/core/lib/iomgr/timer_uv.cc +63 -0
  459. data/src/core/lib/iomgr/udp_server.cc +692 -0
  460. data/src/core/lib/iomgr/udp_server.h +103 -0
  461. data/src/core/lib/iomgr/unix_sockets_posix.cc +104 -0
  462. data/src/core/lib/iomgr/unix_sockets_posix.h +43 -0
  463. data/src/core/lib/iomgr/unix_sockets_posix_noop.cc +49 -0
  464. data/src/core/lib/iomgr/wakeup_fd_cv.cc +107 -0
  465. data/src/core/lib/iomgr/wakeup_fd_cv.h +69 -0
  466. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +83 -0
  467. data/src/core/lib/iomgr/wakeup_fd_nospecial.cc +38 -0
  468. data/src/core/lib/iomgr/wakeup_fd_pipe.cc +100 -0
  469. data/src/core/lib/iomgr/wakeup_fd_pipe.h +28 -0
  470. data/src/core/lib/iomgr/wakeup_fd_posix.cc +87 -0
  471. data/src/core/lib/iomgr/wakeup_fd_posix.h +96 -0
  472. data/src/core/lib/json/json.cc +86 -0
  473. data/src/core/lib/json/json.h +94 -0
  474. data/src/core/lib/json/json_common.h +34 -0
  475. data/src/core/lib/json/json_reader.cc +663 -0
  476. data/src/core/lib/json/json_reader.h +146 -0
  477. data/src/core/lib/json/json_string.cc +367 -0
  478. data/src/core/lib/json/json_writer.cc +245 -0
  479. data/src/core/lib/json/json_writer.h +84 -0
  480. data/src/core/lib/profiling/basic_timers.cc +286 -0
  481. data/src/core/lib/profiling/stap_timers.cc +50 -0
  482. data/src/core/lib/profiling/timers.h +94 -0
  483. data/src/core/lib/security/context/security_context.cc +348 -0
  484. data/src/core/lib/security/context/security_context.h +115 -0
  485. data/src/core/lib/security/credentials/alts/alts_credentials.cc +119 -0
  486. data/src/core/lib/security/credentials/alts/alts_credentials.h +102 -0
  487. data/src/core/lib/security/credentials/alts/check_gcp_environment.cc +72 -0
  488. data/src/core/lib/security/credentials/alts/check_gcp_environment.h +57 -0
  489. data/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc +67 -0
  490. data/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc +33 -0
  491. data/src/core/lib/security/credentials/alts/check_gcp_environment_windows.cc +114 -0
  492. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_client_options.cc +126 -0
  493. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.cc +46 -0
  494. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h +112 -0
  495. data/src/core/lib/security/credentials/alts/grpc_alts_credentials_server_options.cc +58 -0
  496. data/src/core/lib/security/credentials/composite/composite_credentials.cc +269 -0
  497. data/src/core/lib/security/credentials/composite/composite_credentials.h +59 -0
  498. data/src/core/lib/security/credentials/credentials.cc +286 -0
  499. data/src/core/lib/security/credentials/credentials.h +246 -0
  500. data/src/core/lib/security/credentials/credentials_metadata.cc +62 -0
  501. data/src/core/lib/security/credentials/fake/fake_credentials.cc +136 -0
  502. data/src/core/lib/security/credentials/fake/fake_credentials.h +64 -0
  503. data/src/core/lib/security/credentials/google_default/credentials_generic.cc +41 -0
  504. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +322 -0
  505. data/src/core/lib/security/credentials/google_default/google_default_credentials.h +45 -0
  506. data/src/core/lib/security/credentials/iam/iam_credentials.cc +86 -0
  507. data/src/core/lib/security/credentials/iam/iam_credentials.h +31 -0
  508. data/src/core/lib/security/credentials/jwt/json_token.cc +314 -0
  509. data/src/core/lib/security/credentials/jwt/json_token.h +75 -0
  510. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +190 -0
  511. data/src/core/lib/security/credentials/jwt/jwt_credentials.h +49 -0
  512. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +934 -0
  513. data/src/core/lib/security/credentials/jwt/jwt_verifier.h +123 -0
  514. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +532 -0
  515. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +106 -0
  516. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +271 -0
  517. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +46 -0
  518. data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +349 -0
  519. data/src/core/lib/security/credentials/ssl/ssl_credentials.h +54 -0
  520. data/src/core/lib/security/security_connector/alts_security_connector.cc +287 -0
  521. data/src/core/lib/security/security_connector/alts_security_connector.h +69 -0
  522. data/src/core/lib/security/security_connector/security_connector.cc +1200 -0
  523. data/src/core/lib/security/security_connector/security_connector.h +283 -0
  524. data/src/core/lib/security/transport/auth_filters.h +37 -0
  525. data/src/core/lib/security/transport/client_auth_filter.cc +418 -0
  526. data/src/core/lib/security/transport/secure_endpoint.cc +429 -0
  527. data/src/core/lib/security/transport/secure_endpoint.h +41 -0
  528. data/src/core/lib/security/transport/security_handshaker.cc +526 -0
  529. data/src/core/lib/security/transport/security_handshaker.h +34 -0
  530. data/src/core/lib/security/transport/server_auth_filter.cc +269 -0
  531. data/src/core/lib/security/transport/target_authority_table.cc +75 -0
  532. data/src/core/lib/security/transport/target_authority_table.h +40 -0
  533. data/src/core/lib/security/transport/tsi_error.cc +29 -0
  534. data/src/core/lib/security/transport/tsi_error.h +29 -0
  535. data/src/core/lib/security/util/json_util.cc +48 -0
  536. data/src/core/lib/security/util/json_util.h +42 -0
  537. data/src/core/lib/slice/b64.cc +240 -0
  538. data/src/core/lib/slice/b64.h +51 -0
  539. data/src/core/lib/slice/percent_encoding.cc +169 -0
  540. data/src/core/lib/slice/percent_encoding.h +65 -0
  541. data/src/core/lib/slice/slice.cc +489 -0
  542. data/src/core/lib/slice/slice_buffer.cc +359 -0
  543. data/src/core/lib/slice/slice_hash_table.h +201 -0
  544. data/src/core/lib/slice/slice_intern.cc +332 -0
  545. data/src/core/lib/slice/slice_internal.h +49 -0
  546. data/src/core/lib/slice/slice_string_helpers.cc +118 -0
  547. data/src/core/lib/slice/slice_string_helpers.h +47 -0
  548. data/src/core/lib/slice/slice_weak_hash_table.h +105 -0
  549. data/src/core/lib/surface/api_trace.cc +24 -0
  550. data/src/core/lib/surface/api_trace.h +52 -0
  551. data/src/core/lib/surface/byte_buffer.cc +92 -0
  552. data/src/core/lib/surface/byte_buffer_reader.cc +129 -0
  553. data/src/core/lib/surface/call.cc +2002 -0
  554. data/src/core/lib/surface/call.h +109 -0
  555. data/src/core/lib/surface/call_details.cc +42 -0
  556. data/src/core/lib/surface/call_log_batch.cc +120 -0
  557. data/src/core/lib/surface/call_test_only.h +43 -0
  558. data/src/core/lib/surface/channel.cc +450 -0
  559. data/src/core/lib/surface/channel.h +83 -0
  560. data/src/core/lib/surface/channel_init.cc +109 -0
  561. data/src/core/lib/surface/channel_init.h +73 -0
  562. data/src/core/lib/surface/channel_ping.cc +65 -0
  563. data/src/core/lib/surface/channel_stack_type.cc +58 -0
  564. data/src/core/lib/surface/channel_stack_type.h +47 -0
  565. data/src/core/lib/surface/completion_queue.cc +1262 -0
  566. data/src/core/lib/surface/completion_queue.h +93 -0
  567. data/src/core/lib/surface/completion_queue_factory.cc +79 -0
  568. data/src/core/lib/surface/completion_queue_factory.h +38 -0
  569. data/src/core/lib/surface/event_string.cc +68 -0
  570. data/src/core/lib/surface/event_string.h +29 -0
  571. data/src/core/lib/surface/init.cc +196 -0
  572. data/src/core/lib/surface/init.h +27 -0
  573. data/src/core/lib/surface/init_secure.cc +81 -0
  574. data/src/core/lib/surface/lame_client.cc +180 -0
  575. data/src/core/lib/surface/lame_client.h +28 -0
  576. data/src/core/lib/surface/metadata_array.cc +36 -0
  577. data/src/core/lib/surface/server.cc +1445 -0
  578. data/src/core/lib/surface/server.h +58 -0
  579. data/src/core/lib/surface/validate_metadata.cc +95 -0
  580. data/src/core/lib/surface/validate_metadata.h +30 -0
  581. data/src/core/lib/surface/version.cc +28 -0
  582. data/src/core/lib/transport/bdp_estimator.cc +87 -0
  583. data/src/core/lib/transport/bdp_estimator.h +94 -0
  584. data/src/core/lib/transport/byte_stream.cc +160 -0
  585. data/src/core/lib/transport/byte_stream.h +164 -0
  586. data/src/core/lib/transport/connectivity_state.cc +196 -0
  587. data/src/core/lib/transport/connectivity_state.h +87 -0
  588. data/src/core/lib/transport/error_utils.cc +118 -0
  589. data/src/core/lib/transport/error_utils.h +46 -0
  590. data/src/core/lib/transport/http2_errors.h +41 -0
  591. data/src/core/lib/transport/metadata.cc +539 -0
  592. data/src/core/lib/transport/metadata.h +165 -0
  593. data/src/core/lib/transport/metadata_batch.cc +329 -0
  594. data/src/core/lib/transport/metadata_batch.h +150 -0
  595. data/src/core/lib/transport/pid_controller.cc +51 -0
  596. data/src/core/lib/transport/pid_controller.h +116 -0
  597. data/src/core/lib/transport/service_config.cc +106 -0
  598. data/src/core/lib/transport/service_config.h +249 -0
  599. data/src/core/lib/transport/static_metadata.cc +601 -0
  600. data/src/core/lib/transport/static_metadata.h +603 -0
  601. data/src/core/lib/transport/status_conversion.cc +100 -0
  602. data/src/core/lib/transport/status_conversion.h +38 -0
  603. data/src/core/lib/transport/status_metadata.cc +54 -0
  604. data/src/core/lib/transport/status_metadata.h +30 -0
  605. data/src/core/lib/transport/timeout_encoding.cc +144 -0
  606. data/src/core/lib/transport/timeout_encoding.h +37 -0
  607. data/src/core/lib/transport/transport.cc +278 -0
  608. data/src/core/lib/transport/transport.h +378 -0
  609. data/src/core/lib/transport/transport_impl.h +71 -0
  610. data/src/core/lib/transport/transport_op_string.cc +214 -0
  611. data/src/core/plugin_registry/grpc_plugin_registry.cc +97 -0
  612. data/src/core/tsi/alts/crypt/aes_gcm.cc +687 -0
  613. data/src/core/tsi/alts/crypt/gsec.cc +189 -0
  614. data/src/core/tsi/alts/crypt/gsec.h +454 -0
  615. data/src/core/tsi/alts/frame_protector/alts_counter.cc +118 -0
  616. data/src/core/tsi/alts/frame_protector/alts_counter.h +98 -0
  617. data/src/core/tsi/alts/frame_protector/alts_crypter.cc +66 -0
  618. data/src/core/tsi/alts/frame_protector/alts_crypter.h +255 -0
  619. data/src/core/tsi/alts/frame_protector/alts_frame_protector.cc +407 -0
  620. data/src/core/tsi/alts/frame_protector/alts_frame_protector.h +55 -0
  621. data/src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.cc +114 -0
  622. data/src/core/tsi/alts/frame_protector/alts_record_protocol_crypter_common.h +114 -0
  623. data/src/core/tsi/alts/frame_protector/alts_seal_privacy_integrity_crypter.cc +105 -0
  624. data/src/core/tsi/alts/frame_protector/alts_unseal_privacy_integrity_crypter.cc +103 -0
  625. data/src/core/tsi/alts/frame_protector/frame_handler.cc +218 -0
  626. data/src/core/tsi/alts/frame_protector/frame_handler.h +236 -0
  627. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +316 -0
  628. data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +137 -0
  629. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api.cc +520 -0
  630. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api.h +323 -0
  631. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.cc +143 -0
  632. data/src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h +149 -0
  633. data/src/core/tsi/alts/handshaker/alts_tsi_event.cc +73 -0
  634. data/src/core/tsi/alts/handshaker/alts_tsi_event.h +93 -0
  635. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +483 -0
  636. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +83 -0
  637. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h +52 -0
  638. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +58 -0
  639. data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +52 -0
  640. data/src/core/tsi/alts/handshaker/altscontext.pb.c +48 -0
  641. data/src/core/tsi/alts/handshaker/altscontext.pb.h +64 -0
  642. data/src/core/tsi/alts/handshaker/handshaker.pb.c +123 -0
  643. data/src/core/tsi/alts/handshaker/handshaker.pb.h +255 -0
  644. data/src/core/tsi/alts/handshaker/transport_security_common.pb.c +50 -0
  645. data/src/core/tsi/alts/handshaker/transport_security_common.pb.h +78 -0
  646. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +196 -0
  647. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +163 -0
  648. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +180 -0
  649. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.h +52 -0
  650. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +144 -0
  651. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.h +49 -0
  652. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol.h +91 -0
  653. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +174 -0
  654. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.h +100 -0
  655. data/src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc +476 -0
  656. data/src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h +199 -0
  657. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +296 -0
  658. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h +52 -0
  659. data/src/core/tsi/alts_transport_security.cc +63 -0
  660. data/src/core/tsi/alts_transport_security.h +47 -0
  661. data/src/core/tsi/fake_transport_security.cc +787 -0
  662. data/src/core/tsi/fake_transport_security.h +45 -0
  663. data/src/core/tsi/ssl/session_cache/ssl_session.h +73 -0
  664. data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +58 -0
  665. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +211 -0
  666. data/src/core/tsi/ssl/session_cache/ssl_session_cache.h +93 -0
  667. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +76 -0
  668. data/src/core/tsi/ssl_transport_security.cc +1831 -0
  669. data/src/core/tsi/ssl_transport_security.h +314 -0
  670. data/src/core/tsi/ssl_types.h +42 -0
  671. data/src/core/tsi/transport_security.cc +326 -0
  672. data/src/core/tsi/transport_security.h +127 -0
  673. data/src/core/tsi/transport_security_adapter.cc +235 -0
  674. data/src/core/tsi/transport_security_adapter.h +41 -0
  675. data/src/core/tsi/transport_security_grpc.cc +66 -0
  676. data/src/core/tsi/transport_security_grpc.h +74 -0
  677. data/src/core/tsi/transport_security_interface.h +454 -0
  678. data/src/ruby/bin/apis/google/protobuf/empty.rb +29 -0
  679. data/src/ruby/bin/apis/pubsub_demo.rb +241 -0
  680. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub.rb +159 -0
  681. data/src/ruby/bin/apis/tech/pubsub/proto/pubsub_services.rb +88 -0
  682. data/src/ruby/bin/math_client.rb +132 -0
  683. data/src/ruby/bin/math_pb.rb +32 -0
  684. data/src/ruby/bin/math_server.rb +191 -0
  685. data/src/ruby/bin/math_services_pb.rb +51 -0
  686. data/src/ruby/bin/noproto_client.rb +93 -0
  687. data/src/ruby/bin/noproto_server.rb +97 -0
  688. data/src/ruby/ext/grpc/extconf.rb +118 -0
  689. data/src/ruby/ext/grpc/rb_byte_buffer.c +64 -0
  690. data/src/ruby/ext/grpc/rb_byte_buffer.h +35 -0
  691. data/src/ruby/ext/grpc/rb_call.c +1041 -0
  692. data/src/ruby/ext/grpc/rb_call.h +53 -0
  693. data/src/ruby/ext/grpc/rb_call_credentials.c +290 -0
  694. data/src/ruby/ext/grpc/rb_call_credentials.h +31 -0
  695. data/src/ruby/ext/grpc/rb_channel.c +828 -0
  696. data/src/ruby/ext/grpc/rb_channel.h +34 -0
  697. data/src/ruby/ext/grpc/rb_channel_args.c +155 -0
  698. data/src/ruby/ext/grpc/rb_channel_args.h +38 -0
  699. data/src/ruby/ext/grpc/rb_channel_credentials.c +263 -0
  700. data/src/ruby/ext/grpc/rb_channel_credentials.h +32 -0
  701. data/src/ruby/ext/grpc/rb_completion_queue.c +100 -0
  702. data/src/ruby/ext/grpc/rb_completion_queue.h +36 -0
  703. data/src/ruby/ext/grpc/rb_compression_options.c +468 -0
  704. data/src/ruby/ext/grpc/rb_compression_options.h +29 -0
  705. data/src/ruby/ext/grpc/rb_event_thread.c +141 -0
  706. data/src/ruby/ext/grpc/rb_event_thread.h +21 -0
  707. data/src/ruby/ext/grpc/rb_grpc.c +340 -0
  708. data/src/ruby/ext/grpc/rb_grpc.h +72 -0
  709. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +507 -0
  710. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +766 -0
  711. data/src/ruby/ext/grpc/rb_loader.c +57 -0
  712. data/src/ruby/ext/grpc/rb_loader.h +25 -0
  713. data/src/ruby/ext/grpc/rb_server.c +366 -0
  714. data/src/ruby/ext/grpc/rb_server.h +32 -0
  715. data/src/ruby/ext/grpc/rb_server_credentials.c +243 -0
  716. data/src/ruby/ext/grpc/rb_server_credentials.h +32 -0
  717. data/src/ruby/lib/grpc.rb +35 -0
  718. data/src/ruby/lib/grpc/core/time_consts.rb +56 -0
  719. data/src/ruby/lib/grpc/errors.rb +201 -0
  720. data/src/ruby/lib/grpc/generic/active_call.rb +674 -0
  721. data/src/ruby/lib/grpc/generic/bidi_call.rb +233 -0
  722. data/src/ruby/lib/grpc/generic/client_stub.rb +501 -0
  723. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  724. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  725. data/src/ruby/lib/grpc/generic/rpc_desc.rb +204 -0
  726. data/src/ruby/lib/grpc/generic/rpc_server.rb +490 -0
  727. data/src/ruby/lib/grpc/generic/service.rb +210 -0
  728. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +35 -0
  729. data/src/ruby/lib/grpc/grpc.rb +24 -0
  730. data/src/ruby/lib/grpc/logconfig.rb +44 -0
  731. data/src/ruby/lib/grpc/notifier.rb +45 -0
  732. data/src/ruby/lib/grpc/version.rb +18 -0
  733. data/src/ruby/pb/README.md +42 -0
  734. data/src/ruby/pb/generate_proto_ruby.sh +43 -0
  735. data/src/ruby/pb/grpc/health/checker.rb +76 -0
  736. data/src/ruby/pb/grpc/health/v1/health_pb.rb +28 -0
  737. data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +41 -0
  738. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +44 -0
  739. data/src/ruby/pb/grpc/testing/metrics_pb.rb +28 -0
  740. data/src/ruby/pb/grpc/testing/metrics_services_pb.rb +49 -0
  741. data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +15 -0
  742. data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +82 -0
  743. data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +14 -0
  744. data/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb +102 -0
  745. data/src/ruby/pb/test/client.rb +764 -0
  746. data/src/ruby/pb/test/server.rb +252 -0
  747. data/src/ruby/spec/call_credentials_spec.rb +42 -0
  748. data/src/ruby/spec/call_spec.rb +180 -0
  749. data/src/ruby/spec/channel_connection_spec.rb +126 -0
  750. data/src/ruby/spec/channel_credentials_spec.rb +82 -0
  751. data/src/ruby/spec/channel_spec.rb +190 -0
  752. data/src/ruby/spec/client_auth_spec.rb +137 -0
  753. data/src/ruby/spec/client_server_spec.rb +664 -0
  754. data/src/ruby/spec/compression_options_spec.rb +149 -0
  755. data/src/ruby/spec/error_sanity_spec.rb +49 -0
  756. data/src/ruby/spec/generic/active_call_spec.rb +672 -0
  757. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  758. data/src/ruby/spec/generic/client_stub_spec.rb +1067 -0
  759. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  760. data/src/ruby/spec/generic/rpc_desc_spec.rb +374 -0
  761. data/src/ruby/spec/generic/rpc_server_pool_spec.rb +127 -0
  762. data/src/ruby/spec/generic/rpc_server_spec.rb +726 -0
  763. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  764. data/src/ruby/spec/generic/service_spec.rb +261 -0
  765. data/src/ruby/spec/google_rpc_status_utils_spec.rb +293 -0
  766. data/src/ruby/spec/pb/duplicate/codegen_spec.rb +56 -0
  767. data/src/ruby/spec/pb/health/checker_spec.rb +236 -0
  768. data/src/ruby/spec/pb/package_with_underscore/checker_spec.rb +54 -0
  769. data/src/ruby/spec/pb/package_with_underscore/data.proto +23 -0
  770. data/src/ruby/spec/pb/package_with_underscore/service.proto +23 -0
  771. data/src/ruby/spec/server_credentials_spec.rb +79 -0
  772. data/src/ruby/spec/server_spec.rb +209 -0
  773. data/src/ruby/spec/spec_helper.rb +60 -0
  774. data/src/ruby/spec/support/helpers.rb +107 -0
  775. data/src/ruby/spec/support/services.rb +147 -0
  776. data/src/ruby/spec/testdata/README +1 -0
  777. data/src/ruby/spec/testdata/ca.pem +15 -0
  778. data/src/ruby/spec/testdata/client.key +16 -0
  779. data/src/ruby/spec/testdata/client.pem +14 -0
  780. data/src/ruby/spec/testdata/server1.key +16 -0
  781. data/src/ruby/spec/testdata/server1.pem +16 -0
  782. data/src/ruby/spec/time_consts_spec.rb +74 -0
  783. data/third_party/address_sorting/address_sorting.c +369 -0
  784. data/third_party/address_sorting/address_sorting_internal.h +70 -0
  785. data/third_party/address_sorting/address_sorting_posix.c +97 -0
  786. data/third_party/address_sorting/address_sorting_windows.c +55 -0
  787. data/third_party/address_sorting/include/address_sorting/address_sorting.h +110 -0
  788. data/third_party/boringssl/crypto/asn1/a_bitstr.c +271 -0
  789. data/third_party/boringssl/crypto/asn1/a_bool.c +110 -0
  790. data/third_party/boringssl/crypto/asn1/a_d2i_fp.c +297 -0
  791. data/third_party/boringssl/crypto/asn1/a_dup.c +111 -0
  792. data/third_party/boringssl/crypto/asn1/a_enum.c +195 -0
  793. data/third_party/boringssl/crypto/asn1/a_gentm.c +261 -0
  794. data/third_party/boringssl/crypto/asn1/a_i2d_fp.c +150 -0
  795. data/third_party/boringssl/crypto/asn1/a_int.c +474 -0
  796. data/third_party/boringssl/crypto/asn1/a_mbstr.c +409 -0
  797. data/third_party/boringssl/crypto/asn1/a_object.c +275 -0
  798. data/third_party/boringssl/crypto/asn1/a_octet.c +77 -0
  799. data/third_party/boringssl/crypto/asn1/a_print.c +93 -0
  800. data/third_party/boringssl/crypto/asn1/a_strnid.c +312 -0
  801. data/third_party/boringssl/crypto/asn1/a_time.c +213 -0
  802. data/third_party/boringssl/crypto/asn1/a_type.c +151 -0
  803. data/third_party/boringssl/crypto/asn1/a_utctm.c +303 -0
  804. data/third_party/boringssl/crypto/asn1/a_utf8.c +234 -0
  805. data/third_party/boringssl/crypto/asn1/asn1_lib.c +442 -0
  806. data/third_party/boringssl/crypto/asn1/asn1_locl.h +101 -0
  807. data/third_party/boringssl/crypto/asn1/asn1_par.c +80 -0
  808. data/third_party/boringssl/crypto/asn1/asn_pack.c +105 -0
  809. data/third_party/boringssl/crypto/asn1/f_enum.c +93 -0
  810. data/third_party/boringssl/crypto/asn1/f_int.c +97 -0
  811. data/third_party/boringssl/crypto/asn1/f_string.c +91 -0
  812. data/third_party/boringssl/crypto/asn1/tasn_dec.c +1223 -0
  813. data/third_party/boringssl/crypto/asn1/tasn_enc.c +662 -0
  814. data/third_party/boringssl/crypto/asn1/tasn_fre.c +244 -0
  815. data/third_party/boringssl/crypto/asn1/tasn_new.c +387 -0
  816. data/third_party/boringssl/crypto/asn1/tasn_typ.c +131 -0
  817. data/third_party/boringssl/crypto/asn1/tasn_utl.c +280 -0
  818. data/third_party/boringssl/crypto/asn1/time_support.c +206 -0
  819. data/third_party/boringssl/crypto/base64/base64.c +466 -0
  820. data/third_party/boringssl/crypto/bio/bio.c +636 -0
  821. data/third_party/boringssl/crypto/bio/bio_mem.c +330 -0
  822. data/third_party/boringssl/crypto/bio/connect.c +542 -0
  823. data/third_party/boringssl/crypto/bio/fd.c +275 -0
  824. data/third_party/boringssl/crypto/bio/file.c +313 -0
  825. data/third_party/boringssl/crypto/bio/hexdump.c +192 -0
  826. data/third_party/boringssl/crypto/bio/internal.h +111 -0
  827. data/third_party/boringssl/crypto/bio/pair.c +489 -0
  828. data/third_party/boringssl/crypto/bio/printf.c +115 -0
  829. data/third_party/boringssl/crypto/bio/socket.c +202 -0
  830. data/third_party/boringssl/crypto/bio/socket_helper.c +114 -0
  831. data/third_party/boringssl/crypto/bn_extra/bn_asn1.c +64 -0
  832. data/third_party/boringssl/crypto/bn_extra/convert.c +465 -0
  833. data/third_party/boringssl/crypto/buf/buf.c +231 -0
  834. data/third_party/boringssl/crypto/bytestring/asn1_compat.c +52 -0
  835. data/third_party/boringssl/crypto/bytestring/ber.c +264 -0
  836. data/third_party/boringssl/crypto/bytestring/cbb.c +568 -0
  837. data/third_party/boringssl/crypto/bytestring/cbs.c +487 -0
  838. data/third_party/boringssl/crypto/bytestring/internal.h +75 -0
  839. data/third_party/boringssl/crypto/chacha/chacha.c +167 -0
  840. data/third_party/boringssl/crypto/cipher_extra/cipher_extra.c +114 -0
  841. data/third_party/boringssl/crypto/cipher_extra/derive_key.c +152 -0
  842. data/third_party/boringssl/crypto/cipher_extra/e_aesctrhmac.c +281 -0
  843. data/third_party/boringssl/crypto/cipher_extra/e_aesgcmsiv.c +867 -0
  844. data/third_party/boringssl/crypto/cipher_extra/e_chacha20poly1305.c +326 -0
  845. data/third_party/boringssl/crypto/cipher_extra/e_null.c +85 -0
  846. data/third_party/boringssl/crypto/cipher_extra/e_rc2.c +460 -0
  847. data/third_party/boringssl/crypto/cipher_extra/e_rc4.c +87 -0
  848. data/third_party/boringssl/crypto/cipher_extra/e_ssl3.c +460 -0
  849. data/third_party/boringssl/crypto/cipher_extra/e_tls.c +681 -0
  850. data/third_party/boringssl/crypto/cipher_extra/internal.h +128 -0
  851. data/third_party/boringssl/crypto/cipher_extra/tls_cbc.c +482 -0
  852. data/third_party/boringssl/crypto/cmac/cmac.c +241 -0
  853. data/third_party/boringssl/crypto/conf/conf.c +803 -0
  854. data/third_party/boringssl/crypto/conf/conf_def.h +127 -0
  855. data/third_party/boringssl/crypto/conf/internal.h +31 -0
  856. data/third_party/boringssl/crypto/cpu-aarch64-linux.c +61 -0
  857. data/third_party/boringssl/crypto/cpu-arm-linux.c +363 -0
  858. data/third_party/boringssl/crypto/cpu-arm.c +38 -0
  859. data/third_party/boringssl/crypto/cpu-intel.c +288 -0
  860. data/third_party/boringssl/crypto/cpu-ppc64le.c +38 -0
  861. data/third_party/boringssl/crypto/crypto.c +198 -0
  862. data/third_party/boringssl/crypto/curve25519/spake25519.c +539 -0
  863. data/third_party/boringssl/crypto/curve25519/x25519-x86_64.c +247 -0
  864. data/third_party/boringssl/crypto/dh/check.c +217 -0
  865. data/third_party/boringssl/crypto/dh/dh.c +519 -0
  866. data/third_party/boringssl/crypto/dh/dh_asn1.c +160 -0
  867. data/third_party/boringssl/crypto/dh/params.c +93 -0
  868. data/third_party/boringssl/crypto/digest_extra/digest_extra.c +240 -0
  869. data/third_party/boringssl/crypto/dsa/dsa.c +984 -0
  870. data/third_party/boringssl/crypto/dsa/dsa_asn1.c +339 -0
  871. data/third_party/boringssl/crypto/ec_extra/ec_asn1.c +563 -0
  872. data/third_party/boringssl/crypto/ecdh/ecdh.c +161 -0
  873. data/third_party/boringssl/crypto/ecdsa_extra/ecdsa_asn1.c +275 -0
  874. data/third_party/boringssl/crypto/engine/engine.c +98 -0
  875. data/third_party/boringssl/crypto/err/err.c +847 -0
  876. data/third_party/boringssl/crypto/err/internal.h +58 -0
  877. data/third_party/boringssl/crypto/evp/digestsign.c +231 -0
  878. data/third_party/boringssl/crypto/evp/evp.c +362 -0
  879. data/third_party/boringssl/crypto/evp/evp_asn1.c +337 -0
  880. data/third_party/boringssl/crypto/evp/evp_ctx.c +446 -0
  881. data/third_party/boringssl/crypto/evp/internal.h +252 -0
  882. data/third_party/boringssl/crypto/evp/p_dsa_asn1.c +268 -0
  883. data/third_party/boringssl/crypto/evp/p_ec.c +239 -0
  884. data/third_party/boringssl/crypto/evp/p_ec_asn1.c +256 -0
  885. data/third_party/boringssl/crypto/evp/p_ed25519.c +71 -0
  886. data/third_party/boringssl/crypto/evp/p_ed25519_asn1.c +190 -0
  887. data/third_party/boringssl/crypto/evp/p_rsa.c +634 -0
  888. data/third_party/boringssl/crypto/evp/p_rsa_asn1.c +189 -0
  889. data/third_party/boringssl/crypto/evp/pbkdf.c +146 -0
  890. data/third_party/boringssl/crypto/evp/print.c +489 -0
  891. data/third_party/boringssl/crypto/evp/scrypt.c +209 -0
  892. data/third_party/boringssl/crypto/evp/sign.c +151 -0
  893. data/third_party/boringssl/crypto/ex_data.c +261 -0
  894. data/third_party/boringssl/crypto/fipsmodule/aes/aes.c +1100 -0
  895. data/third_party/boringssl/crypto/fipsmodule/aes/internal.h +100 -0
  896. data/third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c +138 -0
  897. data/third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c +112 -0
  898. data/third_party/boringssl/crypto/fipsmodule/bcm.c +679 -0
  899. data/third_party/boringssl/crypto/fipsmodule/bn/add.c +371 -0
  900. data/third_party/boringssl/crypto/fipsmodule/bn/asm/x86_64-gcc.c +540 -0
  901. data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +370 -0
  902. data/third_party/boringssl/crypto/fipsmodule/bn/bytes.c +269 -0
  903. data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +254 -0
  904. data/third_party/boringssl/crypto/fipsmodule/bn/ctx.c +303 -0
  905. data/third_party/boringssl/crypto/fipsmodule/bn/div.c +733 -0
  906. data/third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c +1390 -0
  907. data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +627 -0
  908. data/third_party/boringssl/crypto/fipsmodule/bn/generic.c +710 -0
  909. data/third_party/boringssl/crypto/fipsmodule/bn/internal.h +413 -0
  910. data/third_party/boringssl/crypto/fipsmodule/bn/jacobi.c +146 -0
  911. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +483 -0
  912. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +207 -0
  913. data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +902 -0
  914. data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +894 -0
  915. data/third_party/boringssl/crypto/fipsmodule/bn/random.c +299 -0
  916. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c +254 -0
  917. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h +53 -0
  918. data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +305 -0
  919. data/third_party/boringssl/crypto/fipsmodule/bn/sqrt.c +502 -0
  920. data/third_party/boringssl/crypto/fipsmodule/cipher/aead.c +284 -0
  921. data/third_party/boringssl/crypto/fipsmodule/cipher/cipher.c +615 -0
  922. data/third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c +1437 -0
  923. data/third_party/boringssl/crypto/fipsmodule/cipher/e_des.c +233 -0
  924. data/third_party/boringssl/crypto/fipsmodule/cipher/internal.h +129 -0
  925. data/third_party/boringssl/crypto/fipsmodule/delocate.h +88 -0
  926. data/third_party/boringssl/crypto/fipsmodule/des/des.c +785 -0
  927. data/third_party/boringssl/crypto/fipsmodule/des/internal.h +238 -0
  928. data/third_party/boringssl/crypto/fipsmodule/digest/digest.c +256 -0
  929. data/third_party/boringssl/crypto/fipsmodule/digest/digests.c +280 -0
  930. data/third_party/boringssl/crypto/fipsmodule/digest/internal.h +112 -0
  931. data/third_party/boringssl/crypto/fipsmodule/digest/md32_common.h +268 -0
  932. data/third_party/boringssl/crypto/fipsmodule/ec/ec.c +943 -0
  933. data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +517 -0
  934. data/third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c +277 -0
  935. data/third_party/boringssl/crypto/fipsmodule/ec/internal.h +316 -0
  936. data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +404 -0
  937. data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +1131 -0
  938. data/third_party/boringssl/crypto/fipsmodule/ec/p256-64.c +1674 -0
  939. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h +9543 -0
  940. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c +456 -0
  941. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h +113 -0
  942. data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +1052 -0
  943. data/third_party/boringssl/crypto/fipsmodule/ec/util-64.c +109 -0
  944. data/third_party/boringssl/crypto/fipsmodule/ec/wnaf.c +474 -0
  945. data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +442 -0
  946. data/third_party/boringssl/crypto/fipsmodule/hmac/hmac.c +228 -0
  947. data/third_party/boringssl/crypto/fipsmodule/is_fips.c +27 -0
  948. data/third_party/boringssl/crypto/fipsmodule/md4/md4.c +254 -0
  949. data/third_party/boringssl/crypto/fipsmodule/md5/md5.c +298 -0
  950. data/third_party/boringssl/crypto/fipsmodule/modes/cbc.c +211 -0
  951. data/third_party/boringssl/crypto/fipsmodule/modes/cfb.c +234 -0
  952. data/third_party/boringssl/crypto/fipsmodule/modes/ctr.c +220 -0
  953. data/third_party/boringssl/crypto/fipsmodule/modes/gcm.c +1063 -0
  954. data/third_party/boringssl/crypto/fipsmodule/modes/internal.h +384 -0
  955. data/third_party/boringssl/crypto/fipsmodule/modes/ofb.c +95 -0
  956. data/third_party/boringssl/crypto/fipsmodule/modes/polyval.c +91 -0
  957. data/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c +200 -0
  958. data/third_party/boringssl/crypto/fipsmodule/rand/internal.h +92 -0
  959. data/third_party/boringssl/crypto/fipsmodule/rand/rand.c +358 -0
  960. data/third_party/boringssl/crypto/fipsmodule/rand/urandom.c +302 -0
  961. data/third_party/boringssl/crypto/fipsmodule/rsa/blinding.c +263 -0
  962. data/third_party/boringssl/crypto/fipsmodule/rsa/internal.h +131 -0
  963. data/third_party/boringssl/crypto/fipsmodule/rsa/padding.c +692 -0
  964. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +857 -0
  965. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +1051 -0
  966. data/third_party/boringssl/crypto/fipsmodule/sha/sha1-altivec.c +361 -0
  967. data/third_party/boringssl/crypto/fipsmodule/sha/sha1.c +375 -0
  968. data/third_party/boringssl/crypto/fipsmodule/sha/sha256.c +337 -0
  969. data/third_party/boringssl/crypto/fipsmodule/sha/sha512.c +608 -0
  970. data/third_party/boringssl/crypto/hkdf/hkdf.c +112 -0
  971. data/third_party/boringssl/crypto/internal.h +676 -0
  972. data/third_party/boringssl/crypto/lhash/lhash.c +336 -0
  973. data/third_party/boringssl/crypto/mem.c +237 -0
  974. data/third_party/boringssl/crypto/obj/obj.c +621 -0
  975. data/third_party/boringssl/crypto/obj/obj_dat.h +6244 -0
  976. data/third_party/boringssl/crypto/obj/obj_xref.c +122 -0
  977. data/third_party/boringssl/crypto/pem/pem_all.c +262 -0
  978. data/third_party/boringssl/crypto/pem/pem_info.c +379 -0
  979. data/third_party/boringssl/crypto/pem/pem_lib.c +776 -0
  980. data/third_party/boringssl/crypto/pem/pem_oth.c +88 -0
  981. data/third_party/boringssl/crypto/pem/pem_pk8.c +258 -0
  982. data/third_party/boringssl/crypto/pem/pem_pkey.c +227 -0
  983. data/third_party/boringssl/crypto/pem/pem_x509.c +65 -0
  984. data/third_party/boringssl/crypto/pem/pem_xaux.c +65 -0
  985. data/third_party/boringssl/crypto/pkcs7/internal.h +49 -0
  986. data/third_party/boringssl/crypto/pkcs7/pkcs7.c +166 -0
  987. data/third_party/boringssl/crypto/pkcs7/pkcs7_x509.c +233 -0
  988. data/third_party/boringssl/crypto/pkcs8/internal.h +120 -0
  989. data/third_party/boringssl/crypto/pkcs8/p5_pbev2.c +307 -0
  990. data/third_party/boringssl/crypto/pkcs8/pkcs8.c +513 -0
  991. data/third_party/boringssl/crypto/pkcs8/pkcs8_x509.c +789 -0
  992. data/third_party/boringssl/crypto/poly1305/internal.h +41 -0
  993. data/third_party/boringssl/crypto/poly1305/poly1305.c +318 -0
  994. data/third_party/boringssl/crypto/poly1305/poly1305_arm.c +304 -0
  995. data/third_party/boringssl/crypto/poly1305/poly1305_vec.c +839 -0
  996. data/third_party/boringssl/crypto/pool/internal.h +45 -0
  997. data/third_party/boringssl/crypto/pool/pool.c +200 -0
  998. data/third_party/boringssl/crypto/rand_extra/deterministic.c +48 -0
  999. data/third_party/boringssl/crypto/rand_extra/forkunsafe.c +46 -0
  1000. data/third_party/boringssl/crypto/rand_extra/fuchsia.c +43 -0
  1001. data/third_party/boringssl/crypto/rand_extra/rand_extra.c +70 -0
  1002. data/third_party/boringssl/crypto/rand_extra/windows.c +53 -0
  1003. data/third_party/boringssl/crypto/rc4/rc4.c +98 -0
  1004. data/third_party/boringssl/crypto/refcount_c11.c +67 -0
  1005. data/third_party/boringssl/crypto/refcount_lock.c +53 -0
  1006. data/third_party/boringssl/crypto/rsa_extra/rsa_asn1.c +325 -0
  1007. data/third_party/boringssl/crypto/stack/stack.c +380 -0
  1008. data/third_party/boringssl/crypto/thread.c +110 -0
  1009. data/third_party/boringssl/crypto/thread_none.c +59 -0
  1010. data/third_party/boringssl/crypto/thread_pthread.c +176 -0
  1011. data/third_party/boringssl/crypto/thread_win.c +237 -0
  1012. data/third_party/boringssl/crypto/x509/a_digest.c +96 -0
  1013. data/third_party/boringssl/crypto/x509/a_sign.c +128 -0
  1014. data/third_party/boringssl/crypto/x509/a_strex.c +633 -0
  1015. data/third_party/boringssl/crypto/x509/a_verify.c +115 -0
  1016. data/third_party/boringssl/crypto/x509/algorithm.c +153 -0
  1017. data/third_party/boringssl/crypto/x509/asn1_gen.c +841 -0
  1018. data/third_party/boringssl/crypto/x509/by_dir.c +451 -0
  1019. data/third_party/boringssl/crypto/x509/by_file.c +274 -0
  1020. data/third_party/boringssl/crypto/x509/charmap.h +15 -0
  1021. data/third_party/boringssl/crypto/x509/i2d_pr.c +83 -0
  1022. data/third_party/boringssl/crypto/x509/internal.h +66 -0
  1023. data/third_party/boringssl/crypto/x509/rsa_pss.c +385 -0
  1024. data/third_party/boringssl/crypto/x509/t_crl.c +128 -0
  1025. data/third_party/boringssl/crypto/x509/t_req.c +246 -0
  1026. data/third_party/boringssl/crypto/x509/t_x509.c +547 -0
  1027. data/third_party/boringssl/crypto/x509/t_x509a.c +111 -0
  1028. data/third_party/boringssl/crypto/x509/vpm_int.h +70 -0
  1029. data/third_party/boringssl/crypto/x509/x509.c +157 -0
  1030. data/third_party/boringssl/crypto/x509/x509_att.c +381 -0
  1031. data/third_party/boringssl/crypto/x509/x509_cmp.c +477 -0
  1032. data/third_party/boringssl/crypto/x509/x509_d2.c +106 -0
  1033. data/third_party/boringssl/crypto/x509/x509_def.c +103 -0
  1034. data/third_party/boringssl/crypto/x509/x509_ext.c +206 -0
  1035. data/third_party/boringssl/crypto/x509/x509_lu.c +725 -0
  1036. data/third_party/boringssl/crypto/x509/x509_obj.c +198 -0
  1037. data/third_party/boringssl/crypto/x509/x509_r2x.c +117 -0
  1038. data/third_party/boringssl/crypto/x509/x509_req.c +322 -0
  1039. data/third_party/boringssl/crypto/x509/x509_set.c +164 -0
  1040. data/third_party/boringssl/crypto/x509/x509_trs.c +326 -0
  1041. data/third_party/boringssl/crypto/x509/x509_txt.c +205 -0
  1042. data/third_party/boringssl/crypto/x509/x509_v3.c +278 -0
  1043. data/third_party/boringssl/crypto/x509/x509_vfy.c +2472 -0
  1044. data/third_party/boringssl/crypto/x509/x509_vpm.c +648 -0
  1045. data/third_party/boringssl/crypto/x509/x509cset.c +170 -0
  1046. data/third_party/boringssl/crypto/x509/x509name.c +389 -0
  1047. data/third_party/boringssl/crypto/x509/x509rset.c +81 -0
  1048. data/third_party/boringssl/crypto/x509/x509spki.c +137 -0
  1049. data/third_party/boringssl/crypto/x509/x_algor.c +151 -0
  1050. data/third_party/boringssl/crypto/x509/x_all.c +501 -0
  1051. data/third_party/boringssl/crypto/x509/x_attrib.c +111 -0
  1052. data/third_party/boringssl/crypto/x509/x_crl.c +541 -0
  1053. data/third_party/boringssl/crypto/x509/x_exten.c +75 -0
  1054. data/third_party/boringssl/crypto/x509/x_info.c +98 -0
  1055. data/third_party/boringssl/crypto/x509/x_name.c +541 -0
  1056. data/third_party/boringssl/crypto/x509/x_pkey.c +106 -0
  1057. data/third_party/boringssl/crypto/x509/x_pubkey.c +368 -0
  1058. data/third_party/boringssl/crypto/x509/x_req.c +109 -0
  1059. data/third_party/boringssl/crypto/x509/x_sig.c +69 -0
  1060. data/third_party/boringssl/crypto/x509/x_spki.c +80 -0
  1061. data/third_party/boringssl/crypto/x509/x_val.c +69 -0
  1062. data/third_party/boringssl/crypto/x509/x_x509.c +328 -0
  1063. data/third_party/boringssl/crypto/x509/x_x509a.c +198 -0
  1064. data/third_party/boringssl/crypto/x509v3/ext_dat.h +143 -0
  1065. data/third_party/boringssl/crypto/x509v3/pcy_cache.c +284 -0
  1066. data/third_party/boringssl/crypto/x509v3/pcy_data.c +130 -0
  1067. data/third_party/boringssl/crypto/x509v3/pcy_int.h +217 -0
  1068. data/third_party/boringssl/crypto/x509v3/pcy_lib.c +155 -0
  1069. data/third_party/boringssl/crypto/x509v3/pcy_map.c +130 -0
  1070. data/third_party/boringssl/crypto/x509v3/pcy_node.c +188 -0
  1071. data/third_party/boringssl/crypto/x509v3/pcy_tree.c +840 -0
  1072. data/third_party/boringssl/crypto/x509v3/v3_akey.c +204 -0
  1073. data/third_party/boringssl/crypto/x509v3/v3_akeya.c +72 -0
  1074. data/third_party/boringssl/crypto/x509v3/v3_alt.c +623 -0
  1075. data/third_party/boringssl/crypto/x509v3/v3_bcons.c +133 -0
  1076. data/third_party/boringssl/crypto/x509v3/v3_bitst.c +141 -0
  1077. data/third_party/boringssl/crypto/x509v3/v3_conf.c +462 -0
  1078. data/third_party/boringssl/crypto/x509v3/v3_cpols.c +502 -0
  1079. data/third_party/boringssl/crypto/x509v3/v3_crld.c +561 -0
  1080. data/third_party/boringssl/crypto/x509v3/v3_enum.c +100 -0
  1081. data/third_party/boringssl/crypto/x509v3/v3_extku.c +148 -0
  1082. data/third_party/boringssl/crypto/x509v3/v3_genn.c +251 -0
  1083. data/third_party/boringssl/crypto/x509v3/v3_ia5.c +122 -0
  1084. data/third_party/boringssl/crypto/x509v3/v3_info.c +219 -0
  1085. data/third_party/boringssl/crypto/x509v3/v3_int.c +91 -0
  1086. data/third_party/boringssl/crypto/x509v3/v3_lib.c +370 -0
  1087. data/third_party/boringssl/crypto/x509v3/v3_ncons.c +501 -0
  1088. data/third_party/boringssl/crypto/x509v3/v3_pci.c +287 -0
  1089. data/third_party/boringssl/crypto/x509v3/v3_pcia.c +57 -0
  1090. data/third_party/boringssl/crypto/x509v3/v3_pcons.c +139 -0
  1091. data/third_party/boringssl/crypto/x509v3/v3_pku.c +110 -0
  1092. data/third_party/boringssl/crypto/x509v3/v3_pmaps.c +154 -0
  1093. data/third_party/boringssl/crypto/x509v3/v3_prn.c +229 -0
  1094. data/third_party/boringssl/crypto/x509v3/v3_purp.c +866 -0
  1095. data/third_party/boringssl/crypto/x509v3/v3_skey.c +152 -0
  1096. data/third_party/boringssl/crypto/x509v3/v3_sxnet.c +274 -0
  1097. data/third_party/boringssl/crypto/x509v3/v3_utl.c +1352 -0
  1098. data/third_party/boringssl/include/openssl/aead.h +423 -0
  1099. data/third_party/boringssl/include/openssl/aes.h +170 -0
  1100. data/third_party/boringssl/include/openssl/arm_arch.h +121 -0
  1101. data/third_party/boringssl/include/openssl/asn1.h +982 -0
  1102. data/third_party/boringssl/include/openssl/asn1_mac.h +18 -0
  1103. data/third_party/boringssl/include/openssl/asn1t.h +892 -0
  1104. data/third_party/boringssl/include/openssl/base.h +469 -0
  1105. data/third_party/boringssl/include/openssl/base64.h +187 -0
  1106. data/third_party/boringssl/include/openssl/bio.h +902 -0
  1107. data/third_party/boringssl/include/openssl/blowfish.h +93 -0
  1108. data/third_party/boringssl/include/openssl/bn.h +975 -0
  1109. data/third_party/boringssl/include/openssl/buf.h +137 -0
  1110. data/third_party/boringssl/include/openssl/buffer.h +18 -0
  1111. data/third_party/boringssl/include/openssl/bytestring.h +480 -0
  1112. data/third_party/boringssl/include/openssl/cast.h +96 -0
  1113. data/third_party/boringssl/include/openssl/chacha.h +41 -0
  1114. data/third_party/boringssl/include/openssl/cipher.h +608 -0
  1115. data/third_party/boringssl/include/openssl/cmac.h +87 -0
  1116. data/third_party/boringssl/include/openssl/conf.h +183 -0
  1117. data/third_party/boringssl/include/openssl/cpu.h +196 -0
  1118. data/third_party/boringssl/include/openssl/crypto.h +118 -0
  1119. data/third_party/boringssl/include/openssl/curve25519.h +201 -0
  1120. data/third_party/boringssl/include/openssl/des.h +177 -0
  1121. data/third_party/boringssl/include/openssl/dh.h +298 -0
  1122. data/third_party/boringssl/include/openssl/digest.h +316 -0
  1123. data/third_party/boringssl/include/openssl/dsa.h +435 -0
  1124. data/third_party/boringssl/include/openssl/dtls1.h +16 -0
  1125. data/third_party/boringssl/include/openssl/ec.h +407 -0
  1126. data/third_party/boringssl/include/openssl/ec_key.h +341 -0
  1127. data/third_party/boringssl/include/openssl/ecdh.h +101 -0
  1128. data/third_party/boringssl/include/openssl/ecdsa.h +199 -0
  1129. data/third_party/boringssl/include/openssl/engine.h +109 -0
  1130. data/third_party/boringssl/include/openssl/err.h +458 -0
  1131. data/third_party/boringssl/include/openssl/evp.h +873 -0
  1132. data/third_party/boringssl/include/openssl/ex_data.h +203 -0
  1133. data/third_party/boringssl/include/openssl/hkdf.h +64 -0
  1134. data/third_party/boringssl/include/openssl/hmac.h +186 -0
  1135. data/third_party/boringssl/include/openssl/is_boringssl.h +16 -0
  1136. data/third_party/boringssl/include/openssl/lhash.h +174 -0
  1137. data/third_party/boringssl/include/openssl/lhash_macros.h +174 -0
  1138. data/third_party/boringssl/include/openssl/md4.h +106 -0
  1139. data/third_party/boringssl/include/openssl/md5.h +107 -0
  1140. data/third_party/boringssl/include/openssl/mem.h +156 -0
  1141. data/third_party/boringssl/include/openssl/nid.h +4242 -0
  1142. data/third_party/boringssl/include/openssl/obj.h +233 -0
  1143. data/third_party/boringssl/include/openssl/obj_mac.h +18 -0
  1144. data/third_party/boringssl/include/openssl/objects.h +18 -0
  1145. data/third_party/boringssl/include/openssl/opensslconf.h +67 -0
  1146. data/third_party/boringssl/include/openssl/opensslv.h +18 -0
  1147. data/third_party/boringssl/include/openssl/ossl_typ.h +18 -0
  1148. data/third_party/boringssl/include/openssl/pem.h +397 -0
  1149. data/third_party/boringssl/include/openssl/pkcs12.h +18 -0
  1150. data/third_party/boringssl/include/openssl/pkcs7.h +82 -0
  1151. data/third_party/boringssl/include/openssl/pkcs8.h +230 -0
  1152. data/third_party/boringssl/include/openssl/poly1305.h +51 -0
  1153. data/third_party/boringssl/include/openssl/pool.h +91 -0
  1154. data/third_party/boringssl/include/openssl/rand.h +125 -0
  1155. data/third_party/boringssl/include/openssl/rc4.h +96 -0
  1156. data/third_party/boringssl/include/openssl/ripemd.h +107 -0
  1157. data/third_party/boringssl/include/openssl/rsa.h +731 -0
  1158. data/third_party/boringssl/include/openssl/safestack.h +16 -0
  1159. data/third_party/boringssl/include/openssl/sha.h +256 -0
  1160. data/third_party/boringssl/include/openssl/span.h +191 -0
  1161. data/third_party/boringssl/include/openssl/srtp.h +18 -0
  1162. data/third_party/boringssl/include/openssl/ssl.h +4592 -0
  1163. data/third_party/boringssl/include/openssl/ssl3.h +333 -0
  1164. data/third_party/boringssl/include/openssl/stack.h +485 -0
  1165. data/third_party/boringssl/include/openssl/thread.h +191 -0
  1166. data/third_party/boringssl/include/openssl/tls1.h +610 -0
  1167. data/third_party/boringssl/include/openssl/type_check.h +91 -0
  1168. data/third_party/boringssl/include/openssl/x509.h +1176 -0
  1169. data/third_party/boringssl/include/openssl/x509_vfy.h +614 -0
  1170. data/third_party/boringssl/include/openssl/x509v3.h +826 -0
  1171. data/third_party/boringssl/ssl/bio_ssl.cc +179 -0
  1172. data/third_party/boringssl/ssl/custom_extensions.cc +265 -0
  1173. data/third_party/boringssl/ssl/d1_both.cc +837 -0
  1174. data/third_party/boringssl/ssl/d1_lib.cc +267 -0
  1175. data/third_party/boringssl/ssl/d1_pkt.cc +274 -0
  1176. data/third_party/boringssl/ssl/d1_srtp.cc +232 -0
  1177. data/third_party/boringssl/ssl/dtls_method.cc +193 -0
  1178. data/third_party/boringssl/ssl/dtls_record.cc +353 -0
  1179. data/third_party/boringssl/ssl/handshake.cc +616 -0
  1180. data/third_party/boringssl/ssl/handshake_client.cc +1836 -0
  1181. data/third_party/boringssl/ssl/handshake_server.cc +1662 -0
  1182. data/third_party/boringssl/ssl/internal.h +3011 -0
  1183. data/third_party/boringssl/ssl/s3_both.cc +585 -0
  1184. data/third_party/boringssl/ssl/s3_lib.cc +224 -0
  1185. data/third_party/boringssl/ssl/s3_pkt.cc +443 -0
  1186. data/third_party/boringssl/ssl/ssl_aead_ctx.cc +415 -0
  1187. data/third_party/boringssl/ssl/ssl_asn1.cc +840 -0
  1188. data/third_party/boringssl/ssl/ssl_buffer.cc +286 -0
  1189. data/third_party/boringssl/ssl/ssl_cert.cc +913 -0
  1190. data/third_party/boringssl/ssl/ssl_cipher.cc +1777 -0
  1191. data/third_party/boringssl/ssl/ssl_file.cc +583 -0
  1192. data/third_party/boringssl/ssl/ssl_key_share.cc +250 -0
  1193. data/third_party/boringssl/ssl/ssl_lib.cc +2650 -0
  1194. data/third_party/boringssl/ssl/ssl_privkey.cc +488 -0
  1195. data/third_party/boringssl/ssl/ssl_session.cc +1221 -0
  1196. data/third_party/boringssl/ssl/ssl_stat.cc +224 -0
  1197. data/third_party/boringssl/ssl/ssl_transcript.cc +398 -0
  1198. data/third_party/boringssl/ssl/ssl_versions.cc +472 -0
  1199. data/third_party/boringssl/ssl/ssl_x509.cc +1299 -0
  1200. data/third_party/boringssl/ssl/t1_enc.cc +503 -0
  1201. data/third_party/boringssl/ssl/t1_lib.cc +3457 -0
  1202. data/third_party/boringssl/ssl/tls13_both.cc +551 -0
  1203. data/third_party/boringssl/ssl/tls13_client.cc +977 -0
  1204. data/third_party/boringssl/ssl/tls13_enc.cc +563 -0
  1205. data/third_party/boringssl/ssl/tls13_server.cc +1068 -0
  1206. data/third_party/boringssl/ssl/tls_method.cc +291 -0
  1207. data/third_party/boringssl/ssl/tls_record.cc +712 -0
  1208. data/third_party/boringssl/third_party/fiat/curve25519.c +5062 -0
  1209. data/third_party/boringssl/third_party/fiat/internal.h +142 -0
  1210. data/third_party/cares/ares_build.h +223 -0
  1211. data/third_party/cares/cares/ares.h +658 -0
  1212. data/third_party/cares/cares/ares__close_sockets.c +61 -0
  1213. data/third_party/cares/cares/ares__get_hostent.c +261 -0
  1214. data/third_party/cares/cares/ares__read_line.c +73 -0
  1215. data/third_party/cares/cares/ares__timeval.c +111 -0
  1216. data/third_party/cares/cares/ares_cancel.c +63 -0
  1217. data/third_party/cares/cares/ares_create_query.c +202 -0
  1218. data/third_party/cares/cares/ares_data.c +221 -0
  1219. data/third_party/cares/cares/ares_data.h +72 -0
  1220. data/third_party/cares/cares/ares_destroy.c +108 -0
  1221. data/third_party/cares/cares/ares_dns.h +103 -0
  1222. data/third_party/cares/cares/ares_expand_name.c +209 -0
  1223. data/third_party/cares/cares/ares_expand_string.c +70 -0
  1224. data/third_party/cares/cares/ares_fds.c +59 -0
  1225. data/third_party/cares/cares/ares_free_hostent.c +41 -0
  1226. data/third_party/cares/cares/ares_free_string.c +25 -0
  1227. data/third_party/cares/cares/ares_getenv.c +30 -0
  1228. data/third_party/cares/cares/ares_getenv.h +26 -0
  1229. data/third_party/cares/cares/ares_gethostbyaddr.c +294 -0
  1230. data/third_party/cares/cares/ares_gethostbyname.c +518 -0
  1231. data/third_party/cares/cares/ares_getnameinfo.c +442 -0
  1232. data/third_party/cares/cares/ares_getopt.c +122 -0
  1233. data/third_party/cares/cares/ares_getopt.h +53 -0
  1234. data/third_party/cares/cares/ares_getsock.c +66 -0
  1235. data/third_party/cares/cares/ares_inet_net_pton.h +25 -0
  1236. data/third_party/cares/cares/ares_init.c +2514 -0
  1237. data/third_party/cares/cares/ares_iphlpapi.h +221 -0
  1238. data/third_party/cares/cares/ares_ipv6.h +78 -0
  1239. data/third_party/cares/cares/ares_library_init.c +177 -0
  1240. data/third_party/cares/cares/ares_library_init.h +43 -0
  1241. data/third_party/cares/cares/ares_llist.c +63 -0
  1242. data/third_party/cares/cares/ares_llist.h +39 -0
  1243. data/third_party/cares/cares/ares_mkquery.c +24 -0
  1244. data/third_party/cares/cares/ares_nowarn.c +260 -0
  1245. data/third_party/cares/cares/ares_nowarn.h +61 -0
  1246. data/third_party/cares/cares/ares_options.c +402 -0
  1247. data/third_party/cares/cares/ares_parse_a_reply.c +264 -0
  1248. data/third_party/cares/cares/ares_parse_aaaa_reply.c +264 -0
  1249. data/third_party/cares/cares/ares_parse_mx_reply.c +170 -0
  1250. data/third_party/cares/cares/ares_parse_naptr_reply.c +193 -0
  1251. data/third_party/cares/cares/ares_parse_ns_reply.c +183 -0
  1252. data/third_party/cares/cares/ares_parse_ptr_reply.c +219 -0
  1253. data/third_party/cares/cares/ares_parse_soa_reply.c +133 -0
  1254. data/third_party/cares/cares/ares_parse_srv_reply.c +179 -0
  1255. data/third_party/cares/cares/ares_parse_txt_reply.c +220 -0
  1256. data/third_party/cares/cares/ares_platform.c +11035 -0
  1257. data/third_party/cares/cares/ares_platform.h +43 -0
  1258. data/third_party/cares/cares/ares_private.h +374 -0
  1259. data/third_party/cares/cares/ares_process.c +1448 -0
  1260. data/third_party/cares/cares/ares_query.c +186 -0
  1261. data/third_party/cares/cares/ares_rules.h +125 -0
  1262. data/third_party/cares/cares/ares_search.c +316 -0
  1263. data/third_party/cares/cares/ares_send.c +131 -0
  1264. data/third_party/cares/cares/ares_setup.h +217 -0
  1265. data/third_party/cares/cares/ares_strcasecmp.c +66 -0
  1266. data/third_party/cares/cares/ares_strcasecmp.h +30 -0
  1267. data/third_party/cares/cares/ares_strdup.c +49 -0
  1268. data/third_party/cares/cares/ares_strdup.h +24 -0
  1269. data/third_party/cares/cares/ares_strerror.c +56 -0
  1270. data/third_party/cares/cares/ares_timeout.c +88 -0
  1271. data/third_party/cares/cares/ares_version.c +11 -0
  1272. data/third_party/cares/cares/ares_version.h +24 -0
  1273. data/third_party/cares/cares/ares_writev.c +79 -0
  1274. data/third_party/cares/cares/bitncmp.c +59 -0
  1275. data/third_party/cares/cares/bitncmp.h +26 -0
  1276. data/third_party/cares/cares/config-win32.h +351 -0
  1277. data/third_party/cares/cares/inet_net_pton.c +450 -0
  1278. data/third_party/cares/cares/inet_ntop.c +208 -0
  1279. data/third_party/cares/cares/setup_once.h +554 -0
  1280. data/third_party/cares/cares/windows_port.c +22 -0
  1281. data/third_party/cares/config_darwin/ares_config.h +425 -0
  1282. data/third_party/cares/config_freebsd/ares_config.h +502 -0
  1283. data/third_party/cares/config_linux/ares_config.h +458 -0
  1284. data/third_party/cares/config_openbsd/ares_config.h +502 -0
  1285. data/third_party/nanopb/pb.h +579 -0
  1286. data/third_party/nanopb/pb_common.c +97 -0
  1287. data/third_party/nanopb/pb_common.h +42 -0
  1288. data/third_party/nanopb/pb_decode.c +1347 -0
  1289. data/third_party/nanopb/pb_decode.h +149 -0
  1290. data/third_party/nanopb/pb_encode.c +696 -0
  1291. data/third_party/nanopb/pb_encode.h +154 -0
  1292. data/third_party/zlib/adler32.c +186 -0
  1293. data/third_party/zlib/compress.c +86 -0
  1294. data/third_party/zlib/crc32.c +442 -0
  1295. data/third_party/zlib/crc32.h +441 -0
  1296. data/third_party/zlib/deflate.c +2163 -0
  1297. data/third_party/zlib/deflate.h +349 -0
  1298. data/third_party/zlib/gzclose.c +25 -0
  1299. data/third_party/zlib/gzguts.h +218 -0
  1300. data/third_party/zlib/gzlib.c +637 -0
  1301. data/third_party/zlib/gzread.c +654 -0
  1302. data/third_party/zlib/gzwrite.c +665 -0
  1303. data/third_party/zlib/infback.c +640 -0
  1304. data/third_party/zlib/inffast.c +323 -0
  1305. data/third_party/zlib/inffast.h +11 -0
  1306. data/third_party/zlib/inffixed.h +94 -0
  1307. data/third_party/zlib/inflate.c +1561 -0
  1308. data/third_party/zlib/inflate.h +125 -0
  1309. data/third_party/zlib/inftrees.c +304 -0
  1310. data/third_party/zlib/inftrees.h +62 -0
  1311. data/third_party/zlib/trees.c +1203 -0
  1312. data/third_party/zlib/trees.h +128 -0
  1313. data/third_party/zlib/uncompr.c +93 -0
  1314. data/third_party/zlib/zconf.h +534 -0
  1315. data/third_party/zlib/zlib.h +1912 -0
  1316. data/third_party/zlib/zutil.c +325 -0
  1317. data/third_party/zlib/zutil.h +271 -0
  1318. metadata +1586 -0
@@ -0,0 +1,3209 @@
1
+ /*
2
+ *
3
+ * Copyright 2015 gRPC authors.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ */
18
+
19
+ #include <grpc/support/port_platform.h>
20
+
21
+ #include "src/core/ext/filters/client_channel/client_channel.h"
22
+
23
+ #include <inttypes.h>
24
+ #include <limits.h>
25
+ #include <stdbool.h>
26
+ #include <stdio.h>
27
+ #include <string.h>
28
+
29
+ #include <grpc/support/alloc.h>
30
+ #include <grpc/support/log.h>
31
+ #include <grpc/support/string_util.h>
32
+ #include <grpc/support/sync.h>
33
+
34
+ #include "src/core/ext/filters/client_channel/backup_poller.h"
35
+ #include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
36
+ #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
37
+ #include "src/core/ext/filters/client_channel/method_params.h"
38
+ #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
39
+ #include "src/core/ext/filters/client_channel/resolver_registry.h"
40
+ #include "src/core/ext/filters/client_channel/retry_throttle.h"
41
+ #include "src/core/ext/filters/client_channel/subchannel.h"
42
+ #include "src/core/ext/filters/deadline/deadline_filter.h"
43
+ #include "src/core/lib/backoff/backoff.h"
44
+ #include "src/core/lib/channel/channel_args.h"
45
+ #include "src/core/lib/channel/connected_channel.h"
46
+ #include "src/core/lib/channel/status_util.h"
47
+ #include "src/core/lib/gpr/string.h"
48
+ #include "src/core/lib/gprpp/inlined_vector.h"
49
+ #include "src/core/lib/gprpp/manual_constructor.h"
50
+ #include "src/core/lib/iomgr/combiner.h"
51
+ #include "src/core/lib/iomgr/iomgr.h"
52
+ #include "src/core/lib/iomgr/polling_entity.h"
53
+ #include "src/core/lib/profiling/timers.h"
54
+ #include "src/core/lib/slice/slice_internal.h"
55
+ #include "src/core/lib/slice/slice_string_helpers.h"
56
+ #include "src/core/lib/surface/channel.h"
57
+ #include "src/core/lib/transport/connectivity_state.h"
58
+ #include "src/core/lib/transport/error_utils.h"
59
+ #include "src/core/lib/transport/metadata.h"
60
+ #include "src/core/lib/transport/metadata_batch.h"
61
+ #include "src/core/lib/transport/service_config.h"
62
+ #include "src/core/lib/transport/static_metadata.h"
63
+ #include "src/core/lib/transport/status_metadata.h"
64
+
65
+ using grpc_core::internal::ClientChannelMethodParams;
66
+ using grpc_core::internal::ServerRetryThrottleData;
67
+
68
+ /* Client channel implementation */
69
+
70
+ // By default, we buffer 256 KiB per RPC for retries.
71
+ // TODO(roth): Do we have any data to suggest a better value?
72
+ #define DEFAULT_PER_RPC_RETRY_BUFFER_SIZE (256 << 10)
73
+
74
+ // This value was picked arbitrarily. It can be changed if there is
75
+ // any even moderately compelling reason to do so.
76
+ #define RETRY_BACKOFF_JITTER 0.2
77
+
78
+ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel");
79
+
80
+ /*************************************************************************
81
+ * CHANNEL-WIDE FUNCTIONS
82
+ */
83
+
84
+ struct external_connectivity_watcher;
85
+
86
+ typedef grpc_core::SliceHashTable<
87
+ grpc_core::RefCountedPtr<ClientChannelMethodParams>>
88
+ MethodParamsTable;
89
+
90
+ typedef struct client_channel_channel_data {
91
+ grpc_core::OrphanablePtr<grpc_core::Resolver> resolver;
92
+ bool started_resolving;
93
+ bool deadline_checking_enabled;
94
+ grpc_client_channel_factory* client_channel_factory;
95
+ bool enable_retries;
96
+ size_t per_rpc_retry_buffer_size;
97
+
98
+ /** combiner protecting all variables below in this data structure */
99
+ grpc_combiner* combiner;
100
+ /** currently active load balancer */
101
+ grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> lb_policy;
102
+ /** retry throttle data */
103
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
104
+ /** maps method names to method_parameters structs */
105
+ grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
106
+ /** incoming resolver result - set by resolver.next() */
107
+ grpc_channel_args* resolver_result;
108
+ /** a list of closures that are all waiting for resolver result to come in */
109
+ grpc_closure_list waiting_for_resolver_result_closures;
110
+ /** resolver callback */
111
+ grpc_closure on_resolver_result_changed;
112
+ /** connectivity state being tracked */
113
+ grpc_connectivity_state_tracker state_tracker;
114
+ /** when an lb_policy arrives, should we try to exit idle */
115
+ bool exit_idle_when_lb_policy_arrives;
116
+ /** owning stack */
117
+ grpc_channel_stack* owning_stack;
118
+ /** interested parties (owned) */
119
+ grpc_pollset_set* interested_parties;
120
+
121
+ /* external_connectivity_watcher_list head is guarded by its own mutex, since
122
+ * counts need to be grabbed immediately without polling on a cq */
123
+ gpr_mu external_connectivity_watcher_list_mu;
124
+ struct external_connectivity_watcher* external_connectivity_watcher_list_head;
125
+
126
+ /* the following properties are guarded by a mutex since APIs require them
127
+ to be instantaneously available */
128
+ gpr_mu info_mu;
129
+ char* info_lb_policy_name;
130
+ /** service config in JSON form */
131
+ char* info_service_config_json;
132
+ } channel_data;
133
+
134
+ typedef struct {
135
+ channel_data* chand;
136
+ /** used as an identifier, don't dereference it because the LB policy may be
137
+ * non-existing when the callback is run */
138
+ grpc_core::LoadBalancingPolicy* lb_policy;
139
+ grpc_closure closure;
140
+ } reresolution_request_args;
141
+
142
+ /** We create one watcher for each new lb_policy that is returned from a
143
+ resolver, to watch for state changes from the lb_policy. When a state
144
+ change is seen, we update the channel, and create a new watcher. */
145
+ typedef struct {
146
+ channel_data* chand;
147
+ grpc_closure on_changed;
148
+ grpc_connectivity_state state;
149
+ grpc_core::LoadBalancingPolicy* lb_policy;
150
+ } lb_policy_connectivity_watcher;
151
+
152
+ static void watch_lb_policy_locked(channel_data* chand,
153
+ grpc_core::LoadBalancingPolicy* lb_policy,
154
+ grpc_connectivity_state current_state);
155
+
156
+ static void set_channel_connectivity_state_locked(channel_data* chand,
157
+ grpc_connectivity_state state,
158
+ grpc_error* error,
159
+ const char* reason) {
160
+ /* TODO: Improve failure handling:
161
+ * - Make it possible for policies to return GRPC_CHANNEL_TRANSIENT_FAILURE.
162
+ * - Hand over pending picks from old policies during the switch that happens
163
+ * when resolver provides an update. */
164
+ if (chand->lb_policy != nullptr) {
165
+ if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
166
+ /* cancel picks with wait_for_ready=false */
167
+ chand->lb_policy->CancelMatchingPicksLocked(
168
+ /* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
169
+ /* check= */ 0, GRPC_ERROR_REF(error));
170
+ } else if (state == GRPC_CHANNEL_SHUTDOWN) {
171
+ /* cancel all picks */
172
+ chand->lb_policy->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0,
173
+ GRPC_ERROR_REF(error));
174
+ }
175
+ }
176
+ if (grpc_client_channel_trace.enabled()) {
177
+ gpr_log(GPR_DEBUG, "chand=%p: setting connectivity state to %s", chand,
178
+ grpc_connectivity_state_name(state));
179
+ }
180
+ grpc_connectivity_state_set(&chand->state_tracker, state, error, reason);
181
+ }
182
+
183
+ static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) {
184
+ lb_policy_connectivity_watcher* w =
185
+ static_cast<lb_policy_connectivity_watcher*>(arg);
186
+ /* check if the notification is for the latest policy */
187
+ if (w->lb_policy == w->chand->lb_policy.get()) {
188
+ if (grpc_client_channel_trace.enabled()) {
189
+ gpr_log(GPR_DEBUG, "chand=%p: lb_policy=%p state changed to %s", w->chand,
190
+ w->lb_policy, grpc_connectivity_state_name(w->state));
191
+ }
192
+ set_channel_connectivity_state_locked(w->chand, w->state,
193
+ GRPC_ERROR_REF(error), "lb_changed");
194
+ if (w->state != GRPC_CHANNEL_SHUTDOWN) {
195
+ watch_lb_policy_locked(w->chand, w->lb_policy, w->state);
196
+ }
197
+ }
198
+ GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack, "watch_lb_policy");
199
+ gpr_free(w);
200
+ }
201
+
202
+ static void watch_lb_policy_locked(channel_data* chand,
203
+ grpc_core::LoadBalancingPolicy* lb_policy,
204
+ grpc_connectivity_state current_state) {
205
+ lb_policy_connectivity_watcher* w =
206
+ static_cast<lb_policy_connectivity_watcher*>(gpr_malloc(sizeof(*w)));
207
+ GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy");
208
+ w->chand = chand;
209
+ GRPC_CLOSURE_INIT(&w->on_changed, on_lb_policy_state_changed_locked, w,
210
+ grpc_combiner_scheduler(chand->combiner));
211
+ w->state = current_state;
212
+ w->lb_policy = lb_policy;
213
+ lb_policy->NotifyOnStateChangeLocked(&w->state, &w->on_changed);
214
+ }
215
+
216
+ static void start_resolving_locked(channel_data* chand) {
217
+ if (grpc_client_channel_trace.enabled()) {
218
+ gpr_log(GPR_DEBUG, "chand=%p: starting name resolution", chand);
219
+ }
220
+ GPR_ASSERT(!chand->started_resolving);
221
+ chand->started_resolving = true;
222
+ GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
223
+ chand->resolver->NextLocked(&chand->resolver_result,
224
+ &chand->on_resolver_result_changed);
225
+ }
226
+
227
+ typedef struct {
228
+ char* server_name;
229
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
230
+ } service_config_parsing_state;
231
+
232
+ static void parse_retry_throttle_params(
233
+ const grpc_json* field, service_config_parsing_state* parsing_state) {
234
+ if (strcmp(field->key, "retryThrottling") == 0) {
235
+ if (parsing_state->retry_throttle_data != nullptr) return; // Duplicate.
236
+ if (field->type != GRPC_JSON_OBJECT) return;
237
+ int max_milli_tokens = 0;
238
+ int milli_token_ratio = 0;
239
+ for (grpc_json* sub_field = field->child; sub_field != nullptr;
240
+ sub_field = sub_field->next) {
241
+ if (sub_field->key == nullptr) return;
242
+ if (strcmp(sub_field->key, "maxTokens") == 0) {
243
+ if (max_milli_tokens != 0) return; // Duplicate.
244
+ if (sub_field->type != GRPC_JSON_NUMBER) return;
245
+ max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
246
+ if (max_milli_tokens == -1) return;
247
+ max_milli_tokens *= 1000;
248
+ } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
249
+ if (milli_token_ratio != 0) return; // Duplicate.
250
+ if (sub_field->type != GRPC_JSON_NUMBER) return;
251
+ // We support up to 3 decimal digits.
252
+ size_t whole_len = strlen(sub_field->value);
253
+ uint32_t multiplier = 1;
254
+ uint32_t decimal_value = 0;
255
+ const char* decimal_point = strchr(sub_field->value, '.');
256
+ if (decimal_point != nullptr) {
257
+ whole_len = static_cast<size_t>(decimal_point - sub_field->value);
258
+ multiplier = 1000;
259
+ size_t decimal_len = strlen(decimal_point + 1);
260
+ if (decimal_len > 3) decimal_len = 3;
261
+ if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
262
+ &decimal_value)) {
263
+ return;
264
+ }
265
+ uint32_t decimal_multiplier = 1;
266
+ for (size_t i = 0; i < (3 - decimal_len); ++i) {
267
+ decimal_multiplier *= 10;
268
+ }
269
+ decimal_value *= decimal_multiplier;
270
+ }
271
+ uint32_t whole_value;
272
+ if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
273
+ &whole_value)) {
274
+ return;
275
+ }
276
+ milli_token_ratio =
277
+ static_cast<int>((whole_value * multiplier) + decimal_value);
278
+ if (milli_token_ratio <= 0) return;
279
+ }
280
+ }
281
+ parsing_state->retry_throttle_data =
282
+ grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
283
+ parsing_state->server_name, max_milli_tokens, milli_token_ratio);
284
+ }
285
+ }
286
+
287
+ static void request_reresolution_locked(void* arg, grpc_error* error) {
288
+ reresolution_request_args* args =
289
+ static_cast<reresolution_request_args*>(arg);
290
+ channel_data* chand = args->chand;
291
+ // If this invocation is for a stale LB policy, treat it as an LB shutdown
292
+ // signal.
293
+ if (args->lb_policy != chand->lb_policy.get() || error != GRPC_ERROR_NONE ||
294
+ chand->resolver == nullptr) {
295
+ GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "re-resolution");
296
+ gpr_free(args);
297
+ return;
298
+ }
299
+ if (grpc_client_channel_trace.enabled()) {
300
+ gpr_log(GPR_DEBUG, "chand=%p: started name re-resolving", chand);
301
+ }
302
+ chand->resolver->RequestReresolutionLocked();
303
+ // Give back the closure to the LB policy.
304
+ chand->lb_policy->SetReresolutionClosureLocked(&args->closure);
305
+ }
306
+
307
+ // TODO(roth): The logic in this function is very hard to follow. We
308
+ // should refactor this so that it's easier to understand, perhaps as
309
+ // part of changing the resolver API to more clearly differentiate
310
+ // between transient failures and shutdown.
311
+ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
312
+ channel_data* chand = static_cast<channel_data*>(arg);
313
+ if (grpc_client_channel_trace.enabled()) {
314
+ gpr_log(GPR_DEBUG,
315
+ "chand=%p: got resolver result: resolver_result=%p error=%s", chand,
316
+ chand->resolver_result, grpc_error_string(error));
317
+ }
318
+ // Extract the following fields from the resolver result, if non-nullptr.
319
+ bool lb_policy_updated = false;
320
+ bool lb_policy_created = false;
321
+ char* lb_policy_name_dup = nullptr;
322
+ bool lb_policy_name_changed = false;
323
+ grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> new_lb_policy;
324
+ char* service_config_json = nullptr;
325
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
326
+ grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
327
+ if (chand->resolver_result != nullptr) {
328
+ if (chand->resolver != nullptr) {
329
+ // Find LB policy name.
330
+ const grpc_arg* channel_arg = grpc_channel_args_find(
331
+ chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
332
+ const char* lb_policy_name = grpc_channel_arg_get_string(channel_arg);
333
+ // Special case: If at least one balancer address is present, we use
334
+ // the grpclb policy, regardless of what the resolver actually specified.
335
+ channel_arg =
336
+ grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
337
+ if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
338
+ grpc_lb_addresses* addresses =
339
+ static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
340
+ bool found_balancer_address = false;
341
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
342
+ if (addresses->addresses[i].is_balancer) {
343
+ found_balancer_address = true;
344
+ break;
345
+ }
346
+ }
347
+ if (found_balancer_address) {
348
+ if (lb_policy_name != nullptr &&
349
+ strcmp(lb_policy_name, "grpclb") != 0) {
350
+ gpr_log(GPR_INFO,
351
+ "resolver requested LB policy %s but provided at least one "
352
+ "balancer address -- forcing use of grpclb LB policy",
353
+ lb_policy_name);
354
+ }
355
+ lb_policy_name = "grpclb";
356
+ }
357
+ }
358
+ // Use pick_first if nothing was specified and we didn't select grpclb
359
+ // above.
360
+ if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
361
+ // Check to see if we're already using the right LB policy.
362
+ // Note: It's safe to use chand->info_lb_policy_name here without
363
+ // taking a lock on chand->info_mu, because this function is the
364
+ // only thing that modifies its value, and it can only be invoked
365
+ // once at any given time.
366
+ lb_policy_name_changed =
367
+ chand->info_lb_policy_name == nullptr ||
368
+ gpr_stricmp(chand->info_lb_policy_name, lb_policy_name) != 0;
369
+ if (chand->lb_policy != nullptr && !lb_policy_name_changed) {
370
+ // Continue using the same LB policy. Update with new addresses.
371
+ lb_policy_updated = true;
372
+ chand->lb_policy->UpdateLocked(*chand->resolver_result);
373
+ } else {
374
+ // Instantiate new LB policy.
375
+ grpc_core::LoadBalancingPolicy::Args lb_policy_args;
376
+ lb_policy_args.combiner = chand->combiner;
377
+ lb_policy_args.client_channel_factory = chand->client_channel_factory;
378
+ lb_policy_args.args = chand->resolver_result;
379
+ new_lb_policy =
380
+ grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
381
+ lb_policy_name, lb_policy_args);
382
+ if (new_lb_policy == nullptr) {
383
+ gpr_log(GPR_ERROR, "could not create LB policy \"%s\"",
384
+ lb_policy_name);
385
+ } else {
386
+ lb_policy_created = true;
387
+ reresolution_request_args* args =
388
+ static_cast<reresolution_request_args*>(
389
+ gpr_zalloc(sizeof(*args)));
390
+ args->chand = chand;
391
+ args->lb_policy = new_lb_policy.get();
392
+ GRPC_CLOSURE_INIT(&args->closure, request_reresolution_locked, args,
393
+ grpc_combiner_scheduler(chand->combiner));
394
+ GRPC_CHANNEL_STACK_REF(chand->owning_stack, "re-resolution");
395
+ new_lb_policy->SetReresolutionClosureLocked(&args->closure);
396
+ }
397
+ }
398
+ // Before we clean up, save a copy of lb_policy_name, since it might
399
+ // be pointing to data inside chand->resolver_result.
400
+ // The copy will be saved in chand->lb_policy_name below.
401
+ lb_policy_name_dup = gpr_strdup(lb_policy_name);
402
+ // Find service config.
403
+ channel_arg = grpc_channel_args_find(chand->resolver_result,
404
+ GRPC_ARG_SERVICE_CONFIG);
405
+ service_config_json =
406
+ gpr_strdup(grpc_channel_arg_get_string(channel_arg));
407
+ if (service_config_json != nullptr) {
408
+ grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
409
+ grpc_core::ServiceConfig::Create(service_config_json);
410
+ if (service_config != nullptr) {
411
+ if (chand->enable_retries) {
412
+ channel_arg = grpc_channel_args_find(chand->resolver_result,
413
+ GRPC_ARG_SERVER_URI);
414
+ const char* server_uri = grpc_channel_arg_get_string(channel_arg);
415
+ GPR_ASSERT(server_uri != nullptr);
416
+ grpc_uri* uri = grpc_uri_parse(server_uri, true);
417
+ GPR_ASSERT(uri->path[0] != '\0');
418
+ service_config_parsing_state parsing_state;
419
+ memset(&parsing_state, 0, sizeof(parsing_state));
420
+ parsing_state.server_name =
421
+ uri->path[0] == '/' ? uri->path + 1 : uri->path;
422
+ service_config->ParseGlobalParams(parse_retry_throttle_params,
423
+ &parsing_state);
424
+ grpc_uri_destroy(uri);
425
+ retry_throttle_data = std::move(parsing_state.retry_throttle_data);
426
+ }
427
+ method_params_table = service_config->CreateMethodConfigTable(
428
+ ClientChannelMethodParams::CreateFromJson);
429
+ }
430
+ }
431
+ }
432
+ }
433
+ if (grpc_client_channel_trace.enabled()) {
434
+ gpr_log(GPR_DEBUG,
435
+ "chand=%p: resolver result: lb_policy_name=\"%s\"%s, "
436
+ "service_config=\"%s\"",
437
+ chand, lb_policy_name_dup,
438
+ lb_policy_name_changed ? " (changed)" : "", service_config_json);
439
+ }
440
+ // Now swap out fields in chand. Note that the new values may still
441
+ // be nullptr if (e.g.) the resolver failed to return results or the
442
+ // results did not contain the necessary data.
443
+ //
444
+ // First, swap out the data used by cc_get_channel_info().
445
+ gpr_mu_lock(&chand->info_mu);
446
+ if (lb_policy_name_dup != nullptr) {
447
+ gpr_free(chand->info_lb_policy_name);
448
+ chand->info_lb_policy_name = lb_policy_name_dup;
449
+ }
450
+ if (service_config_json != nullptr) {
451
+ gpr_free(chand->info_service_config_json);
452
+ chand->info_service_config_json = service_config_json;
453
+ }
454
+ gpr_mu_unlock(&chand->info_mu);
455
+ // Swap out the retry throttle data.
456
+ chand->retry_throttle_data = std::move(retry_throttle_data);
457
+ // Swap out the method params table.
458
+ chand->method_params_table = std::move(method_params_table);
459
+ // If we have a new LB policy or are shutting down (in which case
460
+ // new_lb_policy will be nullptr), swap out the LB policy, unreffing the
461
+ // old one and removing its fds from chand->interested_parties.
462
+ // Note that we do NOT do this if either (a) we updated the existing
463
+ // LB policy above or (b) we failed to create the new LB policy (in
464
+ // which case we want to continue using the most recent one we had).
465
+ if (new_lb_policy != nullptr || error != GRPC_ERROR_NONE ||
466
+ chand->resolver == nullptr) {
467
+ if (chand->lb_policy != nullptr) {
468
+ if (grpc_client_channel_trace.enabled()) {
469
+ gpr_log(GPR_DEBUG, "chand=%p: unreffing lb_policy=%p", chand,
470
+ chand->lb_policy.get());
471
+ }
472
+ grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
473
+ chand->interested_parties);
474
+ chand->lb_policy->HandOffPendingPicksLocked(new_lb_policy.get());
475
+ chand->lb_policy.reset();
476
+ }
477
+ chand->lb_policy = std::move(new_lb_policy);
478
+ }
479
+ // Now that we've swapped out the relevant fields of chand, check for
480
+ // error or shutdown.
481
+ if (error != GRPC_ERROR_NONE || chand->resolver == nullptr) {
482
+ if (grpc_client_channel_trace.enabled()) {
483
+ gpr_log(GPR_DEBUG, "chand=%p: shutting down", chand);
484
+ }
485
+ if (chand->resolver != nullptr) {
486
+ if (grpc_client_channel_trace.enabled()) {
487
+ gpr_log(GPR_DEBUG, "chand=%p: shutting down resolver", chand);
488
+ }
489
+ chand->resolver.reset();
490
+ }
491
+ set_channel_connectivity_state_locked(
492
+ chand, GRPC_CHANNEL_SHUTDOWN,
493
+ GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
494
+ "Got resolver result after disconnection", &error, 1),
495
+ "resolver_gone");
496
+ grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures,
497
+ GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
498
+ "Channel disconnected", &error, 1));
499
+ GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
500
+ GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "resolver");
501
+ grpc_channel_args_destroy(chand->resolver_result);
502
+ chand->resolver_result = nullptr;
503
+ } else { // Not shutting down.
504
+ grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
505
+ grpc_error* state_error =
506
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
507
+ if (lb_policy_created) {
508
+ if (grpc_client_channel_trace.enabled()) {
509
+ gpr_log(GPR_DEBUG, "chand=%p: initializing new LB policy", chand);
510
+ }
511
+ GRPC_ERROR_UNREF(state_error);
512
+ state = chand->lb_policy->CheckConnectivityLocked(&state_error);
513
+ grpc_pollset_set_add_pollset_set(chand->lb_policy->interested_parties(),
514
+ chand->interested_parties);
515
+ GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
516
+ if (chand->exit_idle_when_lb_policy_arrives) {
517
+ chand->lb_policy->ExitIdleLocked();
518
+ chand->exit_idle_when_lb_policy_arrives = false;
519
+ }
520
+ watch_lb_policy_locked(chand, chand->lb_policy.get(), state);
521
+ } else if (chand->resolver_result == nullptr) {
522
+ // Transient failure.
523
+ GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
524
+ }
525
+ if (!lb_policy_updated) {
526
+ set_channel_connectivity_state_locked(
527
+ chand, state, GRPC_ERROR_REF(state_error), "new_lb+resolver");
528
+ }
529
+ grpc_channel_args_destroy(chand->resolver_result);
530
+ chand->resolver_result = nullptr;
531
+ chand->resolver->NextLocked(&chand->resolver_result,
532
+ &chand->on_resolver_result_changed);
533
+ GRPC_ERROR_UNREF(state_error);
534
+ }
535
+ }
536
+
537
+ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
538
+ grpc_transport_op* op = static_cast<grpc_transport_op*>(arg);
539
+ grpc_channel_element* elem =
540
+ static_cast<grpc_channel_element*>(op->handler_private.extra_arg);
541
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
542
+
543
+ if (op->on_connectivity_state_change != nullptr) {
544
+ grpc_connectivity_state_notify_on_state_change(
545
+ &chand->state_tracker, op->connectivity_state,
546
+ op->on_connectivity_state_change);
547
+ op->on_connectivity_state_change = nullptr;
548
+ op->connectivity_state = nullptr;
549
+ }
550
+
551
+ if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) {
552
+ if (chand->lb_policy == nullptr) {
553
+ GRPC_CLOSURE_SCHED(
554
+ op->send_ping.on_initiate,
555
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
556
+ GRPC_CLOSURE_SCHED(
557
+ op->send_ping.on_ack,
558
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
559
+ } else {
560
+ chand->lb_policy->PingOneLocked(op->send_ping.on_initiate,
561
+ op->send_ping.on_ack);
562
+ op->bind_pollset = nullptr;
563
+ }
564
+ op->send_ping.on_initiate = nullptr;
565
+ op->send_ping.on_ack = nullptr;
566
+ }
567
+
568
+ if (op->disconnect_with_error != GRPC_ERROR_NONE) {
569
+ if (chand->resolver != nullptr) {
570
+ set_channel_connectivity_state_locked(
571
+ chand, GRPC_CHANNEL_SHUTDOWN,
572
+ GRPC_ERROR_REF(op->disconnect_with_error), "disconnect");
573
+ chand->resolver.reset();
574
+ if (!chand->started_resolving) {
575
+ grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures,
576
+ GRPC_ERROR_REF(op->disconnect_with_error));
577
+ GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
578
+ }
579
+ if (chand->lb_policy != nullptr) {
580
+ grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
581
+ chand->interested_parties);
582
+ chand->lb_policy.reset();
583
+ }
584
+ }
585
+ GRPC_ERROR_UNREF(op->disconnect_with_error);
586
+ }
587
+ GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "start_transport_op");
588
+
589
+ GRPC_CLOSURE_SCHED(op->on_consumed, GRPC_ERROR_NONE);
590
+ }
591
+
592
+ static void cc_start_transport_op(grpc_channel_element* elem,
593
+ grpc_transport_op* op) {
594
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
595
+
596
+ GPR_ASSERT(op->set_accept_stream == false);
597
+ if (op->bind_pollset != nullptr) {
598
+ grpc_pollset_set_add_pollset(chand->interested_parties, op->bind_pollset);
599
+ }
600
+
601
+ op->handler_private.extra_arg = elem;
602
+ GRPC_CHANNEL_STACK_REF(chand->owning_stack, "start_transport_op");
603
+ GRPC_CLOSURE_SCHED(
604
+ GRPC_CLOSURE_INIT(&op->handler_private.closure, start_transport_op_locked,
605
+ op, grpc_combiner_scheduler(chand->combiner)),
606
+ GRPC_ERROR_NONE);
607
+ }
608
+
609
+ static void cc_get_channel_info(grpc_channel_element* elem,
610
+ const grpc_channel_info* info) {
611
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
612
+ gpr_mu_lock(&chand->info_mu);
613
+ if (info->lb_policy_name != nullptr) {
614
+ *info->lb_policy_name = chand->info_lb_policy_name == nullptr
615
+ ? nullptr
616
+ : gpr_strdup(chand->info_lb_policy_name);
617
+ }
618
+ if (info->service_config_json != nullptr) {
619
+ *info->service_config_json =
620
+ chand->info_service_config_json == nullptr
621
+ ? nullptr
622
+ : gpr_strdup(chand->info_service_config_json);
623
+ }
624
+ gpr_mu_unlock(&chand->info_mu);
625
+ }
626
+
627
+ /* Constructor for channel_data */
628
+ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem,
629
+ grpc_channel_element_args* args) {
630
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
631
+ GPR_ASSERT(args->is_last);
632
+ GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
633
+ // Initialize data members.
634
+ chand->combiner = grpc_combiner_create();
635
+ gpr_mu_init(&chand->info_mu);
636
+ gpr_mu_init(&chand->external_connectivity_watcher_list_mu);
637
+
638
+ gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
639
+ chand->external_connectivity_watcher_list_head = nullptr;
640
+ gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
641
+
642
+ chand->owning_stack = args->channel_stack;
643
+ GRPC_CLOSURE_INIT(&chand->on_resolver_result_changed,
644
+ on_resolver_result_changed_locked, chand,
645
+ grpc_combiner_scheduler(chand->combiner));
646
+ chand->interested_parties = grpc_pollset_set_create();
647
+ grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
648
+ "client_channel");
649
+ grpc_client_channel_start_backup_polling(chand->interested_parties);
650
+ // Record max per-RPC retry buffer size.
651
+ const grpc_arg* arg = grpc_channel_args_find(
652
+ args->channel_args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE);
653
+ chand->per_rpc_retry_buffer_size = (size_t)grpc_channel_arg_get_integer(
654
+ arg, {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX});
655
+ // Record enable_retries.
656
+ arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES);
657
+ chand->enable_retries = grpc_channel_arg_get_bool(arg, true);
658
+ // Record client channel factory.
659
+ arg = grpc_channel_args_find(args->channel_args,
660
+ GRPC_ARG_CLIENT_CHANNEL_FACTORY);
661
+ if (arg == nullptr) {
662
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
663
+ "Missing client channel factory in args for client channel filter");
664
+ }
665
+ if (arg->type != GRPC_ARG_POINTER) {
666
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
667
+ "client channel factory arg must be a pointer");
668
+ }
669
+ grpc_client_channel_factory_ref(
670
+ static_cast<grpc_client_channel_factory*>(arg->value.pointer.p));
671
+ chand->client_channel_factory =
672
+ static_cast<grpc_client_channel_factory*>(arg->value.pointer.p);
673
+ // Get server name to resolve, using proxy mapper if needed.
674
+ arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
675
+ if (arg == nullptr) {
676
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
677
+ "Missing server uri in args for client channel filter");
678
+ }
679
+ if (arg->type != GRPC_ARG_STRING) {
680
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
681
+ "server uri arg must be a string");
682
+ }
683
+ char* proxy_name = nullptr;
684
+ grpc_channel_args* new_args = nullptr;
685
+ grpc_proxy_mappers_map_name(arg->value.string, args->channel_args,
686
+ &proxy_name, &new_args);
687
+ // Instantiate resolver.
688
+ chand->resolver = grpc_core::ResolverRegistry::CreateResolver(
689
+ proxy_name != nullptr ? proxy_name : arg->value.string,
690
+ new_args != nullptr ? new_args : args->channel_args,
691
+ chand->interested_parties, chand->combiner);
692
+ if (proxy_name != nullptr) gpr_free(proxy_name);
693
+ if (new_args != nullptr) grpc_channel_args_destroy(new_args);
694
+ if (chand->resolver == nullptr) {
695
+ return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed");
696
+ }
697
+ chand->deadline_checking_enabled =
698
+ grpc_deadline_checking_enabled(args->channel_args);
699
+ return GRPC_ERROR_NONE;
700
+ }
701
+
702
+ static void shutdown_resolver_locked(void* arg, grpc_error* error) {
703
+ grpc_core::Resolver* resolver = static_cast<grpc_core::Resolver*>(arg);
704
+ resolver->Orphan();
705
+ }
706
+
707
+ /* Destructor for channel_data */
708
+ static void cc_destroy_channel_elem(grpc_channel_element* elem) {
709
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
710
+ if (chand->resolver != nullptr) {
711
+ GRPC_CLOSURE_SCHED(
712
+ GRPC_CLOSURE_CREATE(shutdown_resolver_locked, chand->resolver.release(),
713
+ grpc_combiner_scheduler(chand->combiner)),
714
+ GRPC_ERROR_NONE);
715
+ }
716
+ if (chand->client_channel_factory != nullptr) {
717
+ grpc_client_channel_factory_unref(chand->client_channel_factory);
718
+ }
719
+ if (chand->lb_policy != nullptr) {
720
+ grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
721
+ chand->interested_parties);
722
+ chand->lb_policy.reset();
723
+ }
724
+ gpr_free(chand->info_lb_policy_name);
725
+ gpr_free(chand->info_service_config_json);
726
+ chand->retry_throttle_data.reset();
727
+ chand->method_params_table.reset();
728
+ grpc_client_channel_stop_backup_polling(chand->interested_parties);
729
+ grpc_connectivity_state_destroy(&chand->state_tracker);
730
+ grpc_pollset_set_destroy(chand->interested_parties);
731
+ GRPC_COMBINER_UNREF(chand->combiner, "client_channel");
732
+ gpr_mu_destroy(&chand->info_mu);
733
+ gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu);
734
+ }
735
+
736
+ /*************************************************************************
737
+ * PER-CALL FUNCTIONS
738
+ */
739
+
740
+ // Max number of batches that can be pending on a call at any given
741
+ // time. This includes one batch for each of the following ops:
742
+ // recv_initial_metadata
743
+ // send_initial_metadata
744
+ // recv_message
745
+ // send_message
746
+ // recv_trailing_metadata
747
+ // send_trailing_metadata
748
+ #define MAX_PENDING_BATCHES 6
749
+
750
+ // Retry support:
751
+ //
752
+ // In order to support retries, we act as a proxy for stream op batches.
753
+ // When we get a batch from the surface, we add it to our list of pending
754
+ // batches, and we then use those batches to construct separate "child"
755
+ // batches to be started on the subchannel call. When the child batches
756
+ // return, we then decide which pending batches have been completed and
757
+ // schedule their callbacks accordingly. If a subchannel call fails and
758
+ // we want to retry it, we do a new pick and start again, constructing
759
+ // new "child" batches for the new subchannel call.
760
+ //
761
+ // Note that retries are committed when receiving data from the server
762
+ // (except for Trailers-Only responses). However, there may be many
763
+ // send ops started before receiving any data, so we may have already
764
+ // completed some number of send ops (and returned the completions up to
765
+ // the surface) by the time we realize that we need to retry. To deal
766
+ // with this, we cache data for send ops, so that we can replay them on a
767
+ // different subchannel call even after we have completed the original
768
+ // batches.
769
+ //
770
+ // There are two sets of data to maintain:
771
+ // - In call_data (in the parent channel), we maintain a list of pending
772
+ // ops and cached data for send ops.
773
+ // - In the subchannel call, we maintain state to indicate what ops have
774
+ // already been sent down to that call.
775
+ //
776
+ // When constructing the "child" batches, we compare those two sets of
777
+ // data to see which batches need to be sent to the subchannel call.
778
+
779
+ // TODO(roth): In subsequent PRs:
780
+ // - add support for transparent retries (including initial metadata)
781
+ // - figure out how to record stats in census for retries
782
+ // (census filter is on top of this one)
783
+ // - add census stats for retries
784
+
785
+ // State used for starting a retryable batch on a subchannel call.
786
+ // This provides its own grpc_transport_stream_op_batch and other data
787
+ // structures needed to populate the ops in the batch.
788
+ // We allocate one struct on the arena for each attempt at starting a
789
+ // batch on a given subchannel call.
790
+ typedef struct {
791
+ gpr_refcount refs;
792
+ grpc_call_element* elem;
793
+ grpc_subchannel_call* subchannel_call; // Holds a ref.
794
+ // The batch to use in the subchannel call.
795
+ // Its payload field points to subchannel_call_retry_state.batch_payload.
796
+ grpc_transport_stream_op_batch batch;
797
+ // For send_initial_metadata.
798
+ // Note that we need to make a copy of the initial metadata for each
799
+ // subchannel call instead of just referring to the copy in call_data,
800
+ // because filters in the subchannel stack will probably add entries,
801
+ // so we need to start in a pristine state for each attempt of the call.
802
+ grpc_linked_mdelem* send_initial_metadata_storage;
803
+ grpc_metadata_batch send_initial_metadata;
804
+ // For send_message.
805
+ grpc_core::ManualConstructor<grpc_core::ByteStreamCache::CachingByteStream>
806
+ send_message;
807
+ // For send_trailing_metadata.
808
+ grpc_linked_mdelem* send_trailing_metadata_storage;
809
+ grpc_metadata_batch send_trailing_metadata;
810
+ // For intercepting recv_initial_metadata.
811
+ grpc_metadata_batch recv_initial_metadata;
812
+ grpc_closure recv_initial_metadata_ready;
813
+ bool trailing_metadata_available;
814
+ // For intercepting recv_message.
815
+ grpc_closure recv_message_ready;
816
+ grpc_core::OrphanablePtr<grpc_core::ByteStream> recv_message;
817
+ // For intercepting recv_trailing_metadata.
818
+ grpc_metadata_batch recv_trailing_metadata;
819
+ grpc_transport_stream_stats collect_stats;
820
+ // For intercepting on_complete.
821
+ grpc_closure on_complete;
822
+ } subchannel_batch_data;
823
+
824
+ // Retry state associated with a subchannel call.
825
+ // Stored in the parent_data of the subchannel call object.
826
+ typedef struct {
827
+ // subchannel_batch_data.batch.payload points to this.
828
+ grpc_transport_stream_op_batch_payload batch_payload;
829
+ // These fields indicate which ops have been started and completed on
830
+ // this subchannel call.
831
+ size_t started_send_message_count;
832
+ size_t completed_send_message_count;
833
+ size_t started_recv_message_count;
834
+ size_t completed_recv_message_count;
835
+ bool started_send_initial_metadata : 1;
836
+ bool completed_send_initial_metadata : 1;
837
+ bool started_send_trailing_metadata : 1;
838
+ bool completed_send_trailing_metadata : 1;
839
+ bool started_recv_initial_metadata : 1;
840
+ bool completed_recv_initial_metadata : 1;
841
+ bool started_recv_trailing_metadata : 1;
842
+ bool completed_recv_trailing_metadata : 1;
843
+ // State for callback processing.
844
+ bool retry_dispatched : 1;
845
+ bool recv_initial_metadata_ready_deferred : 1;
846
+ bool recv_message_ready_deferred : 1;
847
+ grpc_error* recv_initial_metadata_error;
848
+ grpc_error* recv_message_error;
849
+ } subchannel_call_retry_state;
850
+
851
+ // Pending batches stored in call data.
852
+ typedef struct {
853
+ // The pending batch. If nullptr, this slot is empty.
854
+ grpc_transport_stream_op_batch* batch;
855
+ // Indicates whether payload for send ops has been cached in call data.
856
+ bool send_ops_cached;
857
+ } pending_batch;
858
+
859
+ /** Call data. Holds a pointer to grpc_subchannel_call and the
860
+ associated machinery to create such a pointer.
861
+ Handles queueing of stream ops until a call object is ready, waiting
862
+ for initial metadata before trying to create a call object,
863
+ and handling cancellation gracefully. */
864
+ typedef struct client_channel_call_data {
865
+ // State for handling deadlines.
866
+ // The code in deadline_filter.c requires this to be the first field.
867
+ // TODO(roth): This is slightly sub-optimal in that grpc_deadline_state
868
+ // and this struct both independently store pointers to the call stack
869
+ // and call combiner. If/when we have time, find a way to avoid this
870
+ // without breaking the grpc_deadline_state abstraction.
871
+ grpc_deadline_state deadline_state;
872
+
873
+ grpc_slice path; // Request path.
874
+ gpr_timespec call_start_time;
875
+ grpc_millis deadline;
876
+ gpr_arena* arena;
877
+ grpc_call_stack* owning_call;
878
+ grpc_call_combiner* call_combiner;
879
+
880
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
881
+ grpc_core::RefCountedPtr<ClientChannelMethodParams> method_params;
882
+
883
+ grpc_subchannel_call* subchannel_call;
884
+
885
+ // Set when we get a cancel_stream op.
886
+ grpc_error* cancel_error;
887
+
888
+ grpc_core::LoadBalancingPolicy::PickState pick;
889
+ grpc_closure pick_closure;
890
+ grpc_closure pick_cancel_closure;
891
+
892
+ grpc_polling_entity* pollent;
893
+
894
+ // Batches are added to this list when received from above.
895
+ // They are removed when we are done handling the batch (i.e., when
896
+ // either we have invoked all of the batch's callbacks or we have
897
+ // passed the batch down to the subchannel call and are not
898
+ // intercepting any of its callbacks).
899
+ pending_batch pending_batches[MAX_PENDING_BATCHES];
900
+ bool pending_send_initial_metadata : 1;
901
+ bool pending_send_message : 1;
902
+ bool pending_send_trailing_metadata : 1;
903
+
904
+ // Retry state.
905
+ bool enable_retries : 1;
906
+ bool retry_committed : 1;
907
+ bool last_attempt_got_server_pushback : 1;
908
+ int num_attempts_completed;
909
+ size_t bytes_buffered_for_retry;
910
+ grpc_core::ManualConstructor<grpc_core::BackOff> retry_backoff;
911
+ grpc_timer retry_timer;
912
+
913
+ // Cached data for retrying send ops.
914
+ // send_initial_metadata
915
+ bool seen_send_initial_metadata;
916
+ grpc_linked_mdelem* send_initial_metadata_storage;
917
+ grpc_metadata_batch send_initial_metadata;
918
+ uint32_t send_initial_metadata_flags;
919
+ gpr_atm* peer_string;
920
+ // send_message
921
+ // When we get a send_message op, we replace the original byte stream
922
+ // with a CachingByteStream that caches the slices to a local buffer for
923
+ // use in retries.
924
+ // Note: We inline the cache for the first 3 send_message ops and use
925
+ // dynamic allocation after that. This number was essentially picked
926
+ // at random; it could be changed in the future to tune performance.
927
+ grpc_core::InlinedVector<grpc_core::ByteStreamCache*, 3> send_messages;
928
+ // send_trailing_metadata
929
+ bool seen_send_trailing_metadata;
930
+ grpc_linked_mdelem* send_trailing_metadata_storage;
931
+ grpc_metadata_batch send_trailing_metadata;
932
+ } call_data;
933
+
934
+ // Forward declarations.
935
+ static void retry_commit(grpc_call_element* elem,
936
+ subchannel_call_retry_state* retry_state);
937
+ static void start_internal_recv_trailing_metadata(grpc_call_element* elem);
938
+ static void on_complete(void* arg, grpc_error* error);
939
+ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored);
940
+ static void pick_after_resolver_result_start_locked(grpc_call_element* elem);
941
+ static void start_pick_locked(void* arg, grpc_error* ignored);
942
+
943
+ //
944
+ // send op data caching
945
+ //
946
+
947
+ // Caches data for send ops so that it can be retried later, if not
948
+ // already cached.
949
+ static void maybe_cache_send_ops_for_batch(call_data* calld,
950
+ pending_batch* pending) {
951
+ if (pending->send_ops_cached) return;
952
+ pending->send_ops_cached = true;
953
+ grpc_transport_stream_op_batch* batch = pending->batch;
954
+ // Save a copy of metadata for send_initial_metadata ops.
955
+ if (batch->send_initial_metadata) {
956
+ calld->seen_send_initial_metadata = true;
957
+ GPR_ASSERT(calld->send_initial_metadata_storage == nullptr);
958
+ grpc_metadata_batch* send_initial_metadata =
959
+ batch->payload->send_initial_metadata.send_initial_metadata;
960
+ calld->send_initial_metadata_storage = (grpc_linked_mdelem*)gpr_arena_alloc(
961
+ calld->arena,
962
+ sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count);
963
+ grpc_metadata_batch_copy(send_initial_metadata,
964
+ &calld->send_initial_metadata,
965
+ calld->send_initial_metadata_storage);
966
+ calld->send_initial_metadata_flags =
967
+ batch->payload->send_initial_metadata.send_initial_metadata_flags;
968
+ calld->peer_string = batch->payload->send_initial_metadata.peer_string;
969
+ }
970
+ // Set up cache for send_message ops.
971
+ if (batch->send_message) {
972
+ grpc_core::ByteStreamCache* cache =
973
+ static_cast<grpc_core::ByteStreamCache*>(
974
+ gpr_arena_alloc(calld->arena, sizeof(grpc_core::ByteStreamCache)));
975
+ new (cache) grpc_core::ByteStreamCache(
976
+ std::move(batch->payload->send_message.send_message));
977
+ calld->send_messages.push_back(cache);
978
+ }
979
+ // Save metadata batch for send_trailing_metadata ops.
980
+ if (batch->send_trailing_metadata) {
981
+ calld->seen_send_trailing_metadata = true;
982
+ GPR_ASSERT(calld->send_trailing_metadata_storage == nullptr);
983
+ grpc_metadata_batch* send_trailing_metadata =
984
+ batch->payload->send_trailing_metadata.send_trailing_metadata;
985
+ calld->send_trailing_metadata_storage =
986
+ (grpc_linked_mdelem*)gpr_arena_alloc(
987
+ calld->arena,
988
+ sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count);
989
+ grpc_metadata_batch_copy(send_trailing_metadata,
990
+ &calld->send_trailing_metadata,
991
+ calld->send_trailing_metadata_storage);
992
+ }
993
+ }
994
+
995
+ // Frees cached send ops that have already been completed after
996
+ // committing the call.
997
+ static void free_cached_send_op_data_after_commit(
998
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state) {
999
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1000
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1001
+ if (retry_state->completed_send_initial_metadata) {
1002
+ grpc_metadata_batch_destroy(&calld->send_initial_metadata);
1003
+ }
1004
+ for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) {
1005
+ if (grpc_client_channel_trace.enabled()) {
1006
+ gpr_log(GPR_DEBUG,
1007
+ "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR
1008
+ "]",
1009
+ chand, calld, i);
1010
+ }
1011
+ calld->send_messages[i]->Destroy();
1012
+ }
1013
+ if (retry_state->completed_send_trailing_metadata) {
1014
+ grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
1015
+ }
1016
+ }
1017
+
1018
+ // Frees cached send ops that were completed by the completed batch in
1019
+ // batch_data. Used when batches are completed after the call is committed.
1020
+ static void free_cached_send_op_data_for_completed_batch(
1021
+ grpc_call_element* elem, subchannel_batch_data* batch_data,
1022
+ subchannel_call_retry_state* retry_state) {
1023
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1024
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1025
+ if (batch_data->batch.send_initial_metadata) {
1026
+ grpc_metadata_batch_destroy(&calld->send_initial_metadata);
1027
+ }
1028
+ if (batch_data->batch.send_message) {
1029
+ if (grpc_client_channel_trace.enabled()) {
1030
+ gpr_log(GPR_DEBUG,
1031
+ "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR
1032
+ "]",
1033
+ chand, calld, retry_state->completed_send_message_count - 1);
1034
+ }
1035
+ calld->send_messages[retry_state->completed_send_message_count - 1]
1036
+ ->Destroy();
1037
+ }
1038
+ if (batch_data->batch.send_trailing_metadata) {
1039
+ grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
1040
+ }
1041
+ }
1042
+
1043
+ //
1044
+ // pending_batches management
1045
+ //
1046
+
1047
+ // Returns the index into calld->pending_batches to be used for batch.
1048
+ static size_t get_batch_index(grpc_transport_stream_op_batch* batch) {
1049
+ // Note: It is important the send_initial_metadata be the first entry
1050
+ // here, since the code in pick_subchannel_locked() assumes it will be.
1051
+ if (batch->send_initial_metadata) return 0;
1052
+ if (batch->send_message) return 1;
1053
+ if (batch->send_trailing_metadata) return 2;
1054
+ if (batch->recv_initial_metadata) return 3;
1055
+ if (batch->recv_message) return 4;
1056
+ if (batch->recv_trailing_metadata) return 5;
1057
+ GPR_UNREACHABLE_CODE(return (size_t)-1);
1058
+ }
1059
+
1060
+ // This is called via the call combiner, so access to calld is synchronized.
1061
+ static void pending_batches_add(grpc_call_element* elem,
1062
+ grpc_transport_stream_op_batch* batch) {
1063
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1064
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1065
+ const size_t idx = get_batch_index(batch);
1066
+ if (grpc_client_channel_trace.enabled()) {
1067
+ gpr_log(GPR_DEBUG,
1068
+ "chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand,
1069
+ calld, idx);
1070
+ }
1071
+ pending_batch* pending = &calld->pending_batches[idx];
1072
+ GPR_ASSERT(pending->batch == nullptr);
1073
+ pending->batch = batch;
1074
+ pending->send_ops_cached = false;
1075
+ if (calld->enable_retries) {
1076
+ // Update state in calld about pending batches.
1077
+ // Also check if the batch takes us over the retry buffer limit.
1078
+ // Note: We don't check the size of trailing metadata here, because
1079
+ // gRPC clients do not send trailing metadata.
1080
+ if (batch->send_initial_metadata) {
1081
+ calld->pending_send_initial_metadata = true;
1082
+ calld->bytes_buffered_for_retry += grpc_metadata_batch_size(
1083
+ batch->payload->send_initial_metadata.send_initial_metadata);
1084
+ }
1085
+ if (batch->send_message) {
1086
+ calld->pending_send_message = true;
1087
+ calld->bytes_buffered_for_retry +=
1088
+ batch->payload->send_message.send_message->length();
1089
+ }
1090
+ if (batch->send_trailing_metadata) {
1091
+ calld->pending_send_trailing_metadata = true;
1092
+ }
1093
+ if (calld->bytes_buffered_for_retry > chand->per_rpc_retry_buffer_size) {
1094
+ if (grpc_client_channel_trace.enabled()) {
1095
+ gpr_log(GPR_DEBUG,
1096
+ "chand=%p calld=%p: exceeded retry buffer size, committing",
1097
+ chand, calld);
1098
+ }
1099
+ subchannel_call_retry_state* retry_state =
1100
+ calld->subchannel_call == nullptr
1101
+ ? nullptr
1102
+ : static_cast<subchannel_call_retry_state*>(
1103
+ grpc_connected_subchannel_call_get_parent_data(
1104
+ calld->subchannel_call));
1105
+ retry_commit(elem, retry_state);
1106
+ // If we are not going to retry and have not yet started, pretend
1107
+ // retries are disabled so that we don't bother with retry overhead.
1108
+ if (calld->num_attempts_completed == 0) {
1109
+ if (grpc_client_channel_trace.enabled()) {
1110
+ gpr_log(GPR_DEBUG,
1111
+ "chand=%p calld=%p: disabling retries before first attempt",
1112
+ chand, calld);
1113
+ }
1114
+ calld->enable_retries = false;
1115
+ }
1116
+ }
1117
+ }
1118
+ }
1119
+
1120
+ static void pending_batch_clear(call_data* calld, pending_batch* pending) {
1121
+ if (calld->enable_retries) {
1122
+ if (pending->batch->send_initial_metadata) {
1123
+ calld->pending_send_initial_metadata = false;
1124
+ }
1125
+ if (pending->batch->send_message) {
1126
+ calld->pending_send_message = false;
1127
+ }
1128
+ if (pending->batch->send_trailing_metadata) {
1129
+ calld->pending_send_trailing_metadata = false;
1130
+ }
1131
+ }
1132
+ pending->batch = nullptr;
1133
+ }
1134
+
1135
+ // This is called via the call combiner, so access to calld is synchronized.
1136
+ static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) {
1137
+ grpc_transport_stream_op_batch* batch =
1138
+ static_cast<grpc_transport_stream_op_batch*>(arg);
1139
+ call_data* calld = static_cast<call_data*>(batch->handler_private.extra_arg);
1140
+ // Note: This will release the call combiner.
1141
+ grpc_transport_stream_op_batch_finish_with_failure(
1142
+ batch, GRPC_ERROR_REF(error), calld->call_combiner);
1143
+ }
1144
+
1145
+ // This is called via the call combiner, so access to calld is synchronized.
1146
+ // If yield_call_combiner is true, assumes responsibility for yielding
1147
+ // the call combiner.
1148
+ static void pending_batches_fail(grpc_call_element* elem, grpc_error* error,
1149
+ bool yield_call_combiner) {
1150
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
1151
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1152
+ if (grpc_client_channel_trace.enabled()) {
1153
+ size_t num_batches = 0;
1154
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1155
+ if (calld->pending_batches[i].batch != nullptr) ++num_batches;
1156
+ }
1157
+ gpr_log(GPR_DEBUG,
1158
+ "chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
1159
+ elem->channel_data, calld, num_batches, grpc_error_string(error));
1160
+ }
1161
+ grpc_transport_stream_op_batch*
1162
+ batches[GPR_ARRAY_SIZE(calld->pending_batches)];
1163
+ size_t num_batches = 0;
1164
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1165
+ pending_batch* pending = &calld->pending_batches[i];
1166
+ grpc_transport_stream_op_batch* batch = pending->batch;
1167
+ if (batch != nullptr) {
1168
+ batches[num_batches++] = batch;
1169
+ pending_batch_clear(calld, pending);
1170
+ }
1171
+ }
1172
+ for (size_t i = yield_call_combiner ? 1 : 0; i < num_batches; ++i) {
1173
+ grpc_transport_stream_op_batch* batch = batches[i];
1174
+ batch->handler_private.extra_arg = calld;
1175
+ GRPC_CLOSURE_INIT(&batch->handler_private.closure,
1176
+ fail_pending_batch_in_call_combiner, batch,
1177
+ grpc_schedule_on_exec_ctx);
1178
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
1179
+ &batch->handler_private.closure,
1180
+ GRPC_ERROR_REF(error), "pending_batches_fail");
1181
+ }
1182
+ if (yield_call_combiner) {
1183
+ if (num_batches > 0) {
1184
+ // Note: This will release the call combiner.
1185
+ grpc_transport_stream_op_batch_finish_with_failure(
1186
+ batches[0], GRPC_ERROR_REF(error), calld->call_combiner);
1187
+ } else {
1188
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner, "pending_batches_fail");
1189
+ }
1190
+ }
1191
+ GRPC_ERROR_UNREF(error);
1192
+ }
1193
+
1194
+ // This is called via the call combiner, so access to calld is synchronized.
1195
+ static void resume_pending_batch_in_call_combiner(void* arg,
1196
+ grpc_error* ignored) {
1197
+ grpc_transport_stream_op_batch* batch =
1198
+ static_cast<grpc_transport_stream_op_batch*>(arg);
1199
+ grpc_subchannel_call* subchannel_call =
1200
+ static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg);
1201
+ // Note: This will release the call combiner.
1202
+ grpc_subchannel_call_process_op(subchannel_call, batch);
1203
+ }
1204
+
1205
+ // This is called via the call combiner, so access to calld is synchronized.
1206
+ static void pending_batches_resume(grpc_call_element* elem) {
1207
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1208
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1209
+ if (calld->enable_retries) {
1210
+ start_retriable_subchannel_batches(elem, GRPC_ERROR_NONE);
1211
+ return;
1212
+ }
1213
+ // Retries not enabled; send down batches as-is.
1214
+ if (grpc_client_channel_trace.enabled()) {
1215
+ size_t num_batches = 0;
1216
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1217
+ if (calld->pending_batches[i].batch != nullptr) ++num_batches;
1218
+ }
1219
+ gpr_log(GPR_DEBUG,
1220
+ "chand=%p calld=%p: starting %" PRIuPTR
1221
+ " pending batches on subchannel_call=%p",
1222
+ chand, calld, num_batches, calld->subchannel_call);
1223
+ }
1224
+ grpc_transport_stream_op_batch*
1225
+ batches[GPR_ARRAY_SIZE(calld->pending_batches)];
1226
+ size_t num_batches = 0;
1227
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1228
+ pending_batch* pending = &calld->pending_batches[i];
1229
+ grpc_transport_stream_op_batch* batch = pending->batch;
1230
+ if (batch != nullptr) {
1231
+ batches[num_batches++] = batch;
1232
+ pending_batch_clear(calld, pending);
1233
+ }
1234
+ }
1235
+ for (size_t i = 1; i < num_batches; ++i) {
1236
+ grpc_transport_stream_op_batch* batch = batches[i];
1237
+ batch->handler_private.extra_arg = calld->subchannel_call;
1238
+ GRPC_CLOSURE_INIT(&batch->handler_private.closure,
1239
+ resume_pending_batch_in_call_combiner, batch,
1240
+ grpc_schedule_on_exec_ctx);
1241
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
1242
+ &batch->handler_private.closure, GRPC_ERROR_NONE,
1243
+ "pending_batches_resume");
1244
+ }
1245
+ GPR_ASSERT(num_batches > 0);
1246
+ // Note: This will release the call combiner.
1247
+ grpc_subchannel_call_process_op(calld->subchannel_call, batches[0]);
1248
+ }
1249
+
1250
+ static void maybe_clear_pending_batch(grpc_call_element* elem,
1251
+ pending_batch* pending) {
1252
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1253
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1254
+ grpc_transport_stream_op_batch* batch = pending->batch;
1255
+ // We clear the pending batch if all of its callbacks have been
1256
+ // scheduled and reset to nullptr.
1257
+ if (batch->on_complete == nullptr &&
1258
+ (!batch->recv_initial_metadata ||
1259
+ batch->payload->recv_initial_metadata.recv_initial_metadata_ready ==
1260
+ nullptr) &&
1261
+ (!batch->recv_message ||
1262
+ batch->payload->recv_message.recv_message_ready == nullptr)) {
1263
+ if (grpc_client_channel_trace.enabled()) {
1264
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: clearing pending batch", chand,
1265
+ calld);
1266
+ }
1267
+ pending_batch_clear(calld, pending);
1268
+ }
1269
+ }
1270
+
1271
+ // Returns true if all ops in the pending batch have been completed.
1272
+ static bool pending_batch_is_completed(
1273
+ pending_batch* pending, call_data* calld,
1274
+ subchannel_call_retry_state* retry_state) {
1275
+ if (pending->batch == nullptr || pending->batch->on_complete == nullptr) {
1276
+ return false;
1277
+ }
1278
+ if (pending->batch->send_initial_metadata &&
1279
+ !retry_state->completed_send_initial_metadata) {
1280
+ return false;
1281
+ }
1282
+ if (pending->batch->send_message &&
1283
+ retry_state->completed_send_message_count < calld->send_messages.size()) {
1284
+ return false;
1285
+ }
1286
+ if (pending->batch->send_trailing_metadata &&
1287
+ !retry_state->completed_send_trailing_metadata) {
1288
+ return false;
1289
+ }
1290
+ if (pending->batch->recv_initial_metadata &&
1291
+ !retry_state->completed_recv_initial_metadata) {
1292
+ return false;
1293
+ }
1294
+ if (pending->batch->recv_message &&
1295
+ retry_state->completed_recv_message_count <
1296
+ retry_state->started_recv_message_count) {
1297
+ return false;
1298
+ }
1299
+ if (pending->batch->recv_trailing_metadata &&
1300
+ !retry_state->completed_recv_trailing_metadata) {
1301
+ return false;
1302
+ }
1303
+ return true;
1304
+ }
1305
+
1306
+ // Returns true if any op in the batch was not yet started.
1307
+ static bool pending_batch_is_unstarted(
1308
+ pending_batch* pending, call_data* calld,
1309
+ subchannel_call_retry_state* retry_state) {
1310
+ if (pending->batch == nullptr || pending->batch->on_complete == nullptr) {
1311
+ return false;
1312
+ }
1313
+ if (pending->batch->send_initial_metadata &&
1314
+ !retry_state->started_send_initial_metadata) {
1315
+ return true;
1316
+ }
1317
+ if (pending->batch->send_message &&
1318
+ retry_state->started_send_message_count < calld->send_messages.size()) {
1319
+ return true;
1320
+ }
1321
+ if (pending->batch->send_trailing_metadata &&
1322
+ !retry_state->started_send_trailing_metadata) {
1323
+ return true;
1324
+ }
1325
+ if (pending->batch->recv_initial_metadata &&
1326
+ !retry_state->started_recv_initial_metadata) {
1327
+ return true;
1328
+ }
1329
+ if (pending->batch->recv_message &&
1330
+ retry_state->completed_recv_message_count ==
1331
+ retry_state->started_recv_message_count) {
1332
+ return true;
1333
+ }
1334
+ if (pending->batch->recv_trailing_metadata &&
1335
+ !retry_state->started_recv_trailing_metadata) {
1336
+ return true;
1337
+ }
1338
+ return false;
1339
+ }
1340
+
1341
+ //
1342
+ // retry code
1343
+ //
1344
+
1345
+ // Commits the call so that no further retry attempts will be performed.
1346
+ static void retry_commit(grpc_call_element* elem,
1347
+ subchannel_call_retry_state* retry_state) {
1348
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1349
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1350
+ if (calld->retry_committed) return;
1351
+ calld->retry_committed = true;
1352
+ if (grpc_client_channel_trace.enabled()) {
1353
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: committing retries", chand, calld);
1354
+ }
1355
+ if (retry_state != nullptr) {
1356
+ free_cached_send_op_data_after_commit(elem, retry_state);
1357
+ }
1358
+ }
1359
+
1360
+ // Starts a retry after appropriate back-off.
1361
+ static void do_retry(grpc_call_element* elem,
1362
+ subchannel_call_retry_state* retry_state,
1363
+ grpc_millis server_pushback_ms) {
1364
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1365
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1366
+ GPR_ASSERT(calld->method_params != nullptr);
1367
+ const ClientChannelMethodParams::RetryPolicy* retry_policy =
1368
+ calld->method_params->retry_policy();
1369
+ GPR_ASSERT(retry_policy != nullptr);
1370
+ // Reset subchannel call and connected subchannel.
1371
+ if (calld->subchannel_call != nullptr) {
1372
+ GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call,
1373
+ "client_channel_call_retry");
1374
+ calld->subchannel_call = nullptr;
1375
+ }
1376
+ if (calld->pick.connected_subchannel != nullptr) {
1377
+ calld->pick.connected_subchannel.reset();
1378
+ }
1379
+ // Compute backoff delay.
1380
+ grpc_millis next_attempt_time;
1381
+ if (server_pushback_ms >= 0) {
1382
+ next_attempt_time = grpc_core::ExecCtx::Get()->Now() + server_pushback_ms;
1383
+ calld->last_attempt_got_server_pushback = true;
1384
+ } else {
1385
+ if (calld->num_attempts_completed == 1 ||
1386
+ calld->last_attempt_got_server_pushback) {
1387
+ calld->retry_backoff.Init(
1388
+ grpc_core::BackOff::Options()
1389
+ .set_initial_backoff(retry_policy->initial_backoff)
1390
+ .set_multiplier(retry_policy->backoff_multiplier)
1391
+ .set_jitter(RETRY_BACKOFF_JITTER)
1392
+ .set_max_backoff(retry_policy->max_backoff));
1393
+ calld->last_attempt_got_server_pushback = false;
1394
+ }
1395
+ next_attempt_time = calld->retry_backoff->NextAttemptTime();
1396
+ }
1397
+ if (grpc_client_channel_trace.enabled()) {
1398
+ gpr_log(GPR_DEBUG,
1399
+ "chand=%p calld=%p: retrying failed call in %" PRIuPTR " ms", chand,
1400
+ calld, next_attempt_time - grpc_core::ExecCtx::Get()->Now());
1401
+ }
1402
+ // Schedule retry after computed delay.
1403
+ GRPC_CLOSURE_INIT(&calld->pick_closure, start_pick_locked, elem,
1404
+ grpc_combiner_scheduler(chand->combiner));
1405
+ grpc_timer_init(&calld->retry_timer, next_attempt_time, &calld->pick_closure);
1406
+ // Update bookkeeping.
1407
+ if (retry_state != nullptr) retry_state->retry_dispatched = true;
1408
+ }
1409
+
1410
+ // Returns true if the call is being retried.
1411
+ static bool maybe_retry(grpc_call_element* elem,
1412
+ subchannel_batch_data* batch_data,
1413
+ grpc_status_code status,
1414
+ grpc_mdelem* server_pushback_md) {
1415
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1416
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1417
+ // Get retry policy.
1418
+ if (calld->method_params == nullptr) return false;
1419
+ const ClientChannelMethodParams::RetryPolicy* retry_policy =
1420
+ calld->method_params->retry_policy();
1421
+ if (retry_policy == nullptr) return false;
1422
+ // If we've already dispatched a retry from this call, return true.
1423
+ // This catches the case where the batch has multiple callbacks
1424
+ // (i.e., it includes either recv_message or recv_initial_metadata).
1425
+ subchannel_call_retry_state* retry_state = nullptr;
1426
+ if (batch_data != nullptr) {
1427
+ retry_state = static_cast<subchannel_call_retry_state*>(
1428
+ grpc_connected_subchannel_call_get_parent_data(
1429
+ batch_data->subchannel_call));
1430
+ if (retry_state->retry_dispatched) {
1431
+ if (grpc_client_channel_trace.enabled()) {
1432
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: retry already dispatched", chand,
1433
+ calld);
1434
+ }
1435
+ return true;
1436
+ }
1437
+ }
1438
+ // Check status.
1439
+ if (status == GRPC_STATUS_OK) {
1440
+ if (calld->retry_throttle_data != nullptr) {
1441
+ calld->retry_throttle_data->RecordSuccess();
1442
+ }
1443
+ if (grpc_client_channel_trace.enabled()) {
1444
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: call succeeded", chand, calld);
1445
+ }
1446
+ return false;
1447
+ }
1448
+ // Status is not OK. Check whether the status is retryable.
1449
+ if (!retry_policy->retryable_status_codes.Contains(status)) {
1450
+ if (grpc_client_channel_trace.enabled()) {
1451
+ gpr_log(GPR_DEBUG,
1452
+ "chand=%p calld=%p: status %s not configured as retryable", chand,
1453
+ calld, grpc_status_code_to_string(status));
1454
+ }
1455
+ return false;
1456
+ }
1457
+ // Record the failure and check whether retries are throttled.
1458
+ // Note that it's important for this check to come after the status
1459
+ // code check above, since we should only record failures whose statuses
1460
+ // match the configured retryable status codes, so that we don't count
1461
+ // things like failures due to malformed requests (INVALID_ARGUMENT).
1462
+ // Conversely, it's important for this to come before the remaining
1463
+ // checks, so that we don't fail to record failures due to other factors.
1464
+ if (calld->retry_throttle_data != nullptr &&
1465
+ !calld->retry_throttle_data->RecordFailure()) {
1466
+ if (grpc_client_channel_trace.enabled()) {
1467
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: retries throttled", chand, calld);
1468
+ }
1469
+ return false;
1470
+ }
1471
+ // Check whether the call is committed.
1472
+ if (calld->retry_committed) {
1473
+ if (grpc_client_channel_trace.enabled()) {
1474
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: retries already committed", chand,
1475
+ calld);
1476
+ }
1477
+ return false;
1478
+ }
1479
+ // Check whether we have retries remaining.
1480
+ ++calld->num_attempts_completed;
1481
+ if (calld->num_attempts_completed >= retry_policy->max_attempts) {
1482
+ if (grpc_client_channel_trace.enabled()) {
1483
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: exceeded %d retry attempts", chand,
1484
+ calld, retry_policy->max_attempts);
1485
+ }
1486
+ return false;
1487
+ }
1488
+ // If the call was cancelled from the surface, don't retry.
1489
+ if (calld->cancel_error != GRPC_ERROR_NONE) {
1490
+ if (grpc_client_channel_trace.enabled()) {
1491
+ gpr_log(GPR_DEBUG,
1492
+ "chand=%p calld=%p: call cancelled from surface, not retrying",
1493
+ chand, calld);
1494
+ }
1495
+ return false;
1496
+ }
1497
+ // Check server push-back.
1498
+ grpc_millis server_pushback_ms = -1;
1499
+ if (server_pushback_md != nullptr) {
1500
+ // If the value is "-1" or any other unparseable string, we do not retry.
1501
+ uint32_t ms;
1502
+ if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(*server_pushback_md), &ms)) {
1503
+ if (grpc_client_channel_trace.enabled()) {
1504
+ gpr_log(GPR_DEBUG,
1505
+ "chand=%p calld=%p: not retrying due to server push-back",
1506
+ chand, calld);
1507
+ }
1508
+ return false;
1509
+ } else {
1510
+ if (grpc_client_channel_trace.enabled()) {
1511
+ gpr_log(GPR_DEBUG,
1512
+ "chand=%p calld=%p: server push-back: retry in %u ms", chand,
1513
+ calld, ms);
1514
+ }
1515
+ server_pushback_ms = (grpc_millis)ms;
1516
+ }
1517
+ }
1518
+ do_retry(elem, retry_state, server_pushback_ms);
1519
+ return true;
1520
+ }
1521
+
1522
+ //
1523
+ // subchannel_batch_data
1524
+ //
1525
+
1526
+ static subchannel_batch_data* batch_data_create(grpc_call_element* elem,
1527
+ int refcount) {
1528
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1529
+ subchannel_call_retry_state* retry_state =
1530
+ static_cast<subchannel_call_retry_state*>(
1531
+ grpc_connected_subchannel_call_get_parent_data(
1532
+ calld->subchannel_call));
1533
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(
1534
+ gpr_arena_alloc(calld->arena, sizeof(*batch_data)));
1535
+ batch_data->elem = elem;
1536
+ batch_data->subchannel_call =
1537
+ GRPC_SUBCHANNEL_CALL_REF(calld->subchannel_call, "batch_data_create");
1538
+ batch_data->batch.payload = &retry_state->batch_payload;
1539
+ gpr_ref_init(&batch_data->refs, refcount);
1540
+ GRPC_CLOSURE_INIT(&batch_data->on_complete, on_complete, batch_data,
1541
+ grpc_schedule_on_exec_ctx);
1542
+ batch_data->batch.on_complete = &batch_data->on_complete;
1543
+ GRPC_CALL_STACK_REF(calld->owning_call, "batch_data");
1544
+ return batch_data;
1545
+ }
1546
+
1547
+ static void batch_data_unref(subchannel_batch_data* batch_data) {
1548
+ if (gpr_unref(&batch_data->refs)) {
1549
+ if (batch_data->send_initial_metadata_storage != nullptr) {
1550
+ grpc_metadata_batch_destroy(&batch_data->send_initial_metadata);
1551
+ }
1552
+ if (batch_data->send_trailing_metadata_storage != nullptr) {
1553
+ grpc_metadata_batch_destroy(&batch_data->send_trailing_metadata);
1554
+ }
1555
+ if (batch_data->batch.recv_initial_metadata) {
1556
+ grpc_metadata_batch_destroy(&batch_data->recv_initial_metadata);
1557
+ }
1558
+ if (batch_data->batch.recv_trailing_metadata) {
1559
+ grpc_metadata_batch_destroy(&batch_data->recv_trailing_metadata);
1560
+ }
1561
+ GRPC_SUBCHANNEL_CALL_UNREF(batch_data->subchannel_call, "batch_data_unref");
1562
+ call_data* calld = static_cast<call_data*>(batch_data->elem->call_data);
1563
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data");
1564
+ }
1565
+ }
1566
+
1567
+ //
1568
+ // recv_initial_metadata callback handling
1569
+ //
1570
+
1571
+ // Invokes recv_initial_metadata_ready for a subchannel batch.
1572
+ static void invoke_recv_initial_metadata_callback(void* arg,
1573
+ grpc_error* error) {
1574
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
1575
+ channel_data* chand =
1576
+ static_cast<channel_data*>(batch_data->elem->channel_data);
1577
+ call_data* calld = static_cast<call_data*>(batch_data->elem->call_data);
1578
+ // Find pending batch.
1579
+ pending_batch* pending = nullptr;
1580
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1581
+ grpc_transport_stream_op_batch* batch = calld->pending_batches[i].batch;
1582
+ if (batch != nullptr && batch->recv_initial_metadata &&
1583
+ batch->payload->recv_initial_metadata.recv_initial_metadata_ready !=
1584
+ nullptr) {
1585
+ if (grpc_client_channel_trace.enabled()) {
1586
+ gpr_log(GPR_DEBUG,
1587
+ "chand=%p calld=%p: invoking recv_initial_metadata_ready for "
1588
+ "pending batch at index %" PRIuPTR,
1589
+ chand, calld, i);
1590
+ }
1591
+ pending = &calld->pending_batches[i];
1592
+ break;
1593
+ }
1594
+ }
1595
+ GPR_ASSERT(pending != nullptr);
1596
+ // Return metadata.
1597
+ grpc_metadata_batch_move(
1598
+ &batch_data->recv_initial_metadata,
1599
+ pending->batch->payload->recv_initial_metadata.recv_initial_metadata);
1600
+ // Update bookkeeping.
1601
+ // Note: Need to do this before invoking the callback, since invoking
1602
+ // the callback will result in yielding the call combiner.
1603
+ grpc_closure* recv_initial_metadata_ready =
1604
+ pending->batch->payload->recv_initial_metadata
1605
+ .recv_initial_metadata_ready;
1606
+ pending->batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
1607
+ nullptr;
1608
+ maybe_clear_pending_batch(batch_data->elem, pending);
1609
+ batch_data_unref(batch_data);
1610
+ // Invoke callback.
1611
+ GRPC_CLOSURE_RUN(recv_initial_metadata_ready, GRPC_ERROR_REF(error));
1612
+ }
1613
+
1614
+ // Intercepts recv_initial_metadata_ready callback for retries.
1615
+ // Commits the call and returns the initial metadata up the stack.
1616
+ static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
1617
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
1618
+ grpc_call_element* elem = batch_data->elem;
1619
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1620
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1621
+ if (grpc_client_channel_trace.enabled()) {
1622
+ gpr_log(GPR_DEBUG,
1623
+ "chand=%p calld=%p: got recv_initial_metadata_ready, error=%s",
1624
+ chand, calld, grpc_error_string(error));
1625
+ }
1626
+ subchannel_call_retry_state* retry_state =
1627
+ static_cast<subchannel_call_retry_state*>(
1628
+ grpc_connected_subchannel_call_get_parent_data(
1629
+ batch_data->subchannel_call));
1630
+ // If we got an error or a Trailers-Only response and have not yet gotten
1631
+ // the recv_trailing_metadata on_complete callback, then defer
1632
+ // propagating this callback back to the surface. We can evaluate whether
1633
+ // to retry when recv_trailing_metadata comes back.
1634
+ if ((batch_data->trailing_metadata_available || error != GRPC_ERROR_NONE) &&
1635
+ !retry_state->completed_recv_trailing_metadata) {
1636
+ if (grpc_client_channel_trace.enabled()) {
1637
+ gpr_log(GPR_DEBUG,
1638
+ "chand=%p calld=%p: deferring recv_initial_metadata_ready "
1639
+ "(Trailers-Only)",
1640
+ chand, calld);
1641
+ }
1642
+ retry_state->recv_initial_metadata_ready_deferred = true;
1643
+ retry_state->recv_initial_metadata_error = GRPC_ERROR_REF(error);
1644
+ if (!retry_state->started_recv_trailing_metadata) {
1645
+ // recv_trailing_metadata not yet started by application; start it
1646
+ // ourselves to get status.
1647
+ start_internal_recv_trailing_metadata(elem);
1648
+ } else {
1649
+ GRPC_CALL_COMBINER_STOP(
1650
+ calld->call_combiner,
1651
+ "recv_initial_metadata_ready trailers-only or error");
1652
+ }
1653
+ return;
1654
+ }
1655
+ // Received valid initial metadata, so commit the call.
1656
+ retry_commit(elem, retry_state);
1657
+ // Manually invoking a callback function; it does not take ownership of error.
1658
+ invoke_recv_initial_metadata_callback(batch_data, error);
1659
+ GRPC_ERROR_UNREF(error);
1660
+ }
1661
+
1662
+ //
1663
+ // recv_message callback handling
1664
+ //
1665
+
1666
+ // Invokes recv_message_ready for a subchannel batch.
1667
+ static void invoke_recv_message_callback(void* arg, grpc_error* error) {
1668
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
1669
+ channel_data* chand =
1670
+ static_cast<channel_data*>(batch_data->elem->channel_data);
1671
+ call_data* calld = static_cast<call_data*>(batch_data->elem->call_data);
1672
+ // Find pending op.
1673
+ pending_batch* pending = nullptr;
1674
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1675
+ grpc_transport_stream_op_batch* batch = calld->pending_batches[i].batch;
1676
+ if (batch != nullptr && batch->recv_message &&
1677
+ batch->payload->recv_message.recv_message_ready != nullptr) {
1678
+ if (grpc_client_channel_trace.enabled()) {
1679
+ gpr_log(GPR_DEBUG,
1680
+ "chand=%p calld=%p: invoking recv_message_ready for "
1681
+ "pending batch at index %" PRIuPTR,
1682
+ chand, calld, i);
1683
+ }
1684
+ pending = &calld->pending_batches[i];
1685
+ break;
1686
+ }
1687
+ }
1688
+ GPR_ASSERT(pending != nullptr);
1689
+ // Return payload.
1690
+ *pending->batch->payload->recv_message.recv_message =
1691
+ std::move(batch_data->recv_message);
1692
+ // Update bookkeeping.
1693
+ // Note: Need to do this before invoking the callback, since invoking
1694
+ // the callback will result in yielding the call combiner.
1695
+ grpc_closure* recv_message_ready =
1696
+ pending->batch->payload->recv_message.recv_message_ready;
1697
+ pending->batch->payload->recv_message.recv_message_ready = nullptr;
1698
+ maybe_clear_pending_batch(batch_data->elem, pending);
1699
+ batch_data_unref(batch_data);
1700
+ // Invoke callback.
1701
+ GRPC_CLOSURE_RUN(recv_message_ready, GRPC_ERROR_REF(error));
1702
+ }
1703
+
1704
+ // Intercepts recv_message_ready callback for retries.
1705
+ // Commits the call and returns the message up the stack.
1706
+ static void recv_message_ready(void* arg, grpc_error* error) {
1707
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
1708
+ grpc_call_element* elem = batch_data->elem;
1709
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1710
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1711
+ if (grpc_client_channel_trace.enabled()) {
1712
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: got recv_message_ready, error=%s",
1713
+ chand, calld, grpc_error_string(error));
1714
+ }
1715
+ subchannel_call_retry_state* retry_state =
1716
+ static_cast<subchannel_call_retry_state*>(
1717
+ grpc_connected_subchannel_call_get_parent_data(
1718
+ batch_data->subchannel_call));
1719
+ // If we got an error or the payload was nullptr and we have not yet gotten
1720
+ // the recv_trailing_metadata on_complete callback, then defer
1721
+ // propagating this callback back to the surface. We can evaluate whether
1722
+ // to retry when recv_trailing_metadata comes back.
1723
+ if ((batch_data->recv_message == nullptr || error != GRPC_ERROR_NONE) &&
1724
+ !retry_state->completed_recv_trailing_metadata) {
1725
+ if (grpc_client_channel_trace.enabled()) {
1726
+ gpr_log(GPR_DEBUG,
1727
+ "chand=%p calld=%p: deferring recv_message_ready (nullptr "
1728
+ "message and recv_trailing_metadata pending)",
1729
+ chand, calld);
1730
+ }
1731
+ retry_state->recv_message_ready_deferred = true;
1732
+ retry_state->recv_message_error = GRPC_ERROR_REF(error);
1733
+ if (!retry_state->started_recv_trailing_metadata) {
1734
+ // recv_trailing_metadata not yet started by application; start it
1735
+ // ourselves to get status.
1736
+ start_internal_recv_trailing_metadata(elem);
1737
+ } else {
1738
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner, "recv_message_ready null");
1739
+ }
1740
+ return;
1741
+ }
1742
+ // Received a valid message, so commit the call.
1743
+ retry_commit(elem, retry_state);
1744
+ // Manually invoking a callback function; it does not take ownership of error.
1745
+ invoke_recv_message_callback(batch_data, error);
1746
+ GRPC_ERROR_UNREF(error);
1747
+ }
1748
+
1749
+ //
1750
+ // on_complete callback handling
1751
+ //
1752
+
1753
+ // Updates retry_state to reflect the ops completed in batch_data.
1754
+ static void update_retry_state_for_completed_batch(
1755
+ subchannel_batch_data* batch_data,
1756
+ subchannel_call_retry_state* retry_state) {
1757
+ if (batch_data->batch.send_initial_metadata) {
1758
+ retry_state->completed_send_initial_metadata = true;
1759
+ }
1760
+ if (batch_data->batch.send_message) {
1761
+ ++retry_state->completed_send_message_count;
1762
+ }
1763
+ if (batch_data->batch.send_trailing_metadata) {
1764
+ retry_state->completed_send_trailing_metadata = true;
1765
+ }
1766
+ if (batch_data->batch.recv_initial_metadata) {
1767
+ retry_state->completed_recv_initial_metadata = true;
1768
+ }
1769
+ if (batch_data->batch.recv_message) {
1770
+ ++retry_state->completed_recv_message_count;
1771
+ }
1772
+ if (batch_data->batch.recv_trailing_metadata) {
1773
+ retry_state->completed_recv_trailing_metadata = true;
1774
+ }
1775
+ }
1776
+
1777
+ // Represents a closure that needs to run as a result of a completed batch.
1778
+ typedef struct {
1779
+ grpc_closure* closure;
1780
+ grpc_error* error;
1781
+ const char* reason;
1782
+ } closure_to_execute;
1783
+
1784
+ // Adds any necessary closures for deferred recv_initial_metadata and
1785
+ // recv_message callbacks to closures, updating *num_closures as needed.
1786
+ static void add_closures_for_deferred_recv_callbacks(
1787
+ subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state,
1788
+ closure_to_execute* closures, size_t* num_closures) {
1789
+ if (batch_data->batch.recv_trailing_metadata &&
1790
+ retry_state->recv_initial_metadata_ready_deferred) {
1791
+ closure_to_execute* closure = &closures[(*num_closures)++];
1792
+ closure->closure =
1793
+ GRPC_CLOSURE_INIT(&batch_data->recv_initial_metadata_ready,
1794
+ invoke_recv_initial_metadata_callback, batch_data,
1795
+ grpc_schedule_on_exec_ctx);
1796
+ closure->error = retry_state->recv_initial_metadata_error;
1797
+ closure->reason = "resuming recv_initial_metadata_ready";
1798
+ }
1799
+ if (batch_data->batch.recv_trailing_metadata &&
1800
+ retry_state->recv_message_ready_deferred) {
1801
+ closure_to_execute* closure = &closures[(*num_closures)++];
1802
+ closure->closure = GRPC_CLOSURE_INIT(&batch_data->recv_message_ready,
1803
+ invoke_recv_message_callback,
1804
+ batch_data, grpc_schedule_on_exec_ctx);
1805
+ closure->error = retry_state->recv_message_error;
1806
+ closure->reason = "resuming recv_message_ready";
1807
+ }
1808
+ }
1809
+
1810
+ // If there are any cached ops to replay or pending ops to start on the
1811
+ // subchannel call, adds a closure to closures to invoke
1812
+ // start_retriable_subchannel_batches(), updating *num_closures as needed.
1813
+ static void add_closures_for_replay_or_pending_send_ops(
1814
+ grpc_call_element* elem, subchannel_batch_data* batch_data,
1815
+ subchannel_call_retry_state* retry_state, closure_to_execute* closures,
1816
+ size_t* num_closures) {
1817
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1818
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1819
+ bool have_pending_send_message_ops =
1820
+ retry_state->started_send_message_count < calld->send_messages.size();
1821
+ bool have_pending_send_trailing_metadata_op =
1822
+ calld->seen_send_trailing_metadata &&
1823
+ !retry_state->started_send_trailing_metadata;
1824
+ if (!have_pending_send_message_ops &&
1825
+ !have_pending_send_trailing_metadata_op) {
1826
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1827
+ pending_batch* pending = &calld->pending_batches[i];
1828
+ grpc_transport_stream_op_batch* batch = pending->batch;
1829
+ if (batch == nullptr || pending->send_ops_cached) continue;
1830
+ if (batch->send_message) have_pending_send_message_ops = true;
1831
+ if (batch->send_trailing_metadata) {
1832
+ have_pending_send_trailing_metadata_op = true;
1833
+ }
1834
+ }
1835
+ }
1836
+ if (have_pending_send_message_ops || have_pending_send_trailing_metadata_op) {
1837
+ if (grpc_client_channel_trace.enabled()) {
1838
+ gpr_log(GPR_DEBUG,
1839
+ "chand=%p calld=%p: starting next batch for pending send op(s)",
1840
+ chand, calld);
1841
+ }
1842
+ closure_to_execute* closure = &closures[(*num_closures)++];
1843
+ closure->closure = GRPC_CLOSURE_INIT(
1844
+ &batch_data->batch.handler_private.closure,
1845
+ start_retriable_subchannel_batches, elem, grpc_schedule_on_exec_ctx);
1846
+ closure->error = GRPC_ERROR_NONE;
1847
+ closure->reason = "starting next batch for send_* op(s)";
1848
+ }
1849
+ }
1850
+
1851
+ // For any pending batch completed in batch_data, adds the necessary
1852
+ // completion closures to closures, updating *num_closures as needed.
1853
+ static void add_closures_for_completed_pending_batches(
1854
+ grpc_call_element* elem, subchannel_batch_data* batch_data,
1855
+ subchannel_call_retry_state* retry_state, grpc_error* error,
1856
+ closure_to_execute* closures, size_t* num_closures) {
1857
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1858
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1859
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1860
+ pending_batch* pending = &calld->pending_batches[i];
1861
+ if (pending_batch_is_completed(pending, calld, retry_state)) {
1862
+ if (grpc_client_channel_trace.enabled()) {
1863
+ gpr_log(GPR_DEBUG,
1864
+ "chand=%p calld=%p: pending batch completed at index %" PRIuPTR,
1865
+ chand, calld, i);
1866
+ }
1867
+ // Copy the trailing metadata to return it to the surface.
1868
+ if (batch_data->batch.recv_trailing_metadata) {
1869
+ grpc_metadata_batch_move(&batch_data->recv_trailing_metadata,
1870
+ pending->batch->payload->recv_trailing_metadata
1871
+ .recv_trailing_metadata);
1872
+ }
1873
+ closure_to_execute* closure = &closures[(*num_closures)++];
1874
+ closure->closure = pending->batch->on_complete;
1875
+ closure->error = GRPC_ERROR_REF(error);
1876
+ closure->reason = "on_complete for pending batch";
1877
+ pending->batch->on_complete = nullptr;
1878
+ maybe_clear_pending_batch(elem, pending);
1879
+ }
1880
+ }
1881
+ GRPC_ERROR_UNREF(error);
1882
+ }
1883
+
1884
+ // For any pending batch containing an op that has not yet been started,
1885
+ // adds the pending batch's completion closures to closures, updating
1886
+ // *num_closures as needed.
1887
+ static void add_closures_to_fail_unstarted_pending_batches(
1888
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state,
1889
+ grpc_error* error, closure_to_execute* closures, size_t* num_closures) {
1890
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1891
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1892
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
1893
+ pending_batch* pending = &calld->pending_batches[i];
1894
+ if (pending_batch_is_unstarted(pending, calld, retry_state)) {
1895
+ if (grpc_client_channel_trace.enabled()) {
1896
+ gpr_log(GPR_DEBUG,
1897
+ "chand=%p calld=%p: failing unstarted pending batch at index "
1898
+ "%" PRIuPTR,
1899
+ chand, calld, i);
1900
+ }
1901
+ if (pending->batch->recv_initial_metadata) {
1902
+ closure_to_execute* closure = &closures[(*num_closures)++];
1903
+ closure->closure = pending->batch->payload->recv_initial_metadata
1904
+ .recv_initial_metadata_ready;
1905
+ closure->error = GRPC_ERROR_REF(error);
1906
+ closure->reason =
1907
+ "failing recv_initial_metadata_ready for pending batch";
1908
+ pending->batch->payload->recv_initial_metadata
1909
+ .recv_initial_metadata_ready = nullptr;
1910
+ }
1911
+ if (pending->batch->recv_message) {
1912
+ *pending->batch->payload->recv_message.recv_message = nullptr;
1913
+ closure_to_execute* closure = &closures[(*num_closures)++];
1914
+ closure->closure =
1915
+ pending->batch->payload->recv_message.recv_message_ready;
1916
+ closure->error = GRPC_ERROR_REF(error);
1917
+ closure->reason = "failing recv_message_ready for pending batch";
1918
+ pending->batch->payload->recv_message.recv_message_ready = nullptr;
1919
+ }
1920
+ closure_to_execute* closure = &closures[(*num_closures)++];
1921
+ closure->closure = pending->batch->on_complete;
1922
+ closure->error = GRPC_ERROR_REF(error);
1923
+ closure->reason = "failing on_complete for pending batch";
1924
+ pending->batch->on_complete = nullptr;
1925
+ maybe_clear_pending_batch(elem, pending);
1926
+ }
1927
+ }
1928
+ GRPC_ERROR_UNREF(error);
1929
+ }
1930
+
1931
+ // Callback used to intercept on_complete from subchannel calls.
1932
+ // Called only when retries are enabled.
1933
+ static void on_complete(void* arg, grpc_error* error) {
1934
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
1935
+ grpc_call_element* elem = batch_data->elem;
1936
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
1937
+ call_data* calld = static_cast<call_data*>(elem->call_data);
1938
+ if (grpc_client_channel_trace.enabled()) {
1939
+ char* batch_str = grpc_transport_stream_op_batch_string(&batch_data->batch);
1940
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: got on_complete, error=%s, batch=%s",
1941
+ chand, calld, grpc_error_string(error), batch_str);
1942
+ gpr_free(batch_str);
1943
+ }
1944
+ subchannel_call_retry_state* retry_state =
1945
+ static_cast<subchannel_call_retry_state*>(
1946
+ grpc_connected_subchannel_call_get_parent_data(
1947
+ batch_data->subchannel_call));
1948
+ // If we have previously completed recv_trailing_metadata, then the
1949
+ // call is finished.
1950
+ bool call_finished = retry_state->completed_recv_trailing_metadata;
1951
+ // Update bookkeeping in retry_state.
1952
+ update_retry_state_for_completed_batch(batch_data, retry_state);
1953
+ if (call_finished) {
1954
+ if (grpc_client_channel_trace.enabled()) {
1955
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: call already finished", chand,
1956
+ calld);
1957
+ }
1958
+ } else {
1959
+ // Check if this batch finished the call, and if so, get its status.
1960
+ // The call is finished if either (a) this callback was invoked with
1961
+ // an error or (b) we receive status.
1962
+ grpc_status_code status = GRPC_STATUS_OK;
1963
+ grpc_mdelem* server_pushback_md = nullptr;
1964
+ if (error != GRPC_ERROR_NONE) { // Case (a).
1965
+ call_finished = true;
1966
+ grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr,
1967
+ nullptr);
1968
+ } else if (batch_data->batch.recv_trailing_metadata) { // Case (b).
1969
+ call_finished = true;
1970
+ grpc_metadata_batch* md_batch =
1971
+ batch_data->batch.payload->recv_trailing_metadata
1972
+ .recv_trailing_metadata;
1973
+ GPR_ASSERT(md_batch->idx.named.grpc_status != nullptr);
1974
+ status = grpc_get_status_code_from_metadata(
1975
+ md_batch->idx.named.grpc_status->md);
1976
+ if (md_batch->idx.named.grpc_retry_pushback_ms != nullptr) {
1977
+ server_pushback_md = &md_batch->idx.named.grpc_retry_pushback_ms->md;
1978
+ }
1979
+ } else if (retry_state->completed_recv_trailing_metadata) {
1980
+ call_finished = true;
1981
+ }
1982
+ if (call_finished && grpc_client_channel_trace.enabled()) {
1983
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: call finished, status=%s", chand,
1984
+ calld, grpc_status_code_to_string(status));
1985
+ }
1986
+ // If the call is finished, check if we should retry.
1987
+ if (call_finished &&
1988
+ maybe_retry(elem, batch_data, status, server_pushback_md)) {
1989
+ // Unref batch_data for deferred recv_initial_metadata_ready or
1990
+ // recv_message_ready callbacks, if any.
1991
+ if (batch_data->batch.recv_trailing_metadata &&
1992
+ retry_state->recv_initial_metadata_ready_deferred) {
1993
+ batch_data_unref(batch_data);
1994
+ GRPC_ERROR_UNREF(retry_state->recv_initial_metadata_error);
1995
+ }
1996
+ if (batch_data->batch.recv_trailing_metadata &&
1997
+ retry_state->recv_message_ready_deferred) {
1998
+ batch_data_unref(batch_data);
1999
+ GRPC_ERROR_UNREF(retry_state->recv_message_error);
2000
+ }
2001
+ batch_data_unref(batch_data);
2002
+ return;
2003
+ }
2004
+ }
2005
+ // If the call is finished or retries are committed, free cached data for
2006
+ // send ops that we've just completed.
2007
+ if (call_finished || calld->retry_committed) {
2008
+ free_cached_send_op_data_for_completed_batch(elem, batch_data, retry_state);
2009
+ }
2010
+ // Call not being retried.
2011
+ // Construct list of closures to execute.
2012
+ // Max number of closures is number of pending batches plus one for
2013
+ // each of:
2014
+ // - recv_initial_metadata_ready (either deferred or unstarted)
2015
+ // - recv_message_ready (either deferred or unstarted)
2016
+ // - starting a new batch for pending send ops
2017
+ closure_to_execute closures[GPR_ARRAY_SIZE(calld->pending_batches) + 3];
2018
+ size_t num_closures = 0;
2019
+ // If there are deferred recv_initial_metadata_ready or recv_message_ready
2020
+ // callbacks, add them to closures.
2021
+ add_closures_for_deferred_recv_callbacks(batch_data, retry_state, closures,
2022
+ &num_closures);
2023
+ // Find pending batches whose ops are now complete and add their
2024
+ // on_complete callbacks to closures.
2025
+ add_closures_for_completed_pending_batches(elem, batch_data, retry_state,
2026
+ GRPC_ERROR_REF(error), closures,
2027
+ &num_closures);
2028
+ // Add closures to handle any pending batches that have not yet been started.
2029
+ // If the call is finished, we fail these batches; otherwise, we add a
2030
+ // callback to start_retriable_subchannel_batches() to start them on
2031
+ // the subchannel call.
2032
+ if (call_finished) {
2033
+ add_closures_to_fail_unstarted_pending_batches(
2034
+ elem, retry_state, GRPC_ERROR_REF(error), closures, &num_closures);
2035
+ } else {
2036
+ add_closures_for_replay_or_pending_send_ops(elem, batch_data, retry_state,
2037
+ closures, &num_closures);
2038
+ }
2039
+ // Don't need batch_data anymore.
2040
+ batch_data_unref(batch_data);
2041
+ // Schedule all of the closures identified above.
2042
+ // Note that the call combiner will be yielded for each closure that
2043
+ // we schedule. We're already running in the call combiner, so one of
2044
+ // the closures can be scheduled directly, but the others will
2045
+ // have to re-enter the call combiner.
2046
+ if (num_closures > 0) {
2047
+ GRPC_CLOSURE_SCHED(closures[0].closure, closures[0].error);
2048
+ for (size_t i = 1; i < num_closures; ++i) {
2049
+ GRPC_CALL_COMBINER_START(calld->call_combiner, closures[i].closure,
2050
+ closures[i].error, closures[i].reason);
2051
+ }
2052
+ } else {
2053
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
2054
+ "no closures to run for on_complete");
2055
+ }
2056
+ }
2057
+
2058
+ //
2059
+ // subchannel batch construction
2060
+ //
2061
+
2062
+ // Helper function used to start a subchannel batch in the call combiner.
2063
+ static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) {
2064
+ grpc_transport_stream_op_batch* batch =
2065
+ static_cast<grpc_transport_stream_op_batch*>(arg);
2066
+ grpc_subchannel_call* subchannel_call =
2067
+ static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg);
2068
+ // Note: This will release the call combiner.
2069
+ grpc_subchannel_call_process_op(subchannel_call, batch);
2070
+ }
2071
+
2072
+ // Adds retriable send_initial_metadata op to batch_data.
2073
+ static void add_retriable_send_initial_metadata_op(
2074
+ call_data* calld, subchannel_call_retry_state* retry_state,
2075
+ subchannel_batch_data* batch_data) {
2076
+ // Maps the number of retries to the corresponding metadata value slice.
2077
+ static const grpc_slice* retry_count_strings[] = {
2078
+ &GRPC_MDSTR_1, &GRPC_MDSTR_2, &GRPC_MDSTR_3, &GRPC_MDSTR_4};
2079
+ // We need to make a copy of the metadata batch for each attempt, since
2080
+ // the filters in the subchannel stack may modify this batch, and we don't
2081
+ // want those modifications to be passed forward to subsequent attempts.
2082
+ //
2083
+ // If we've already completed one or more attempts, add the
2084
+ // grpc-retry-attempts header.
2085
+ batch_data->send_initial_metadata_storage =
2086
+ static_cast<grpc_linked_mdelem*>(gpr_arena_alloc(
2087
+ calld->arena, sizeof(grpc_linked_mdelem) *
2088
+ (calld->send_initial_metadata.list.count +
2089
+ (calld->num_attempts_completed > 0))));
2090
+ grpc_metadata_batch_copy(&calld->send_initial_metadata,
2091
+ &batch_data->send_initial_metadata,
2092
+ batch_data->send_initial_metadata_storage);
2093
+ if (batch_data->send_initial_metadata.idx.named.grpc_previous_rpc_attempts !=
2094
+ nullptr) {
2095
+ grpc_metadata_batch_remove(
2096
+ &batch_data->send_initial_metadata,
2097
+ batch_data->send_initial_metadata.idx.named.grpc_previous_rpc_attempts);
2098
+ }
2099
+ if (calld->num_attempts_completed > 0) {
2100
+ grpc_mdelem retry_md = grpc_mdelem_from_slices(
2101
+ GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS,
2102
+ *retry_count_strings[calld->num_attempts_completed - 1]);
2103
+ grpc_error* error = grpc_metadata_batch_add_tail(
2104
+ &batch_data->send_initial_metadata,
2105
+ &batch_data->send_initial_metadata_storage[calld->send_initial_metadata
2106
+ .list.count],
2107
+ retry_md);
2108
+ if (error != GRPC_ERROR_NONE) {
2109
+ gpr_log(GPR_ERROR, "error adding retry metadata: %s",
2110
+ grpc_error_string(error));
2111
+ GPR_ASSERT(false);
2112
+ }
2113
+ }
2114
+ retry_state->started_send_initial_metadata = true;
2115
+ batch_data->batch.send_initial_metadata = true;
2116
+ batch_data->batch.payload->send_initial_metadata.send_initial_metadata =
2117
+ &batch_data->send_initial_metadata;
2118
+ batch_data->batch.payload->send_initial_metadata.send_initial_metadata_flags =
2119
+ calld->send_initial_metadata_flags;
2120
+ batch_data->batch.payload->send_initial_metadata.peer_string =
2121
+ calld->peer_string;
2122
+ }
2123
+
2124
+ // Adds retriable send_message op to batch_data.
2125
+ static void add_retriable_send_message_op(
2126
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state,
2127
+ subchannel_batch_data* batch_data) {
2128
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2129
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2130
+ if (grpc_client_channel_trace.enabled()) {
2131
+ gpr_log(GPR_DEBUG,
2132
+ "chand=%p calld=%p: starting calld->send_messages[%" PRIuPTR "]",
2133
+ chand, calld, retry_state->started_send_message_count);
2134
+ }
2135
+ grpc_core::ByteStreamCache* cache =
2136
+ calld->send_messages[retry_state->started_send_message_count];
2137
+ ++retry_state->started_send_message_count;
2138
+ batch_data->send_message.Init(cache);
2139
+ batch_data->batch.send_message = true;
2140
+ batch_data->batch.payload->send_message.send_message.reset(
2141
+ batch_data->send_message.get());
2142
+ }
2143
+
2144
+ // Adds retriable send_trailing_metadata op to batch_data.
2145
+ static void add_retriable_send_trailing_metadata_op(
2146
+ call_data* calld, subchannel_call_retry_state* retry_state,
2147
+ subchannel_batch_data* batch_data) {
2148
+ // We need to make a copy of the metadata batch for each attempt, since
2149
+ // the filters in the subchannel stack may modify this batch, and we don't
2150
+ // want those modifications to be passed forward to subsequent attempts.
2151
+ batch_data->send_trailing_metadata_storage =
2152
+ static_cast<grpc_linked_mdelem*>(gpr_arena_alloc(
2153
+ calld->arena, sizeof(grpc_linked_mdelem) *
2154
+ calld->send_trailing_metadata.list.count));
2155
+ grpc_metadata_batch_copy(&calld->send_trailing_metadata,
2156
+ &batch_data->send_trailing_metadata,
2157
+ batch_data->send_trailing_metadata_storage);
2158
+ retry_state->started_send_trailing_metadata = true;
2159
+ batch_data->batch.send_trailing_metadata = true;
2160
+ batch_data->batch.payload->send_trailing_metadata.send_trailing_metadata =
2161
+ &batch_data->send_trailing_metadata;
2162
+ }
2163
+
2164
+ // Adds retriable recv_initial_metadata op to batch_data.
2165
+ static void add_retriable_recv_initial_metadata_op(
2166
+ call_data* calld, subchannel_call_retry_state* retry_state,
2167
+ subchannel_batch_data* batch_data) {
2168
+ retry_state->started_recv_initial_metadata = true;
2169
+ batch_data->batch.recv_initial_metadata = true;
2170
+ grpc_metadata_batch_init(&batch_data->recv_initial_metadata);
2171
+ batch_data->batch.payload->recv_initial_metadata.recv_initial_metadata =
2172
+ &batch_data->recv_initial_metadata;
2173
+ batch_data->batch.payload->recv_initial_metadata.trailing_metadata_available =
2174
+ &batch_data->trailing_metadata_available;
2175
+ GRPC_CLOSURE_INIT(&batch_data->recv_initial_metadata_ready,
2176
+ recv_initial_metadata_ready, batch_data,
2177
+ grpc_schedule_on_exec_ctx);
2178
+ batch_data->batch.payload->recv_initial_metadata.recv_initial_metadata_ready =
2179
+ &batch_data->recv_initial_metadata_ready;
2180
+ }
2181
+
2182
+ // Adds retriable recv_message op to batch_data.
2183
+ static void add_retriable_recv_message_op(
2184
+ call_data* calld, subchannel_call_retry_state* retry_state,
2185
+ subchannel_batch_data* batch_data) {
2186
+ ++retry_state->started_recv_message_count;
2187
+ batch_data->batch.recv_message = true;
2188
+ batch_data->batch.payload->recv_message.recv_message =
2189
+ &batch_data->recv_message;
2190
+ GRPC_CLOSURE_INIT(&batch_data->recv_message_ready, recv_message_ready,
2191
+ batch_data, grpc_schedule_on_exec_ctx);
2192
+ batch_data->batch.payload->recv_message.recv_message_ready =
2193
+ &batch_data->recv_message_ready;
2194
+ }
2195
+
2196
+ // Adds retriable recv_trailing_metadata op to batch_data.
2197
+ static void add_retriable_recv_trailing_metadata_op(
2198
+ call_data* calld, subchannel_call_retry_state* retry_state,
2199
+ subchannel_batch_data* batch_data) {
2200
+ retry_state->started_recv_trailing_metadata = true;
2201
+ batch_data->batch.recv_trailing_metadata = true;
2202
+ grpc_metadata_batch_init(&batch_data->recv_trailing_metadata);
2203
+ batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata =
2204
+ &batch_data->recv_trailing_metadata;
2205
+ batch_data->batch.collect_stats = true;
2206
+ batch_data->batch.payload->collect_stats.collect_stats =
2207
+ &batch_data->collect_stats;
2208
+ }
2209
+
2210
+ // Helper function used to start a recv_trailing_metadata batch. This
2211
+ // is used in the case where a recv_initial_metadata or recv_message
2212
+ // op fails in a way that we know the call is over but when the application
2213
+ // has not yet started its own recv_trailing_metadata op.
2214
+ static void start_internal_recv_trailing_metadata(grpc_call_element* elem) {
2215
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2216
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2217
+ if (grpc_client_channel_trace.enabled()) {
2218
+ gpr_log(GPR_DEBUG,
2219
+ "chand=%p calld=%p: call failed but recv_trailing_metadata not "
2220
+ "started; starting it internally",
2221
+ chand, calld);
2222
+ }
2223
+ subchannel_call_retry_state* retry_state =
2224
+ static_cast<subchannel_call_retry_state*>(
2225
+ grpc_connected_subchannel_call_get_parent_data(
2226
+ calld->subchannel_call));
2227
+ subchannel_batch_data* batch_data = batch_data_create(elem, 1);
2228
+ add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data);
2229
+ // Note: This will release the call combiner.
2230
+ grpc_subchannel_call_process_op(calld->subchannel_call, &batch_data->batch);
2231
+ }
2232
+
2233
+ // If there are any cached send ops that need to be replayed on the
2234
+ // current subchannel call, creates and returns a new subchannel batch
2235
+ // to replay those ops. Otherwise, returns nullptr.
2236
+ static subchannel_batch_data* maybe_create_subchannel_batch_for_replay(
2237
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state) {
2238
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2239
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2240
+ subchannel_batch_data* replay_batch_data = nullptr;
2241
+ // send_initial_metadata.
2242
+ if (calld->seen_send_initial_metadata &&
2243
+ !retry_state->started_send_initial_metadata &&
2244
+ !calld->pending_send_initial_metadata) {
2245
+ if (grpc_client_channel_trace.enabled()) {
2246
+ gpr_log(GPR_DEBUG,
2247
+ "chand=%p calld=%p: replaying previously completed "
2248
+ "send_initial_metadata op",
2249
+ chand, calld);
2250
+ }
2251
+ replay_batch_data = batch_data_create(elem, 1);
2252
+ add_retriable_send_initial_metadata_op(calld, retry_state,
2253
+ replay_batch_data);
2254
+ }
2255
+ // send_message.
2256
+ // Note that we can only have one send_message op in flight at a time.
2257
+ if (retry_state->started_send_message_count < calld->send_messages.size() &&
2258
+ retry_state->started_send_message_count ==
2259
+ retry_state->completed_send_message_count &&
2260
+ !calld->pending_send_message) {
2261
+ if (grpc_client_channel_trace.enabled()) {
2262
+ gpr_log(GPR_DEBUG,
2263
+ "chand=%p calld=%p: replaying previously completed "
2264
+ "send_message op",
2265
+ chand, calld);
2266
+ }
2267
+ if (replay_batch_data == nullptr) {
2268
+ replay_batch_data = batch_data_create(elem, 1);
2269
+ }
2270
+ add_retriable_send_message_op(elem, retry_state, replay_batch_data);
2271
+ }
2272
+ // send_trailing_metadata.
2273
+ // Note that we only add this op if we have no more send_message ops
2274
+ // to start, since we can't send down any more send_message ops after
2275
+ // send_trailing_metadata.
2276
+ if (calld->seen_send_trailing_metadata &&
2277
+ retry_state->started_send_message_count == calld->send_messages.size() &&
2278
+ !retry_state->started_send_trailing_metadata &&
2279
+ !calld->pending_send_trailing_metadata) {
2280
+ if (grpc_client_channel_trace.enabled()) {
2281
+ gpr_log(GPR_DEBUG,
2282
+ "chand=%p calld=%p: replaying previously completed "
2283
+ "send_trailing_metadata op",
2284
+ chand, calld);
2285
+ }
2286
+ if (replay_batch_data == nullptr) {
2287
+ replay_batch_data = batch_data_create(elem, 1);
2288
+ }
2289
+ add_retriable_send_trailing_metadata_op(calld, retry_state,
2290
+ replay_batch_data);
2291
+ }
2292
+ return replay_batch_data;
2293
+ }
2294
+
2295
+ // Adds subchannel batches for pending batches to batches, updating
2296
+ // *num_batches as needed.
2297
+ static void add_subchannel_batches_for_pending_batches(
2298
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state,
2299
+ grpc_transport_stream_op_batch** batches, size_t* num_batches) {
2300
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2301
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
2302
+ pending_batch* pending = &calld->pending_batches[i];
2303
+ grpc_transport_stream_op_batch* batch = pending->batch;
2304
+ if (batch == nullptr) continue;
2305
+ // Skip any batch that either (a) has already been started on this
2306
+ // subchannel call or (b) we can't start yet because we're still
2307
+ // replaying send ops that need to be completed first.
2308
+ // TODO(roth): Note that if any one op in the batch can't be sent
2309
+ // yet due to ops that we're replaying, we don't start any of the ops
2310
+ // in the batch. This is probably okay, but it could conceivably
2311
+ // lead to increased latency in some cases -- e.g., we could delay
2312
+ // starting a recv op due to it being in the same batch with a send
2313
+ // op. If/when we revamp the callback protocol in
2314
+ // transport_stream_op_batch, we may be able to fix this.
2315
+ if (batch->send_initial_metadata &&
2316
+ retry_state->started_send_initial_metadata) {
2317
+ continue;
2318
+ }
2319
+ if (batch->send_message && retry_state->completed_send_message_count <
2320
+ retry_state->started_send_message_count) {
2321
+ continue;
2322
+ }
2323
+ // Note that we only start send_trailing_metadata if we have no more
2324
+ // send_message ops to start, since we can't send down any more
2325
+ // send_message ops after send_trailing_metadata.
2326
+ if (batch->send_trailing_metadata &&
2327
+ (retry_state->started_send_message_count + batch->send_message <
2328
+ calld->send_messages.size() ||
2329
+ retry_state->started_send_trailing_metadata)) {
2330
+ continue;
2331
+ }
2332
+ if (batch->recv_initial_metadata &&
2333
+ retry_state->started_recv_initial_metadata) {
2334
+ continue;
2335
+ }
2336
+ if (batch->recv_message && retry_state->completed_recv_message_count <
2337
+ retry_state->started_recv_message_count) {
2338
+ continue;
2339
+ }
2340
+ if (batch->recv_trailing_metadata &&
2341
+ retry_state->started_recv_trailing_metadata) {
2342
+ continue;
2343
+ }
2344
+ // If we're not retrying, just send the batch as-is.
2345
+ if (calld->method_params == nullptr ||
2346
+ calld->method_params->retry_policy() == nullptr ||
2347
+ calld->retry_committed) {
2348
+ batches[(*num_batches)++] = batch;
2349
+ pending_batch_clear(calld, pending);
2350
+ continue;
2351
+ }
2352
+ // Create batch with the right number of callbacks.
2353
+ const int num_callbacks =
2354
+ 1 + batch->recv_initial_metadata + batch->recv_message;
2355
+ subchannel_batch_data* batch_data = batch_data_create(elem, num_callbacks);
2356
+ // Cache send ops if needed.
2357
+ maybe_cache_send_ops_for_batch(calld, pending);
2358
+ // send_initial_metadata.
2359
+ if (batch->send_initial_metadata) {
2360
+ add_retriable_send_initial_metadata_op(calld, retry_state, batch_data);
2361
+ }
2362
+ // send_message.
2363
+ if (batch->send_message) {
2364
+ add_retriable_send_message_op(elem, retry_state, batch_data);
2365
+ }
2366
+ // send_trailing_metadata.
2367
+ if (batch->send_trailing_metadata) {
2368
+ add_retriable_send_trailing_metadata_op(calld, retry_state, batch_data);
2369
+ }
2370
+ // recv_initial_metadata.
2371
+ if (batch->recv_initial_metadata) {
2372
+ // recv_flags is only used on the server side.
2373
+ GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr);
2374
+ add_retriable_recv_initial_metadata_op(calld, retry_state, batch_data);
2375
+ }
2376
+ // recv_message.
2377
+ if (batch->recv_message) {
2378
+ add_retriable_recv_message_op(calld, retry_state, batch_data);
2379
+ }
2380
+ // recv_trailing_metadata.
2381
+ if (batch->recv_trailing_metadata) {
2382
+ GPR_ASSERT(batch->collect_stats);
2383
+ add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data);
2384
+ }
2385
+ batches[(*num_batches)++] = &batch_data->batch;
2386
+ }
2387
+ }
2388
+
2389
+ // Constructs and starts whatever subchannel batches are needed on the
2390
+ // subchannel call.
2391
+ static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) {
2392
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
2393
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2394
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2395
+ if (grpc_client_channel_trace.enabled()) {
2396
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: constructing retriable batches",
2397
+ chand, calld);
2398
+ }
2399
+ subchannel_call_retry_state* retry_state =
2400
+ static_cast<subchannel_call_retry_state*>(
2401
+ grpc_connected_subchannel_call_get_parent_data(
2402
+ calld->subchannel_call));
2403
+ // We can start up to 6 batches.
2404
+ grpc_transport_stream_op_batch*
2405
+ batches[GPR_ARRAY_SIZE(calld->pending_batches)];
2406
+ size_t num_batches = 0;
2407
+ // Replay previously-returned send_* ops if needed.
2408
+ subchannel_batch_data* replay_batch_data =
2409
+ maybe_create_subchannel_batch_for_replay(elem, retry_state);
2410
+ if (replay_batch_data != nullptr) {
2411
+ batches[num_batches++] = &replay_batch_data->batch;
2412
+ }
2413
+ // Now add pending batches.
2414
+ add_subchannel_batches_for_pending_batches(elem, retry_state, batches,
2415
+ &num_batches);
2416
+ // Start batches on subchannel call.
2417
+ // Note that the call combiner will be yielded for each batch that we
2418
+ // send down. We're already running in the call combiner, so one of
2419
+ // the batches can be started directly, but the others will have to
2420
+ // re-enter the call combiner.
2421
+ if (grpc_client_channel_trace.enabled()) {
2422
+ gpr_log(GPR_DEBUG,
2423
+ "chand=%p calld=%p: starting %" PRIuPTR
2424
+ " retriable batches on subchannel_call=%p",
2425
+ chand, calld, num_batches, calld->subchannel_call);
2426
+ }
2427
+ if (num_batches == 0) {
2428
+ // This should be fairly rare, but it can happen when (e.g.) an
2429
+ // attempt completes before it has finished replaying all
2430
+ // previously sent messages.
2431
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
2432
+ "no retriable subchannel batches to start");
2433
+ } else {
2434
+ for (size_t i = 1; i < num_batches; ++i) {
2435
+ if (grpc_client_channel_trace.enabled()) {
2436
+ char* batch_str = grpc_transport_stream_op_batch_string(batches[i]);
2437
+ gpr_log(GPR_DEBUG,
2438
+ "chand=%p calld=%p: starting batch in call combiner: %s", chand,
2439
+ calld, batch_str);
2440
+ gpr_free(batch_str);
2441
+ }
2442
+ batches[i]->handler_private.extra_arg = calld->subchannel_call;
2443
+ GRPC_CLOSURE_INIT(&batches[i]->handler_private.closure,
2444
+ start_batch_in_call_combiner, batches[i],
2445
+ grpc_schedule_on_exec_ctx);
2446
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
2447
+ &batches[i]->handler_private.closure,
2448
+ GRPC_ERROR_NONE, "start_subchannel_batch");
2449
+ }
2450
+ if (grpc_client_channel_trace.enabled()) {
2451
+ char* batch_str = grpc_transport_stream_op_batch_string(batches[0]);
2452
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting batch: %s", chand, calld,
2453
+ batch_str);
2454
+ gpr_free(batch_str);
2455
+ }
2456
+ // Note: This will release the call combiner.
2457
+ grpc_subchannel_call_process_op(calld->subchannel_call, batches[0]);
2458
+ }
2459
+ }
2460
+
2461
+ //
2462
+ // LB pick
2463
+ //
2464
+
2465
+ static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) {
2466
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2467
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2468
+ const size_t parent_data_size =
2469
+ calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0;
2470
+ const grpc_core::ConnectedSubchannel::CallArgs call_args = {
2471
+ calld->pollent, // pollent
2472
+ calld->path, // path
2473
+ calld->call_start_time, // start_time
2474
+ calld->deadline, // deadline
2475
+ calld->arena, // arena
2476
+ calld->pick.subchannel_call_context, // context
2477
+ calld->call_combiner, // call_combiner
2478
+ parent_data_size // parent_data_size
2479
+ };
2480
+ grpc_error* new_error = calld->pick.connected_subchannel->CreateCall(
2481
+ call_args, &calld->subchannel_call);
2482
+ if (grpc_client_channel_trace.enabled()) {
2483
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: create subchannel_call=%p: error=%s",
2484
+ chand, calld, calld->subchannel_call, grpc_error_string(new_error));
2485
+ }
2486
+ if (new_error != GRPC_ERROR_NONE) {
2487
+ new_error = grpc_error_add_child(new_error, error);
2488
+ pending_batches_fail(elem, new_error, true /* yield_call_combiner */);
2489
+ } else {
2490
+ if (parent_data_size > 0) {
2491
+ subchannel_call_retry_state* retry_state =
2492
+ static_cast<subchannel_call_retry_state*>(
2493
+ grpc_connected_subchannel_call_get_parent_data(
2494
+ calld->subchannel_call));
2495
+ retry_state->batch_payload.context = calld->pick.subchannel_call_context;
2496
+ }
2497
+ pending_batches_resume(elem);
2498
+ }
2499
+ GRPC_ERROR_UNREF(error);
2500
+ }
2501
+
2502
+ // Invoked when a pick is completed, on both success or failure.
2503
+ static void pick_done(void* arg, grpc_error* error) {
2504
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
2505
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2506
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2507
+ if (calld->pick.connected_subchannel == nullptr) {
2508
+ // Failed to create subchannel.
2509
+ // If there was no error, this is an LB policy drop, in which case
2510
+ // we return an error; otherwise, we may retry.
2511
+ grpc_status_code status = GRPC_STATUS_OK;
2512
+ grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr,
2513
+ nullptr);
2514
+ if (error == GRPC_ERROR_NONE || !calld->enable_retries ||
2515
+ !maybe_retry(elem, nullptr /* batch_data */, status,
2516
+ nullptr /* server_pushback_md */)) {
2517
+ grpc_error* new_error =
2518
+ error == GRPC_ERROR_NONE
2519
+ ? GRPC_ERROR_CREATE_FROM_STATIC_STRING(
2520
+ "Call dropped by load balancing policy")
2521
+ : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
2522
+ "Failed to create subchannel", &error, 1);
2523
+ if (grpc_client_channel_trace.enabled()) {
2524
+ gpr_log(GPR_DEBUG,
2525
+ "chand=%p calld=%p: failed to create subchannel: error=%s",
2526
+ chand, calld, grpc_error_string(new_error));
2527
+ }
2528
+ pending_batches_fail(elem, new_error, true /* yield_call_combiner */);
2529
+ }
2530
+ } else {
2531
+ /* Create call on subchannel. */
2532
+ create_subchannel_call(elem, GRPC_ERROR_REF(error));
2533
+ }
2534
+ }
2535
+
2536
+ // Invoked when a pick is completed to leave the client_channel combiner
2537
+ // and continue processing in the call combiner.
2538
+ static void pick_done_locked(grpc_call_element* elem, grpc_error* error) {
2539
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2540
+ GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem,
2541
+ grpc_schedule_on_exec_ctx);
2542
+ GRPC_CLOSURE_SCHED(&calld->pick_closure, error);
2543
+ }
2544
+
2545
+ // A wrapper around pick_done_locked() that is used in cases where
2546
+ // either (a) the pick was deferred pending a resolver result or (b) the
2547
+ // pick was done asynchronously. Removes the call's polling entity from
2548
+ // chand->interested_parties before invoking pick_done_locked().
2549
+ static void async_pick_done_locked(grpc_call_element* elem, grpc_error* error) {
2550
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2551
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2552
+ grpc_polling_entity_del_from_pollset_set(calld->pollent,
2553
+ chand->interested_parties);
2554
+ pick_done_locked(elem, error);
2555
+ }
2556
+
2557
+ // Note: This runs under the client_channel combiner, but will NOT be
2558
+ // holding the call combiner.
2559
+ static void pick_callback_cancel_locked(void* arg, grpc_error* error) {
2560
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
2561
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2562
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2563
+ // Note: chand->lb_policy may have changed since we started our pick,
2564
+ // in which case we will be cancelling the pick on a policy other than
2565
+ // the one we started it on. However, this will just be a no-op.
2566
+ if (error != GRPC_ERROR_NONE && chand->lb_policy != nullptr) {
2567
+ if (grpc_client_channel_trace.enabled()) {
2568
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: cancelling pick from LB policy %p",
2569
+ chand, calld, chand->lb_policy.get());
2570
+ }
2571
+ chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error));
2572
+ }
2573
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel");
2574
+ }
2575
+
2576
+ // Callback invoked by LoadBalancingPolicy::PickLocked() for async picks.
2577
+ // Unrefs the LB policy and invokes async_pick_done_locked().
2578
+ static void pick_callback_done_locked(void* arg, grpc_error* error) {
2579
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
2580
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2581
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2582
+ if (grpc_client_channel_trace.enabled()) {
2583
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed asynchronously",
2584
+ chand, calld);
2585
+ }
2586
+ async_pick_done_locked(elem, GRPC_ERROR_REF(error));
2587
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
2588
+ }
2589
+
2590
+ // Applies service config to the call. Must be invoked once we know
2591
+ // that the resolver has returned results to the channel.
2592
+ static void apply_service_config_to_call_locked(grpc_call_element* elem) {
2593
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2594
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2595
+ if (grpc_client_channel_trace.enabled()) {
2596
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: applying service config to call",
2597
+ chand, calld);
2598
+ }
2599
+ if (chand->retry_throttle_data != nullptr) {
2600
+ calld->retry_throttle_data = chand->retry_throttle_data->Ref();
2601
+ }
2602
+ if (chand->method_params_table != nullptr) {
2603
+ calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup(
2604
+ *chand->method_params_table, calld->path);
2605
+ if (calld->method_params != nullptr) {
2606
+ // If the deadline from the service config is shorter than the one
2607
+ // from the client API, reset the deadline timer.
2608
+ if (chand->deadline_checking_enabled &&
2609
+ calld->method_params->timeout() != 0) {
2610
+ const grpc_millis per_method_deadline =
2611
+ grpc_timespec_to_millis_round_up(calld->call_start_time) +
2612
+ calld->method_params->timeout();
2613
+ if (per_method_deadline < calld->deadline) {
2614
+ calld->deadline = per_method_deadline;
2615
+ grpc_deadline_state_reset(elem, calld->deadline);
2616
+ }
2617
+ }
2618
+ }
2619
+ }
2620
+ // If no retry policy, disable retries.
2621
+ // TODO(roth): Remove this when adding support for transparent retries.
2622
+ if (calld->method_params == nullptr ||
2623
+ calld->method_params->retry_policy() == nullptr) {
2624
+ calld->enable_retries = false;
2625
+ }
2626
+ }
2627
+
2628
+ // Starts a pick on chand->lb_policy.
2629
+ // Returns true if pick is completed synchronously.
2630
+ static bool pick_callback_start_locked(grpc_call_element* elem) {
2631
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2632
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2633
+ if (grpc_client_channel_trace.enabled()) {
2634
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting pick on lb_policy=%p",
2635
+ chand, calld, chand->lb_policy.get());
2636
+ }
2637
+ // Only get service config data on the first attempt.
2638
+ if (calld->num_attempts_completed == 0) {
2639
+ apply_service_config_to_call_locked(elem);
2640
+ }
2641
+ // If the application explicitly set wait_for_ready, use that.
2642
+ // Otherwise, if the service config specified a value for this
2643
+ // method, use that.
2644
+ //
2645
+ // The send_initial_metadata batch will be the first one in the list,
2646
+ // as set by get_batch_index() above.
2647
+ calld->pick.initial_metadata =
2648
+ calld->seen_send_initial_metadata
2649
+ ? &calld->send_initial_metadata
2650
+ : calld->pending_batches[0]
2651
+ .batch->payload->send_initial_metadata.send_initial_metadata;
2652
+ uint32_t send_initial_metadata_flags =
2653
+ calld->seen_send_initial_metadata
2654
+ ? calld->send_initial_metadata_flags
2655
+ : calld->pending_batches[0]
2656
+ .batch->payload->send_initial_metadata
2657
+ .send_initial_metadata_flags;
2658
+ const bool wait_for_ready_set_from_api =
2659
+ send_initial_metadata_flags &
2660
+ GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
2661
+ const bool wait_for_ready_set_from_service_config =
2662
+ calld->method_params != nullptr &&
2663
+ calld->method_params->wait_for_ready() !=
2664
+ ClientChannelMethodParams::WAIT_FOR_READY_UNSET;
2665
+ if (!wait_for_ready_set_from_api && wait_for_ready_set_from_service_config) {
2666
+ if (calld->method_params->wait_for_ready() ==
2667
+ ClientChannelMethodParams::WAIT_FOR_READY_TRUE) {
2668
+ send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
2669
+ } else {
2670
+ send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
2671
+ }
2672
+ }
2673
+ calld->pick.initial_metadata_flags = send_initial_metadata_flags;
2674
+ GRPC_CLOSURE_INIT(&calld->pick_closure, pick_callback_done_locked, elem,
2675
+ grpc_combiner_scheduler(chand->combiner));
2676
+ calld->pick.on_complete = &calld->pick_closure;
2677
+ GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback");
2678
+ const bool pick_done = chand->lb_policy->PickLocked(&calld->pick);
2679
+ if (pick_done) {
2680
+ // Pick completed synchronously.
2681
+ if (grpc_client_channel_trace.enabled()) {
2682
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed synchronously",
2683
+ chand, calld);
2684
+ }
2685
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
2686
+ } else {
2687
+ GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel");
2688
+ grpc_call_combiner_set_notify_on_cancel(
2689
+ calld->call_combiner,
2690
+ GRPC_CLOSURE_INIT(&calld->pick_cancel_closure,
2691
+ pick_callback_cancel_locked, elem,
2692
+ grpc_combiner_scheduler(chand->combiner)));
2693
+ }
2694
+ return pick_done;
2695
+ }
2696
+
2697
+ typedef struct {
2698
+ grpc_call_element* elem;
2699
+ bool finished;
2700
+ grpc_closure closure;
2701
+ grpc_closure cancel_closure;
2702
+ } pick_after_resolver_result_args;
2703
+
2704
+ // Note: This runs under the client_channel combiner, but will NOT be
2705
+ // holding the call combiner.
2706
+ static void pick_after_resolver_result_cancel_locked(void* arg,
2707
+ grpc_error* error) {
2708
+ pick_after_resolver_result_args* args =
2709
+ static_cast<pick_after_resolver_result_args*>(arg);
2710
+ if (args->finished) {
2711
+ gpr_free(args);
2712
+ return;
2713
+ }
2714
+ // If we don't yet have a resolver result, then a closure for
2715
+ // pick_after_resolver_result_done_locked() will have been added to
2716
+ // chand->waiting_for_resolver_result_closures, and it may not be invoked
2717
+ // until after this call has been destroyed. We mark the operation as
2718
+ // finished, so that when pick_after_resolver_result_done_locked()
2719
+ // is called, it will be a no-op. We also immediately invoke
2720
+ // async_pick_done_locked() to propagate the error back to the caller.
2721
+ args->finished = true;
2722
+ grpc_call_element* elem = args->elem;
2723
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2724
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2725
+ if (grpc_client_channel_trace.enabled()) {
2726
+ gpr_log(GPR_DEBUG,
2727
+ "chand=%p calld=%p: cancelling pick waiting for resolver result",
2728
+ chand, calld);
2729
+ }
2730
+ // Note: Although we are not in the call combiner here, we are
2731
+ // basically stealing the call combiner from the pending pick, so
2732
+ // it's safe to call async_pick_done_locked() here -- we are
2733
+ // essentially calling it here instead of calling it in
2734
+ // pick_after_resolver_result_done_locked().
2735
+ async_pick_done_locked(elem, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
2736
+ "Pick cancelled", &error, 1));
2737
+ }
2738
+
2739
+ static void pick_after_resolver_result_done_locked(void* arg,
2740
+ grpc_error* error) {
2741
+ pick_after_resolver_result_args* args =
2742
+ static_cast<pick_after_resolver_result_args*>(arg);
2743
+ if (args->finished) {
2744
+ /* cancelled, do nothing */
2745
+ if (grpc_client_channel_trace.enabled()) {
2746
+ gpr_log(GPR_DEBUG, "call cancelled before resolver result");
2747
+ }
2748
+ gpr_free(args);
2749
+ return;
2750
+ }
2751
+ args->finished = true;
2752
+ grpc_call_element* elem = args->elem;
2753
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2754
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2755
+ if (error != GRPC_ERROR_NONE) {
2756
+ if (grpc_client_channel_trace.enabled()) {
2757
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver failed to return data",
2758
+ chand, calld);
2759
+ }
2760
+ async_pick_done_locked(elem, GRPC_ERROR_REF(error));
2761
+ } else if (chand->resolver == nullptr) {
2762
+ // Shutting down.
2763
+ if (grpc_client_channel_trace.enabled()) {
2764
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver disconnected", chand,
2765
+ calld);
2766
+ }
2767
+ async_pick_done_locked(
2768
+ elem, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
2769
+ } else if (chand->lb_policy == nullptr) {
2770
+ // Transient resolver failure.
2771
+ // If call has wait_for_ready=true, try again; otherwise, fail.
2772
+ uint32_t send_initial_metadata_flags =
2773
+ calld->seen_send_initial_metadata
2774
+ ? calld->send_initial_metadata_flags
2775
+ : calld->pending_batches[0]
2776
+ .batch->payload->send_initial_metadata
2777
+ .send_initial_metadata_flags;
2778
+ if (send_initial_metadata_flags & GRPC_INITIAL_METADATA_WAIT_FOR_READY) {
2779
+ if (grpc_client_channel_trace.enabled()) {
2780
+ gpr_log(GPR_DEBUG,
2781
+ "chand=%p calld=%p: resolver returned but no LB policy; "
2782
+ "wait_for_ready=true; trying again",
2783
+ chand, calld);
2784
+ }
2785
+ pick_after_resolver_result_start_locked(elem);
2786
+ } else {
2787
+ if (grpc_client_channel_trace.enabled()) {
2788
+ gpr_log(GPR_DEBUG,
2789
+ "chand=%p calld=%p: resolver returned but no LB policy; "
2790
+ "wait_for_ready=false; failing",
2791
+ chand, calld);
2792
+ }
2793
+ async_pick_done_locked(
2794
+ elem,
2795
+ grpc_error_set_int(
2796
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Name resolution failure"),
2797
+ GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE));
2798
+ }
2799
+ } else {
2800
+ if (grpc_client_channel_trace.enabled()) {
2801
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: resolver returned, doing pick",
2802
+ chand, calld);
2803
+ }
2804
+ if (pick_callback_start_locked(elem)) {
2805
+ // Even if the LB policy returns a result synchronously, we have
2806
+ // already added our polling entity to chand->interested_parties
2807
+ // in order to wait for the resolver result, so we need to
2808
+ // remove it here. Therefore, we call async_pick_done_locked()
2809
+ // instead of pick_done_locked().
2810
+ async_pick_done_locked(elem, GRPC_ERROR_NONE);
2811
+ }
2812
+ }
2813
+ }
2814
+
2815
+ static void pick_after_resolver_result_start_locked(grpc_call_element* elem) {
2816
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2817
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2818
+ if (grpc_client_channel_trace.enabled()) {
2819
+ gpr_log(GPR_DEBUG,
2820
+ "chand=%p calld=%p: deferring pick pending resolver result", chand,
2821
+ calld);
2822
+ }
2823
+ pick_after_resolver_result_args* args =
2824
+ static_cast<pick_after_resolver_result_args*>(gpr_zalloc(sizeof(*args)));
2825
+ args->elem = elem;
2826
+ GRPC_CLOSURE_INIT(&args->closure, pick_after_resolver_result_done_locked,
2827
+ args, grpc_combiner_scheduler(chand->combiner));
2828
+ grpc_closure_list_append(&chand->waiting_for_resolver_result_closures,
2829
+ &args->closure, GRPC_ERROR_NONE);
2830
+ grpc_call_combiner_set_notify_on_cancel(
2831
+ calld->call_combiner,
2832
+ GRPC_CLOSURE_INIT(&args->cancel_closure,
2833
+ pick_after_resolver_result_cancel_locked, args,
2834
+ grpc_combiner_scheduler(chand->combiner)));
2835
+ }
2836
+
2837
+ static void start_pick_locked(void* arg, grpc_error* ignored) {
2838
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
2839
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2840
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2841
+ GPR_ASSERT(calld->pick.connected_subchannel == nullptr);
2842
+ GPR_ASSERT(calld->subchannel_call == nullptr);
2843
+ if (chand->lb_policy != nullptr) {
2844
+ // We already have an LB policy, so ask it for a pick.
2845
+ if (pick_callback_start_locked(elem)) {
2846
+ // Pick completed synchronously.
2847
+ pick_done_locked(elem, GRPC_ERROR_NONE);
2848
+ return;
2849
+ }
2850
+ } else {
2851
+ // We do not yet have an LB policy, so wait for a resolver result.
2852
+ if (chand->resolver == nullptr) {
2853
+ pick_done_locked(elem,
2854
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
2855
+ return;
2856
+ }
2857
+ if (!chand->started_resolving) {
2858
+ start_resolving_locked(chand);
2859
+ }
2860
+ pick_after_resolver_result_start_locked(elem);
2861
+ }
2862
+ // We need to wait for either a resolver result or for an async result
2863
+ // from the LB policy. Add the polling entity from call_data to the
2864
+ // channel_data's interested_parties, so that the I/O of the LB policy
2865
+ // and resolver can be done under it. The polling entity will be
2866
+ // removed in async_pick_done_locked().
2867
+ grpc_polling_entity_add_to_pollset_set(calld->pollent,
2868
+ chand->interested_parties);
2869
+ }
2870
+
2871
+ //
2872
+ // filter call vtable functions
2873
+ //
2874
+
2875
+ static void cc_start_transport_stream_op_batch(
2876
+ grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
2877
+ GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0);
2878
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2879
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2880
+ if (chand->deadline_checking_enabled) {
2881
+ grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch);
2882
+ }
2883
+ // If we've previously been cancelled, immediately fail any new batches.
2884
+ if (calld->cancel_error != GRPC_ERROR_NONE) {
2885
+ if (grpc_client_channel_trace.enabled()) {
2886
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: failing batch with error: %s",
2887
+ chand, calld, grpc_error_string(calld->cancel_error));
2888
+ }
2889
+ // Note: This will release the call combiner.
2890
+ grpc_transport_stream_op_batch_finish_with_failure(
2891
+ batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner);
2892
+ return;
2893
+ }
2894
+ // Handle cancellation.
2895
+ if (batch->cancel_stream) {
2896
+ // Stash a copy of cancel_error in our call data, so that we can use
2897
+ // it for subsequent operations. This ensures that if the call is
2898
+ // cancelled before any batches are passed down (e.g., if the deadline
2899
+ // is in the past when the call starts), we can return the right
2900
+ // error to the caller when the first batch does get passed down.
2901
+ GRPC_ERROR_UNREF(calld->cancel_error);
2902
+ calld->cancel_error =
2903
+ GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
2904
+ if (grpc_client_channel_trace.enabled()) {
2905
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: recording cancel_error=%s", chand,
2906
+ calld, grpc_error_string(calld->cancel_error));
2907
+ }
2908
+ // If we do not have a subchannel call (i.e., a pick has not yet
2909
+ // been started), fail all pending batches. Otherwise, send the
2910
+ // cancellation down to the subchannel call.
2911
+ if (calld->subchannel_call == nullptr) {
2912
+ pending_batches_fail(elem, GRPC_ERROR_REF(calld->cancel_error),
2913
+ false /* yield_call_combiner */);
2914
+ // Note: This will release the call combiner.
2915
+ grpc_transport_stream_op_batch_finish_with_failure(
2916
+ batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner);
2917
+ } else {
2918
+ // Note: This will release the call combiner.
2919
+ grpc_subchannel_call_process_op(calld->subchannel_call, batch);
2920
+ }
2921
+ return;
2922
+ }
2923
+ // Add the batch to the pending list.
2924
+ pending_batches_add(elem, batch);
2925
+ // Check if we've already gotten a subchannel call.
2926
+ // Note that once we have completed the pick, we do not need to enter
2927
+ // the channel combiner, which is more efficient (especially for
2928
+ // streaming calls).
2929
+ if (calld->subchannel_call != nullptr) {
2930
+ if (grpc_client_channel_trace.enabled()) {
2931
+ gpr_log(GPR_DEBUG,
2932
+ "chand=%p calld=%p: starting batch on subchannel_call=%p", chand,
2933
+ calld, calld->subchannel_call);
2934
+ }
2935
+ pending_batches_resume(elem);
2936
+ return;
2937
+ }
2938
+ // We do not yet have a subchannel call.
2939
+ // For batches containing a send_initial_metadata op, enter the channel
2940
+ // combiner to start a pick.
2941
+ if (batch->send_initial_metadata) {
2942
+ if (grpc_client_channel_trace.enabled()) {
2943
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: entering client_channel combiner",
2944
+ chand, calld);
2945
+ }
2946
+ GRPC_CLOSURE_SCHED(
2947
+ GRPC_CLOSURE_INIT(&batch->handler_private.closure, start_pick_locked,
2948
+ elem, grpc_combiner_scheduler(chand->combiner)),
2949
+ GRPC_ERROR_NONE);
2950
+ } else {
2951
+ // For all other batches, release the call combiner.
2952
+ if (grpc_client_channel_trace.enabled()) {
2953
+ gpr_log(GPR_DEBUG,
2954
+ "chand=%p calld=%p: saved batch, yeilding call combiner", chand,
2955
+ calld);
2956
+ }
2957
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
2958
+ "batch does not include send_initial_metadata");
2959
+ }
2960
+ }
2961
+
2962
+ /* Constructor for call_data */
2963
+ static grpc_error* cc_init_call_elem(grpc_call_element* elem,
2964
+ const grpc_call_element_args* args) {
2965
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2966
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2967
+ // Initialize data members.
2968
+ calld->path = grpc_slice_ref_internal(args->path);
2969
+ calld->call_start_time = args->start_time;
2970
+ calld->deadline = args->deadline;
2971
+ calld->arena = args->arena;
2972
+ calld->owning_call = args->call_stack;
2973
+ calld->call_combiner = args->call_combiner;
2974
+ if (chand->deadline_checking_enabled) {
2975
+ grpc_deadline_state_init(elem, args->call_stack, args->call_combiner,
2976
+ calld->deadline);
2977
+ }
2978
+ calld->enable_retries = chand->enable_retries;
2979
+ return GRPC_ERROR_NONE;
2980
+ }
2981
+
2982
+ /* Destructor for call_data */
2983
+ static void cc_destroy_call_elem(grpc_call_element* elem,
2984
+ const grpc_call_final_info* final_info,
2985
+ grpc_closure* then_schedule_closure) {
2986
+ call_data* calld = static_cast<call_data*>(elem->call_data);
2987
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
2988
+ if (chand->deadline_checking_enabled) {
2989
+ grpc_deadline_state_destroy(elem);
2990
+ }
2991
+ grpc_slice_unref_internal(calld->path);
2992
+ calld->retry_throttle_data.reset();
2993
+ calld->method_params.reset();
2994
+ GRPC_ERROR_UNREF(calld->cancel_error);
2995
+ if (calld->subchannel_call != nullptr) {
2996
+ grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call,
2997
+ then_schedule_closure);
2998
+ then_schedule_closure = nullptr;
2999
+ GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call,
3000
+ "client_channel_destroy_call");
3001
+ }
3002
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
3003
+ GPR_ASSERT(calld->pending_batches[i].batch == nullptr);
3004
+ }
3005
+ if (calld->pick.connected_subchannel != nullptr) {
3006
+ calld->pick.connected_subchannel.reset();
3007
+ }
3008
+ for (size_t i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
3009
+ if (calld->pick.subchannel_call_context[i].value != nullptr) {
3010
+ calld->pick.subchannel_call_context[i].destroy(
3011
+ calld->pick.subchannel_call_context[i].value);
3012
+ }
3013
+ }
3014
+ GRPC_CLOSURE_SCHED(then_schedule_closure, GRPC_ERROR_NONE);
3015
+ }
3016
+
3017
+ static void cc_set_pollset_or_pollset_set(grpc_call_element* elem,
3018
+ grpc_polling_entity* pollent) {
3019
+ call_data* calld = static_cast<call_data*>(elem->call_data);
3020
+ calld->pollent = pollent;
3021
+ }
3022
+
3023
+ /*************************************************************************
3024
+ * EXPORTED SYMBOLS
3025
+ */
3026
+
3027
+ const grpc_channel_filter grpc_client_channel_filter = {
3028
+ cc_start_transport_stream_op_batch,
3029
+ cc_start_transport_op,
3030
+ sizeof(call_data),
3031
+ cc_init_call_elem,
3032
+ cc_set_pollset_or_pollset_set,
3033
+ cc_destroy_call_elem,
3034
+ sizeof(channel_data),
3035
+ cc_init_channel_elem,
3036
+ cc_destroy_channel_elem,
3037
+ cc_get_channel_info,
3038
+ "client-channel",
3039
+ };
3040
+
3041
+ static void try_to_connect_locked(void* arg, grpc_error* error_ignored) {
3042
+ channel_data* chand = static_cast<channel_data*>(arg);
3043
+ if (chand->lb_policy != nullptr) {
3044
+ chand->lb_policy->ExitIdleLocked();
3045
+ } else {
3046
+ chand->exit_idle_when_lb_policy_arrives = true;
3047
+ if (!chand->started_resolving && chand->resolver != nullptr) {
3048
+ start_resolving_locked(chand);
3049
+ }
3050
+ }
3051
+ GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "try_to_connect");
3052
+ }
3053
+
3054
+ grpc_connectivity_state grpc_client_channel_check_connectivity_state(
3055
+ grpc_channel_element* elem, int try_to_connect) {
3056
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
3057
+ grpc_connectivity_state out =
3058
+ grpc_connectivity_state_check(&chand->state_tracker);
3059
+ if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
3060
+ GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect");
3061
+ GRPC_CLOSURE_SCHED(
3062
+ GRPC_CLOSURE_CREATE(try_to_connect_locked, chand,
3063
+ grpc_combiner_scheduler(chand->combiner)),
3064
+ GRPC_ERROR_NONE);
3065
+ }
3066
+ return out;
3067
+ }
3068
+
3069
+ typedef struct external_connectivity_watcher {
3070
+ channel_data* chand;
3071
+ grpc_polling_entity pollent;
3072
+ grpc_closure* on_complete;
3073
+ grpc_closure* watcher_timer_init;
3074
+ grpc_connectivity_state* state;
3075
+ grpc_closure my_closure;
3076
+ struct external_connectivity_watcher* next;
3077
+ } external_connectivity_watcher;
3078
+
3079
+ static external_connectivity_watcher* lookup_external_connectivity_watcher(
3080
+ channel_data* chand, grpc_closure* on_complete) {
3081
+ gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
3082
+ external_connectivity_watcher* w =
3083
+ chand->external_connectivity_watcher_list_head;
3084
+ while (w != nullptr && w->on_complete != on_complete) {
3085
+ w = w->next;
3086
+ }
3087
+ gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
3088
+ return w;
3089
+ }
3090
+
3091
+ static void external_connectivity_watcher_list_append(
3092
+ channel_data* chand, external_connectivity_watcher* w) {
3093
+ GPR_ASSERT(!lookup_external_connectivity_watcher(chand, w->on_complete));
3094
+
3095
+ gpr_mu_lock(&w->chand->external_connectivity_watcher_list_mu);
3096
+ GPR_ASSERT(!w->next);
3097
+ w->next = chand->external_connectivity_watcher_list_head;
3098
+ chand->external_connectivity_watcher_list_head = w;
3099
+ gpr_mu_unlock(&w->chand->external_connectivity_watcher_list_mu);
3100
+ }
3101
+
3102
+ static void external_connectivity_watcher_list_remove(
3103
+ channel_data* chand, external_connectivity_watcher* too_remove) {
3104
+ GPR_ASSERT(
3105
+ lookup_external_connectivity_watcher(chand, too_remove->on_complete));
3106
+ gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
3107
+ if (too_remove == chand->external_connectivity_watcher_list_head) {
3108
+ chand->external_connectivity_watcher_list_head = too_remove->next;
3109
+ gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
3110
+ return;
3111
+ }
3112
+ external_connectivity_watcher* w =
3113
+ chand->external_connectivity_watcher_list_head;
3114
+ while (w != nullptr) {
3115
+ if (w->next == too_remove) {
3116
+ w->next = w->next->next;
3117
+ gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
3118
+ return;
3119
+ }
3120
+ w = w->next;
3121
+ }
3122
+ GPR_UNREACHABLE_CODE(return );
3123
+ }
3124
+
3125
+ int grpc_client_channel_num_external_connectivity_watchers(
3126
+ grpc_channel_element* elem) {
3127
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
3128
+ int count = 0;
3129
+
3130
+ gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
3131
+ external_connectivity_watcher* w =
3132
+ chand->external_connectivity_watcher_list_head;
3133
+ while (w != nullptr) {
3134
+ count++;
3135
+ w = w->next;
3136
+ }
3137
+ gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
3138
+
3139
+ return count;
3140
+ }
3141
+
3142
+ static void on_external_watch_complete_locked(void* arg, grpc_error* error) {
3143
+ external_connectivity_watcher* w =
3144
+ static_cast<external_connectivity_watcher*>(arg);
3145
+ grpc_closure* follow_up = w->on_complete;
3146
+ grpc_polling_entity_del_from_pollset_set(&w->pollent,
3147
+ w->chand->interested_parties);
3148
+ GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack,
3149
+ "external_connectivity_watcher");
3150
+ external_connectivity_watcher_list_remove(w->chand, w);
3151
+ gpr_free(w);
3152
+ GRPC_CLOSURE_RUN(follow_up, GRPC_ERROR_REF(error));
3153
+ }
3154
+
3155
+ static void watch_connectivity_state_locked(void* arg,
3156
+ grpc_error* error_ignored) {
3157
+ external_connectivity_watcher* w =
3158
+ static_cast<external_connectivity_watcher*>(arg);
3159
+ external_connectivity_watcher* found = nullptr;
3160
+ if (w->state != nullptr) {
3161
+ external_connectivity_watcher_list_append(w->chand, w);
3162
+ GRPC_CLOSURE_RUN(w->watcher_timer_init, GRPC_ERROR_NONE);
3163
+ GRPC_CLOSURE_INIT(&w->my_closure, on_external_watch_complete_locked, w,
3164
+ grpc_combiner_scheduler(w->chand->combiner));
3165
+ grpc_connectivity_state_notify_on_state_change(&w->chand->state_tracker,
3166
+ w->state, &w->my_closure);
3167
+ } else {
3168
+ GPR_ASSERT(w->watcher_timer_init == nullptr);
3169
+ found = lookup_external_connectivity_watcher(w->chand, w->on_complete);
3170
+ if (found) {
3171
+ GPR_ASSERT(found->on_complete == w->on_complete);
3172
+ grpc_connectivity_state_notify_on_state_change(
3173
+ &found->chand->state_tracker, nullptr, &found->my_closure);
3174
+ }
3175
+ grpc_polling_entity_del_from_pollset_set(&w->pollent,
3176
+ w->chand->interested_parties);
3177
+ GRPC_CHANNEL_STACK_UNREF(w->chand->owning_stack,
3178
+ "external_connectivity_watcher");
3179
+ gpr_free(w);
3180
+ }
3181
+ }
3182
+
3183
+ void grpc_client_channel_watch_connectivity_state(
3184
+ grpc_channel_element* elem, grpc_polling_entity pollent,
3185
+ grpc_connectivity_state* state, grpc_closure* closure,
3186
+ grpc_closure* watcher_timer_init) {
3187
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
3188
+ external_connectivity_watcher* w =
3189
+ static_cast<external_connectivity_watcher*>(gpr_zalloc(sizeof(*w)));
3190
+ w->chand = chand;
3191
+ w->pollent = pollent;
3192
+ w->on_complete = closure;
3193
+ w->state = state;
3194
+ w->watcher_timer_init = watcher_timer_init;
3195
+ grpc_polling_entity_add_to_pollset_set(&w->pollent,
3196
+ chand->interested_parties);
3197
+ GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
3198
+ "external_connectivity_watcher");
3199
+ GRPC_CLOSURE_SCHED(
3200
+ GRPC_CLOSURE_INIT(&w->my_closure, watch_connectivity_state_locked, w,
3201
+ grpc_combiner_scheduler(chand->combiner)),
3202
+ GRPC_ERROR_NONE);
3203
+ }
3204
+
3205
+ grpc_subchannel_call* grpc_client_channel_get_subchannel_call(
3206
+ grpc_call_element* elem) {
3207
+ call_data* calld = static_cast<call_data*>(elem->call_data);
3208
+ return calld->subchannel_call;
3209
+ }