grpc 1.50.0 → 1.51.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (459) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +131 -42
  3. data/include/grpc/event_engine/event_engine.h +10 -3
  4. data/include/grpc/event_engine/slice_buffer.h +17 -0
  5. data/include/grpc/grpc.h +0 -10
  6. data/include/grpc/impl/codegen/grpc_types.h +1 -5
  7. data/include/grpc/impl/codegen/port_platform.h +0 -3
  8. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +19 -13
  9. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +1 -0
  10. data/src/core/ext/filters/client_channel/backup_poller.cc +3 -3
  11. data/src/core/ext/filters/client_channel/channel_connectivity.cc +7 -5
  12. data/src/core/ext/filters/client_channel/client_channel.cc +120 -140
  13. data/src/core/ext/filters/client_channel/client_channel.h +3 -4
  14. data/src/core/ext/filters/client_channel/client_channel_channelz.cc +0 -2
  15. data/src/core/ext/filters/client_channel/client_channel_plugin.cc +1 -1
  16. data/src/core/ext/filters/client_channel/client_channel_service_config.cc +153 -0
  17. data/src/core/ext/filters/client_channel/{resolver_result_parsing.h → client_channel_service_config.h} +26 -23
  18. data/src/core/ext/filters/client_channel/connector.h +1 -1
  19. data/src/core/ext/filters/client_channel/dynamic_filters.cc +20 -47
  20. data/src/core/ext/filters/client_channel/dynamic_filters.h +7 -8
  21. data/src/core/ext/filters/client_channel/health/health_check_client.cc +3 -4
  22. data/src/core/ext/filters/client_channel/http_proxy.cc +0 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +3 -4
  24. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +5 -0
  25. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +8 -7
  26. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +35 -44
  27. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +0 -1
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +1 -3
  29. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +3 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.h +1 -1
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +41 -29
  32. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +2 -2
  33. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +9 -11
  34. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +15 -12
  35. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +8 -10
  36. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +26 -27
  37. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +7 -9
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +44 -26
  39. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +17 -27
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_attributes.cc +42 -0
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/{xds.h → xds_attributes.h} +15 -17
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +13 -7
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +48 -47
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +40 -126
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +364 -0
  46. data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +9 -9
  47. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +23 -32
  48. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +1 -2
  49. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +22 -23
  50. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +50 -52
  51. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +1 -1
  52. data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +2 -4
  53. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +1 -3
  54. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +34 -26
  55. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +3 -4
  56. data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +4 -7
  57. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +63 -46
  58. data/src/core/ext/filters/client_channel/retry_filter.cc +80 -102
  59. data/src/core/ext/filters/client_channel/retry_service_config.cc +192 -234
  60. data/src/core/ext/filters/client_channel/retry_service_config.h +20 -23
  61. data/src/core/ext/filters/client_channel/retry_throttle.cc +8 -8
  62. data/src/core/ext/filters/client_channel/retry_throttle.h +8 -7
  63. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +2 -2
  64. data/src/core/ext/filters/client_channel/subchannel.cc +21 -25
  65. data/src/core/ext/filters/client_channel/subchannel.h +2 -2
  66. data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +11 -12
  67. data/src/core/ext/filters/deadline/deadline_filter.cc +13 -14
  68. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
  69. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +0 -4
  70. data/src/core/ext/filters/fault_injection/fault_injection_service_config_parser.cc +118 -0
  71. data/src/core/ext/filters/fault_injection/{service_config_parser.h → fault_injection_service_config_parser.h} +20 -12
  72. data/src/core/ext/filters/http/client/http_client_filter.cc +16 -16
  73. data/src/core/ext/filters/http/client_authority_filter.cc +1 -1
  74. data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +13 -13
  75. data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +34 -34
  76. data/src/core/ext/filters/http/server/http_server_filter.cc +26 -25
  77. data/src/core/ext/filters/message_size/message_size_filter.cc +86 -117
  78. data/src/core/ext/filters/message_size/message_size_filter.h +22 -15
  79. data/src/core/ext/filters/rbac/rbac_filter.cc +12 -12
  80. data/src/core/ext/filters/rbac/rbac_service_config_parser.cc +728 -530
  81. data/src/core/ext/filters/rbac/rbac_service_config_parser.h +4 -3
  82. data/src/core/ext/filters/server_config_selector/server_config_selector.h +1 -1
  83. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +6 -7
  84. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +17 -21
  85. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +57 -72
  86. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +5 -5
  87. data/src/core/ext/transport/chttp2/transport/bin_encoder.h +1 -1
  88. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +212 -253
  89. data/src/core/ext/transport/chttp2/transport/flow_control.cc +42 -11
  90. data/src/core/ext/transport/chttp2/transport/flow_control.h +4 -3
  91. data/src/core/ext/transport/chttp2/transport/frame_data.cc +16 -15
  92. data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
  93. data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +13 -13
  94. data/src/core/ext/transport/chttp2/transport/frame_ping.cc +4 -3
  95. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +10 -7
  96. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +15 -17
  97. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +5 -4
  98. data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +5 -6
  99. data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +1 -1
  100. data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +2 -1
  101. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +31 -39
  102. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +7 -6
  103. data/src/core/ext/transport/chttp2/transport/internal.h +24 -8
  104. data/src/core/ext/transport/chttp2/transport/parsing.cc +51 -52
  105. data/src/core/ext/transport/chttp2/transport/varint.cc +2 -3
  106. data/src/core/ext/transport/chttp2/transport/varint.h +11 -8
  107. data/src/core/ext/transport/chttp2/transport/writing.cc +16 -16
  108. data/src/core/ext/transport/inproc/inproc_transport.cc +97 -115
  109. data/src/core/ext/xds/certificate_provider_store.cc +4 -4
  110. data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +4 -7
  111. data/src/core/ext/xds/xds_api.cc +15 -68
  112. data/src/core/ext/xds/xds_api.h +3 -7
  113. data/src/core/ext/xds/xds_bootstrap.h +0 -1
  114. data/src/core/ext/xds/xds_bootstrap_grpc.cc +3 -12
  115. data/src/core/ext/xds/xds_bootstrap_grpc.h +16 -1
  116. data/src/core/ext/xds/xds_certificate_provider.cc +22 -25
  117. data/src/core/ext/xds/xds_channel_stack_modifier.cc +0 -1
  118. data/src/core/ext/xds/xds_client.cc +122 -90
  119. data/src/core/ext/xds/xds_client.h +7 -2
  120. data/src/core/ext/xds/xds_client_grpc.cc +5 -24
  121. data/src/core/ext/xds/xds_cluster.cc +291 -183
  122. data/src/core/ext/xds/xds_cluster.h +11 -15
  123. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +32 -29
  124. data/src/core/ext/xds/xds_cluster_specifier_plugin.h +35 -16
  125. data/src/core/ext/xds/xds_common_types.cc +208 -141
  126. data/src/core/ext/xds/xds_common_types.h +19 -13
  127. data/src/core/ext/xds/xds_endpoint.cc +214 -129
  128. data/src/core/ext/xds/xds_endpoint.h +4 -7
  129. data/src/core/ext/xds/xds_http_fault_filter.cc +56 -43
  130. data/src/core/ext/xds/xds_http_fault_filter.h +13 -21
  131. data/src/core/ext/xds/xds_http_filters.cc +60 -73
  132. data/src/core/ext/xds/xds_http_filters.h +67 -19
  133. data/src/core/ext/xds/xds_http_rbac_filter.cc +152 -207
  134. data/src/core/ext/xds/xds_http_rbac_filter.h +12 -15
  135. data/src/core/ext/xds/xds_lb_policy_registry.cc +122 -169
  136. data/src/core/ext/xds/xds_lb_policy_registry.h +10 -11
  137. data/src/core/ext/xds/xds_listener.cc +459 -417
  138. data/src/core/ext/xds/xds_listener.h +43 -47
  139. data/src/core/ext/xds/xds_resource_type.h +3 -11
  140. data/src/core/ext/xds/xds_resource_type_impl.h +8 -13
  141. data/src/core/ext/xds/xds_route_config.cc +94 -80
  142. data/src/core/ext/xds/xds_route_config.h +10 -10
  143. data/src/core/ext/xds/xds_routing.cc +2 -1
  144. data/src/core/ext/xds/xds_routing.h +2 -0
  145. data/src/core/ext/xds/xds_server_config_fetcher.cc +109 -94
  146. data/src/core/ext/xds/xds_transport_grpc.cc +4 -5
  147. data/src/core/lib/address_utils/parse_address.cc +11 -10
  148. data/src/core/lib/channel/channel_args.h +16 -1
  149. data/src/core/lib/channel/channel_stack.cc +23 -20
  150. data/src/core/lib/channel/channel_stack.h +17 -4
  151. data/src/core/lib/channel/channel_stack_builder.cc +4 -7
  152. data/src/core/lib/channel/channel_stack_builder.h +14 -6
  153. data/src/core/lib/channel/channel_stack_builder_impl.cc +25 -7
  154. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -0
  155. data/src/core/lib/channel/channel_trace.cc +4 -5
  156. data/src/core/lib/channel/channelz.cc +1 -1
  157. data/src/core/lib/channel/connected_channel.cc +695 -35
  158. data/src/core/lib/channel/connected_channel.h +0 -4
  159. data/src/core/lib/channel/promise_based_filter.cc +1004 -140
  160. data/src/core/lib/channel/promise_based_filter.h +364 -87
  161. data/src/core/lib/compression/message_compress.cc +5 -5
  162. data/src/core/lib/debug/event_log.cc +88 -0
  163. data/src/core/lib/debug/event_log.h +81 -0
  164. data/src/core/lib/debug/histogram_view.cc +69 -0
  165. data/src/core/lib/{slice/slice_refcount.cc → debug/histogram_view.h} +15 -13
  166. data/src/core/lib/debug/stats.cc +22 -119
  167. data/src/core/lib/debug/stats.h +29 -35
  168. data/src/core/lib/debug/stats_data.cc +224 -73
  169. data/src/core/lib/debug/stats_data.h +263 -122
  170. data/src/core/lib/event_engine/common_closures.h +71 -0
  171. data/src/core/lib/event_engine/default_event_engine.cc +38 -15
  172. data/src/core/lib/event_engine/default_event_engine.h +15 -3
  173. data/src/core/lib/event_engine/default_event_engine_factory.cc +2 -4
  174. data/src/core/lib/event_engine/memory_allocator.cc +1 -1
  175. data/src/core/lib/event_engine/poller.h +10 -4
  176. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +618 -0
  177. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +129 -0
  178. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +901 -0
  179. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +97 -0
  180. data/src/core/lib/event_engine/posix_engine/event_poller.h +111 -0
  181. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +74 -0
  182. data/src/core/lib/event_engine/{executor/threaded_executor.cc → posix_engine/event_poller_posix_default.h} +13 -16
  183. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +77 -0
  184. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +179 -0
  185. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +267 -0
  186. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +73 -0
  187. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +1270 -0
  188. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +682 -0
  189. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +453 -18
  190. data/src/core/lib/event_engine/posix_engine/posix_engine.h +148 -24
  191. data/src/core/lib/event_engine/posix_engine/posix_engine_closure.h +80 -0
  192. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +1081 -0
  193. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +361 -0
  194. data/src/core/lib/event_engine/posix_engine/timer.h +9 -8
  195. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +57 -194
  196. data/src/core/lib/event_engine/posix_engine/timer_manager.h +21 -49
  197. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +301 -0
  198. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +179 -0
  199. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +126 -0
  200. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +45 -0
  201. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +151 -0
  202. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +45 -0
  203. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +76 -0
  204. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +67 -0
  205. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +37 -0
  206. data/src/core/lib/event_engine/slice.cc +7 -6
  207. data/src/core/lib/event_engine/slice_buffer.cc +2 -2
  208. data/src/core/lib/event_engine/thread_pool.cc +106 -25
  209. data/src/core/lib/event_engine/thread_pool.h +32 -9
  210. data/src/core/lib/event_engine/windows/win_socket.cc +7 -7
  211. data/src/core/lib/event_engine/windows/windows_engine.cc +18 -12
  212. data/src/core/lib/event_engine/windows/windows_engine.h +8 -4
  213. data/src/core/lib/experiments/config.cc +1 -1
  214. data/src/core/lib/experiments/experiments.cc +13 -2
  215. data/src/core/lib/experiments/experiments.h +8 -1
  216. data/src/core/lib/gpr/cpu_linux.cc +6 -2
  217. data/src/core/lib/gpr/log_linux.cc +3 -4
  218. data/src/core/lib/gpr/string.h +1 -1
  219. data/src/core/lib/gpr/tmpfile_posix.cc +3 -2
  220. data/src/core/lib/gprpp/load_file.cc +75 -0
  221. data/src/core/lib/gprpp/load_file.h +33 -0
  222. data/src/core/lib/gprpp/per_cpu.h +46 -0
  223. data/src/core/lib/gprpp/stat_posix.cc +5 -4
  224. data/src/core/lib/gprpp/stat_windows.cc +3 -2
  225. data/src/core/lib/gprpp/status_helper.h +1 -3
  226. data/src/core/lib/gprpp/strerror.cc +41 -0
  227. data/src/core/{ext/xds/xds_resource_type.cc → lib/gprpp/strerror.h} +9 -13
  228. data/src/core/lib/gprpp/thd_windows.cc +1 -2
  229. data/src/core/lib/gprpp/time.cc +3 -4
  230. data/src/core/lib/gprpp/time.h +13 -2
  231. data/src/core/lib/gprpp/validation_errors.h +18 -1
  232. data/src/core/lib/http/httpcli.cc +40 -44
  233. data/src/core/lib/http/httpcli.h +6 -5
  234. data/src/core/lib/http/httpcli_security_connector.cc +4 -6
  235. data/src/core/lib/http/parser.cc +54 -65
  236. data/src/core/lib/iomgr/buffer_list.cc +105 -116
  237. data/src/core/lib/iomgr/buffer_list.h +60 -44
  238. data/src/core/lib/iomgr/call_combiner.cc +11 -10
  239. data/src/core/lib/iomgr/call_combiner.h +3 -4
  240. data/src/core/lib/iomgr/cfstream_handle.cc +13 -16
  241. data/src/core/lib/iomgr/closure.h +49 -5
  242. data/src/core/lib/iomgr/combiner.cc +2 -2
  243. data/src/core/lib/iomgr/endpoint.h +1 -1
  244. data/src/core/lib/iomgr/endpoint_cfstream.cc +26 -25
  245. data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -2
  246. data/src/core/lib/iomgr/error.cc +27 -42
  247. data/src/core/lib/iomgr/error.h +22 -152
  248. data/src/core/lib/iomgr/ev_apple.cc +4 -4
  249. data/src/core/lib/iomgr/ev_epoll1_linux.cc +26 -25
  250. data/src/core/lib/iomgr/ev_poll_posix.cc +27 -31
  251. data/src/core/lib/iomgr/exec_ctx.cc +3 -4
  252. data/src/core/lib/iomgr/exec_ctx.h +2 -3
  253. data/src/core/lib/iomgr/executor.cc +1 -2
  254. data/src/core/lib/iomgr/internal_errqueue.cc +3 -1
  255. data/src/core/lib/iomgr/iocp_windows.cc +1 -0
  256. data/src/core/lib/iomgr/iomgr_posix.cc +2 -2
  257. data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +2 -1
  258. data/src/core/lib/iomgr/iomgr_windows.cc +2 -1
  259. data/src/core/lib/iomgr/load_file.cc +5 -9
  260. data/src/core/lib/iomgr/lockfree_event.cc +10 -10
  261. data/src/core/lib/iomgr/pollset_windows.cc +4 -4
  262. data/src/core/lib/iomgr/python_util.h +2 -2
  263. data/src/core/lib/iomgr/resolve_address.cc +8 -3
  264. data/src/core/lib/iomgr/resolve_address.h +3 -4
  265. data/src/core/lib/iomgr/resolve_address_impl.h +1 -1
  266. data/src/core/lib/iomgr/resolve_address_posix.cc +14 -25
  267. data/src/core/lib/iomgr/resolve_address_posix.h +1 -2
  268. data/src/core/lib/iomgr/resolve_address_windows.cc +14 -17
  269. data/src/core/lib/iomgr/resolve_address_windows.h +1 -2
  270. data/src/core/lib/iomgr/socket_utils_common_posix.cc +30 -29
  271. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -0
  272. data/src/core/lib/iomgr/socket_utils_posix.h +2 -2
  273. data/src/core/lib/iomgr/socket_windows.cc +2 -2
  274. data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -10
  275. data/src/core/lib/iomgr/tcp_client_posix.cc +31 -35
  276. data/src/core/lib/iomgr/tcp_client_windows.cc +8 -12
  277. data/src/core/lib/iomgr/tcp_posix.cc +92 -108
  278. data/src/core/lib/iomgr/tcp_server_posix.cc +34 -34
  279. data/src/core/lib/iomgr/tcp_server_utils_posix.h +1 -1
  280. data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +18 -21
  281. data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +12 -13
  282. data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc +1 -1
  283. data/src/core/lib/iomgr/tcp_server_windows.cc +26 -29
  284. data/src/core/lib/iomgr/tcp_windows.cc +27 -34
  285. data/src/core/lib/iomgr/timer.h +8 -8
  286. data/src/core/lib/iomgr/timer_generic.cc +9 -15
  287. data/src/core/lib/iomgr/unix_sockets_posix.cc +2 -4
  288. data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +4 -3
  289. data/src/core/lib/iomgr/wakeup_fd_pipe.cc +10 -8
  290. data/src/core/lib/json/json_channel_args.h +42 -0
  291. data/src/core/lib/json/json_object_loader.cc +7 -2
  292. data/src/core/lib/json/json_object_loader.h +22 -0
  293. data/src/core/lib/json/json_util.cc +5 -5
  294. data/src/core/lib/json/json_util.h +4 -4
  295. data/src/core/lib/load_balancing/lb_policy.cc +1 -1
  296. data/src/core/lib/load_balancing/lb_policy.h +4 -0
  297. data/src/core/lib/load_balancing/subchannel_interface.h +0 -7
  298. data/src/core/lib/matchers/matchers.cc +3 -4
  299. data/src/core/lib/promise/activity.cc +16 -2
  300. data/src/core/lib/promise/activity.h +38 -15
  301. data/src/core/lib/promise/arena_promise.h +80 -51
  302. data/src/core/lib/promise/context.h +13 -6
  303. data/src/core/lib/promise/detail/basic_seq.h +9 -28
  304. data/src/core/lib/promise/detail/promise_factory.h +58 -10
  305. data/src/core/lib/promise/detail/status.h +28 -0
  306. data/src/core/lib/promise/detail/switch.h +1455 -0
  307. data/src/core/lib/promise/exec_ctx_wakeup_scheduler.h +3 -1
  308. data/src/core/lib/promise/for_each.h +129 -0
  309. data/src/core/lib/promise/loop.h +7 -5
  310. data/src/core/lib/promise/map_pipe.h +87 -0
  311. data/src/core/lib/promise/pipe.cc +19 -0
  312. data/src/core/lib/promise/pipe.h +505 -0
  313. data/src/core/lib/promise/poll.h +13 -0
  314. data/src/core/lib/promise/seq.h +3 -5
  315. data/src/core/lib/promise/sleep.cc +5 -4
  316. data/src/core/lib/promise/sleep.h +1 -2
  317. data/src/core/lib/promise/try_concurrently.h +341 -0
  318. data/src/core/lib/promise/try_seq.h +10 -13
  319. data/src/core/lib/resolver/server_address.cc +1 -0
  320. data/src/core/lib/resolver/server_address.h +1 -3
  321. data/src/core/lib/resource_quota/api.cc +0 -1
  322. data/src/core/lib/resource_quota/arena.cc +19 -0
  323. data/src/core/lib/resource_quota/arena.h +89 -0
  324. data/src/core/lib/resource_quota/memory_quota.cc +1 -0
  325. data/src/core/lib/security/authorization/grpc_authorization_engine.cc +1 -3
  326. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +4 -2
  327. data/src/core/lib/security/authorization/matchers.cc +25 -22
  328. data/src/core/lib/security/authorization/rbac_policy.cc +2 -3
  329. data/src/core/lib/security/context/security_context.h +10 -0
  330. data/src/core/lib/security/credentials/channel_creds_registry_init.cc +3 -4
  331. data/src/core/lib/security/credentials/composite/composite_credentials.cc +1 -1
  332. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +77 -55
  333. data/src/core/lib/security/credentials/external/aws_request_signer.cc +4 -3
  334. data/src/core/lib/security/credentials/external/external_account_credentials.cc +40 -51
  335. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +17 -21
  336. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +21 -25
  337. data/src/core/lib/security/credentials/fake/fake_credentials.cc +1 -0
  338. data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +27 -24
  339. data/src/core/lib/security/credentials/iam/iam_credentials.cc +1 -0
  340. data/src/core/lib/security/credentials/jwt/json_token.cc +1 -2
  341. data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +1 -1
  342. data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +5 -5
  343. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +24 -30
  344. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +6 -5
  345. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +3 -3
  346. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +19 -27
  347. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +4 -11
  348. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +29 -41
  349. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc +1 -1
  350. data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +6 -11
  351. data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +8 -15
  352. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.cc +2 -2
  353. data/src/core/lib/security/security_connector/insecure/insecure_security_connector.h +2 -6
  354. data/src/core/lib/security/security_connector/load_system_roots_supported.cc +1 -4
  355. data/src/core/lib/security/security_connector/local/local_security_connector.cc +7 -11
  356. data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +9 -14
  357. data/src/core/lib/security/security_connector/ssl_utils.cc +5 -7
  358. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +21 -27
  359. data/src/core/lib/security/transport/client_auth_filter.cc +1 -1
  360. data/src/core/lib/security/transport/secure_endpoint.cc +26 -28
  361. data/src/core/lib/security/transport/security_handshaker.cc +53 -53
  362. data/src/core/lib/security/transport/server_auth_filter.cc +21 -21
  363. data/src/core/lib/security/transport/tsi_error.cc +6 -3
  364. data/src/core/lib/security/util/json_util.cc +4 -5
  365. data/src/core/lib/service_config/service_config.h +1 -1
  366. data/src/core/lib/service_config/service_config_impl.cc +111 -158
  367. data/src/core/lib/service_config/service_config_impl.h +14 -17
  368. data/src/core/lib/service_config/service_config_parser.cc +14 -31
  369. data/src/core/lib/service_config/service_config_parser.h +14 -10
  370. data/src/core/lib/slice/b64.cc +2 -2
  371. data/src/core/lib/slice/slice.cc +7 -1
  372. data/src/core/lib/slice/slice.h +19 -6
  373. data/src/core/lib/slice/slice_buffer.cc +13 -14
  374. data/src/core/lib/slice/slice_internal.h +13 -21
  375. data/src/core/lib/slice/slice_refcount.h +34 -19
  376. data/src/core/lib/surface/byte_buffer.cc +3 -4
  377. data/src/core/lib/surface/byte_buffer_reader.cc +4 -4
  378. data/src/core/lib/surface/call.cc +1366 -239
  379. data/src/core/lib/surface/call.h +44 -0
  380. data/src/core/lib/surface/call_details.cc +3 -3
  381. data/src/core/lib/surface/call_trace.cc +113 -0
  382. data/src/core/lib/surface/call_trace.h +30 -0
  383. data/src/core/lib/surface/channel.cc +44 -49
  384. data/src/core/lib/surface/channel.h +9 -1
  385. data/src/core/lib/surface/channel_ping.cc +1 -1
  386. data/src/core/lib/surface/channel_stack_type.cc +4 -0
  387. data/src/core/lib/surface/channel_stack_type.h +2 -0
  388. data/src/core/lib/surface/completion_queue.cc +38 -52
  389. data/src/core/lib/surface/init.cc +8 -39
  390. data/src/core/lib/surface/init_internally.h +8 -0
  391. data/src/core/lib/surface/lame_client.cc +10 -8
  392. data/src/core/lib/surface/server.cc +48 -70
  393. data/src/core/lib/surface/server.h +3 -4
  394. data/src/core/lib/surface/validate_metadata.cc +11 -12
  395. data/src/core/lib/surface/version.cc +2 -2
  396. data/src/core/lib/transport/connectivity_state.cc +2 -2
  397. data/src/core/lib/transport/error_utils.cc +34 -28
  398. data/src/core/lib/transport/error_utils.h +3 -3
  399. data/src/core/lib/transport/handshaker.cc +14 -14
  400. data/src/core/lib/transport/handshaker.h +1 -1
  401. data/src/core/lib/transport/handshaker_factory.h +26 -0
  402. data/src/core/lib/transport/handshaker_registry.cc +8 -2
  403. data/src/core/lib/transport/handshaker_registry.h +3 -4
  404. data/src/core/lib/transport/http_connect_handshaker.cc +23 -24
  405. data/src/core/lib/transport/metadata_batch.h +17 -1
  406. data/src/core/lib/transport/parsed_metadata.cc +2 -6
  407. data/src/core/lib/transport/tcp_connect_handshaker.cc +15 -20
  408. data/src/core/lib/transport/transport.cc +63 -17
  409. data/src/core/lib/transport/transport.h +64 -68
  410. data/src/core/lib/transport/transport_impl.h +1 -1
  411. data/src/core/lib/transport/transport_op_string.cc +7 -6
  412. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -10
  413. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -14
  414. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +10 -10
  415. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +8 -8
  416. data/src/core/tsi/alts/handshaker/alts_tsi_utils.cc +2 -1
  417. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_integrity_only_record_protocol.cc +7 -7
  418. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_protocol.cc +7 -6
  419. data/src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc +1 -1
  420. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +5 -5
  421. data/src/core/tsi/fake_transport_security.cc +3 -3
  422. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +7 -3
  423. data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +1 -1
  424. data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +6 -2
  425. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +0 -2
  426. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +0 -3
  427. data/src/ruby/lib/grpc/version.rb +1 -1
  428. data/src/ruby/spec/channel_spec.rb +0 -43
  429. data/src/ruby/spec/generic/active_call_spec.rb +12 -3
  430. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +140 -0
  431. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +100 -0
  432. data/third_party/zlib/compress.c +3 -3
  433. data/third_party/zlib/crc32.c +21 -12
  434. data/third_party/zlib/deflate.c +112 -106
  435. data/third_party/zlib/deflate.h +2 -2
  436. data/third_party/zlib/gzlib.c +1 -1
  437. data/third_party/zlib/gzread.c +3 -5
  438. data/third_party/zlib/gzwrite.c +1 -1
  439. data/third_party/zlib/infback.c +10 -7
  440. data/third_party/zlib/inflate.c +5 -2
  441. data/third_party/zlib/inftrees.c +2 -2
  442. data/third_party/zlib/inftrees.h +1 -1
  443. data/third_party/zlib/trees.c +61 -62
  444. data/third_party/zlib/uncompr.c +2 -2
  445. data/third_party/zlib/zconf.h +16 -3
  446. data/third_party/zlib/zlib.h +10 -10
  447. data/third_party/zlib/zutil.c +9 -7
  448. data/third_party/zlib/zutil.h +1 -0
  449. metadata +55 -18
  450. data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +0 -188
  451. data/src/core/ext/filters/fault_injection/service_config_parser.cc +0 -187
  452. data/src/core/lib/event_engine/executor/threaded_executor.h +0 -44
  453. data/src/core/lib/gpr/murmur_hash.cc +0 -82
  454. data/src/core/lib/gpr/murmur_hash.h +0 -29
  455. data/src/core/lib/gpr/tls.h +0 -156
  456. data/src/core/lib/promise/call_push_pull.h +0 -148
  457. data/src/core/lib/slice/slice_api.cc +0 -39
  458. data/src/core/lib/slice/slice_buffer_api.cc +0 -35
  459. data/src/core/lib/slice/slice_refcount_base.h +0 -60
@@ -20,24 +20,31 @@
20
20
 
21
21
  #include "src/core/lib/surface/call.h"
22
22
 
23
+ #include <inttypes.h>
23
24
  #include <limits.h>
24
25
  #include <stdlib.h>
25
26
 
26
27
  #include <algorithm>
27
28
  #include <atomic>
29
+ #include <memory>
28
30
  #include <new>
29
31
  #include <string>
30
32
  #include <utility>
33
+ #include <vector>
31
34
 
32
35
  #include "absl/base/thread_annotations.h"
36
+ #include "absl/cleanup/cleanup.h"
33
37
  #include "absl/meta/type_traits.h"
34
38
  #include "absl/status/status.h"
35
39
  #include "absl/strings/str_cat.h"
36
40
  #include "absl/strings/str_format.h"
41
+ #include "absl/strings/str_join.h"
37
42
  #include "absl/strings/string_view.h"
43
+ #include "absl/types/variant.h"
38
44
 
39
45
  #include <grpc/byte_buffer.h>
40
46
  #include <grpc/compression.h>
47
+ #include <grpc/event_engine/event_engine.h>
41
48
  #include <grpc/grpc.h>
42
49
  #include <grpc/impl/codegen/gpr_types.h>
43
50
  #include <grpc/impl/codegen/propagation_bits.h>
@@ -49,24 +56,37 @@
49
56
  #include <grpc/support/log.h>
50
57
  #include <grpc/support/string_util.h>
51
58
 
59
+ #include "src/core/lib/channel/call_finalization.h"
52
60
  #include "src/core/lib/channel/channel_stack.h"
53
61
  #include "src/core/lib/channel/channelz.h"
54
62
  #include "src/core/lib/channel/context.h"
63
+ #include "src/core/lib/channel/status_util.h"
55
64
  #include "src/core/lib/compression/compression_internal.h"
56
65
  #include "src/core/lib/debug/stats.h"
66
+ #include "src/core/lib/debug/stats_data.h"
67
+ #include "src/core/lib/experiments/experiments.h"
57
68
  #include "src/core/lib/gpr/alloc.h"
58
69
  #include "src/core/lib/gpr/time_precise.h"
70
+ #include "src/core/lib/gpr/useful.h"
71
+ #include "src/core/lib/gprpp/bitset.h"
59
72
  #include "src/core/lib/gprpp/cpp_impl_of.h"
60
73
  #include "src/core/lib/gprpp/debug_location.h"
61
74
  #include "src/core/lib/gprpp/ref_counted.h"
75
+ #include "src/core/lib/gprpp/ref_counted_ptr.h"
76
+ #include "src/core/lib/gprpp/status_helper.h"
62
77
  #include "src/core/lib/gprpp/sync.h"
63
78
  #include "src/core/lib/iomgr/call_combiner.h"
64
79
  #include "src/core/lib/iomgr/exec_ctx.h"
65
80
  #include "src/core/lib/iomgr/polling_entity.h"
81
+ #include "src/core/lib/promise/activity.h"
82
+ #include "src/core/lib/promise/arena_promise.h"
83
+ #include "src/core/lib/promise/context.h"
84
+ #include "src/core/lib/promise/latch.h"
85
+ #include "src/core/lib/promise/pipe.h"
86
+ #include "src/core/lib/promise/poll.h"
66
87
  #include "src/core/lib/resource_quota/arena.h"
67
88
  #include "src/core/lib/slice/slice_buffer.h"
68
89
  #include "src/core/lib/slice/slice_internal.h"
69
- #include "src/core/lib/slice/slice_refcount.h"
70
90
  #include "src/core/lib/surface/api_trace.h"
71
91
  #include "src/core/lib/surface/call_test_only.h"
72
92
  #include "src/core/lib/surface/channel.h"
@@ -79,9 +99,14 @@
79
99
 
80
100
  grpc_core::TraceFlag grpc_call_error_trace(false, "call_error");
81
101
  grpc_core::TraceFlag grpc_compression_trace(false, "compression");
102
+ grpc_core::TraceFlag grpc_call_trace(false, "call");
103
+ grpc_core::TraceFlag grpc_call_refcount_trace(false, "call_refcount");
82
104
 
83
105
  namespace grpc_core {
84
106
 
107
+ ///////////////////////////////////////////////////////////////////////////////
108
+ // Call
109
+
85
110
  class Call : public CppImplOf<Call, grpc_call> {
86
111
  public:
87
112
  Arena* arena() { return arena_; }
@@ -94,7 +119,7 @@ class Call : public CppImplOf<Call, grpc_call> {
94
119
  void CancelWithStatus(grpc_status_code status, const char* description);
95
120
  virtual void CancelWithError(grpc_error_handle error) = 0;
96
121
  virtual void SetCompletionQueue(grpc_completion_queue* cq) = 0;
97
- virtual char* GetPeer() = 0;
122
+ char* GetPeer();
98
123
  virtual grpc_call_error StartBatch(const grpc_op* ops, size_t nops,
99
124
  void* notify_tag,
100
125
  bool is_notify_tag_closure) = 0;
@@ -116,12 +141,19 @@ class Call : public CppImplOf<Call, grpc_call> {
116
141
  // for that functionality be invented)
117
142
  virtual grpc_call_stack* call_stack() = 0;
118
143
 
144
+ gpr_atm* peer_string_atm_ptr() { return &peer_string_; }
145
+
119
146
  protected:
120
- Call(Arena* arena, bool is_client, Timestamp send_deadline)
121
- : arena_(arena), send_deadline_(send_deadline), is_client_(is_client) {
122
- GPR_DEBUG_ASSERT(arena_ != nullptr);
123
- }
124
- ~Call() = default;
147
+ // The maximum number of concurrent batches possible.
148
+ // Based upon the maximum number of individually queueable ops in the batch
149
+ // api:
150
+ // - initial metadata send
151
+ // - message send
152
+ // - status/close send (depending on client/server)
153
+ // - initial metadata recv
154
+ // - message recv
155
+ // - status/close recv (depending on client/server)
156
+ static constexpr size_t kMaxConcurrentBatches = 6;
125
157
 
126
158
  struct ParentCall {
127
159
  Mutex child_list_mu;
@@ -138,8 +170,25 @@ class Call : public CppImplOf<Call, grpc_call> {
138
170
  Call* sibling_prev = nullptr;
139
171
  };
140
172
 
173
+ Call(Arena* arena, bool is_client, Timestamp send_deadline,
174
+ RefCountedPtr<Channel> channel)
175
+ : channel_(std::move(channel)),
176
+ arena_(arena),
177
+ send_deadline_(send_deadline),
178
+ is_client_(is_client) {
179
+ GPR_DEBUG_ASSERT(arena_ != nullptr);
180
+ GPR_DEBUG_ASSERT(channel_ != nullptr);
181
+ }
182
+ virtual ~Call() = default;
183
+
184
+ void DeleteThis();
185
+
141
186
  ParentCall* GetOrCreateParentCall();
142
187
  ParentCall* parent_call();
188
+ Channel* channel() {
189
+ GPR_DEBUG_ASSERT(channel_ != nullptr);
190
+ return channel_.get();
191
+ }
143
192
 
144
193
  absl::Status InitParent(Call* parent, uint32_t propagation_mask);
145
194
  void PublishToParent(Call* parent);
@@ -151,7 +200,10 @@ class Call : public CppImplOf<Call, grpc_call> {
151
200
  send_deadline_ = send_deadline;
152
201
  }
153
202
 
203
+ void ClearPeerString() { gpr_atm_rel_store(&peer_string_, 0); }
204
+
154
205
  private:
206
+ RefCountedPtr<Channel> channel_;
155
207
  Arena* const arena_;
156
208
  std::atomic<ParentCall*> parent_call_{nullptr};
157
209
  ChildCall* child_ = nullptr;
@@ -159,11 +211,150 @@ class Call : public CppImplOf<Call, grpc_call> {
159
211
  const bool is_client_;
160
212
  // flag indicating that cancellation is inherited
161
213
  bool cancellation_is_inherited_ = false;
214
+ // A char* indicating the peer name.
215
+ gpr_atm peer_string_ = 0;
162
216
  };
163
217
 
218
+ Call::ParentCall* Call::GetOrCreateParentCall() {
219
+ ParentCall* p = parent_call_.load(std::memory_order_acquire);
220
+ if (p == nullptr) {
221
+ p = arena_->New<ParentCall>();
222
+ ParentCall* expected = nullptr;
223
+ if (!parent_call_.compare_exchange_strong(expected, p,
224
+ std::memory_order_release,
225
+ std::memory_order_relaxed)) {
226
+ p->~ParentCall();
227
+ p = expected;
228
+ }
229
+ }
230
+ return p;
231
+ }
232
+
233
+ Call::ParentCall* Call::parent_call() {
234
+ return parent_call_.load(std::memory_order_acquire);
235
+ }
236
+
237
+ absl::Status Call::InitParent(Call* parent, uint32_t propagation_mask) {
238
+ child_ = arena()->New<ChildCall>(parent);
239
+
240
+ parent->InternalRef("child");
241
+ GPR_ASSERT(is_client_);
242
+ GPR_ASSERT(!parent->is_client_);
243
+
244
+ if (propagation_mask & GRPC_PROPAGATE_DEADLINE) {
245
+ send_deadline_ = std::min(send_deadline_, parent->send_deadline_);
246
+ }
247
+ /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
248
+ * GRPC_PROPAGATE_STATS_CONTEXT */
249
+ /* TODO(ctiller): This should change to use the appropriate census start_op
250
+ * call. */
251
+ if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
252
+ if (0 == (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
253
+ return absl::UnknownError(
254
+ "Census tracing propagation requested without Census context "
255
+ "propagation");
256
+ }
257
+ ContextSet(GRPC_CONTEXT_TRACING, parent->ContextGet(GRPC_CONTEXT_TRACING),
258
+ nullptr);
259
+ } else if (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
260
+ return absl::UnknownError(
261
+ "Census context propagation requested without Census tracing "
262
+ "propagation");
263
+ }
264
+ if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
265
+ cancellation_is_inherited_ = true;
266
+ }
267
+ return absl::OkStatus();
268
+ }
269
+
270
+ void Call::PublishToParent(Call* parent) {
271
+ ChildCall* cc = child_;
272
+ ParentCall* pc = parent->GetOrCreateParentCall();
273
+ MutexLock lock(&pc->child_list_mu);
274
+ if (pc->first_child == nullptr) {
275
+ pc->first_child = this;
276
+ cc->sibling_next = cc->sibling_prev = this;
277
+ } else {
278
+ cc->sibling_next = pc->first_child;
279
+ cc->sibling_prev = pc->first_child->child_->sibling_prev;
280
+ cc->sibling_next->child_->sibling_prev =
281
+ cc->sibling_prev->child_->sibling_next = this;
282
+ }
283
+ if (parent->Completed()) {
284
+ CancelWithError(absl::CancelledError());
285
+ }
286
+ }
287
+
288
+ void Call::MaybeUnpublishFromParent() {
289
+ ChildCall* cc = child_;
290
+ if (cc == nullptr) return;
291
+
292
+ ParentCall* pc = cc->parent->parent_call();
293
+ {
294
+ MutexLock lock(&pc->child_list_mu);
295
+ if (this == pc->first_child) {
296
+ pc->first_child = cc->sibling_next;
297
+ if (this == pc->first_child) {
298
+ pc->first_child = nullptr;
299
+ }
300
+ }
301
+ cc->sibling_prev->child_->sibling_next = cc->sibling_next;
302
+ cc->sibling_next->child_->sibling_prev = cc->sibling_prev;
303
+ }
304
+ cc->parent->InternalUnref("child");
305
+ }
306
+
307
+ void Call::CancelWithStatus(grpc_status_code status, const char* description) {
308
+ // copying 'description' is needed to ensure the grpc_call_cancel_with_status
309
+ // guarantee that can be short-lived.
310
+ CancelWithError(grpc_error_set_int(
311
+ grpc_error_set_str(GRPC_ERROR_CREATE(description),
312
+ StatusStrProperty::kGrpcMessage, description),
313
+ StatusIntProperty::kRpcStatus, status));
314
+ }
315
+
316
+ void Call::PropagateCancellationToChildren() {
317
+ ParentCall* pc = parent_call();
318
+ if (pc != nullptr) {
319
+ Call* child;
320
+ MutexLock lock(&pc->child_list_mu);
321
+ child = pc->first_child;
322
+ if (child != nullptr) {
323
+ do {
324
+ Call* next_child_call = child->child_->sibling_next;
325
+ if (child->cancellation_is_inherited_) {
326
+ child->InternalRef("propagate_cancel");
327
+ child->CancelWithError(absl::CancelledError());
328
+ child->InternalUnref("propagate_cancel");
329
+ }
330
+ child = next_child_call;
331
+ } while (child != pc->first_child);
332
+ }
333
+ }
334
+ }
335
+
336
+ char* Call::GetPeer() {
337
+ char* peer_string = reinterpret_cast<char*>(gpr_atm_acq_load(&peer_string_));
338
+ if (peer_string != nullptr) return gpr_strdup(peer_string);
339
+ peer_string = grpc_channel_get_target(channel_->c_ptr());
340
+ if (peer_string != nullptr) return peer_string;
341
+ return gpr_strdup("unknown");
342
+ }
343
+
344
+ void Call::DeleteThis() {
345
+ RefCountedPtr<Channel> channel = std::move(channel_);
346
+ Arena* arena = arena_;
347
+ this->~Call();
348
+ channel->UpdateCallSizeEstimate(arena->Destroy());
349
+ }
350
+
351
+ ///////////////////////////////////////////////////////////////////////////////
352
+ // FilterStackCall
353
+ // To be removed once promise conversion is complete
354
+
164
355
  class FilterStackCall final : public Call {
165
356
  public:
166
- ~FilterStackCall() {
357
+ ~FilterStackCall() override {
167
358
  for (int i = 0; i < GRPC_CONTEXT_COUNT; ++i) {
168
359
  if (context_[i].destroy) {
169
360
  context_[i].destroy(context_[i].value);
@@ -198,7 +389,6 @@ class FilterStackCall final : public Call {
198
389
 
199
390
  void CancelWithError(grpc_error_handle error) override;
200
391
  void SetCompletionQueue(grpc_completion_queue* cq) override;
201
- char* GetPeer() override;
202
392
  grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
203
393
  bool is_notify_tag_closure) override;
204
394
  void ExternalRef() override { ext_ref_.Ref(); }
@@ -256,17 +446,6 @@ class FilterStackCall final : public Call {
256
446
  }
257
447
 
258
448
  private:
259
- // The maximum number of concurrent batches possible.
260
- // Based upon the maximum number of individually queueable ops in the batch
261
- // api:
262
- // - initial metadata send
263
- // - message send
264
- // - status/close send (depending on client/server)
265
- // - initial metadata recv
266
- // - message recv
267
- // - status/close recv (depending on client/server)
268
- static constexpr size_t kMaxConcurrentBatches = 6;
269
-
270
449
  static constexpr gpr_atm kRecvNone = 0;
271
450
  static constexpr gpr_atm kRecvInitialMetadataFirst = 1;
272
451
 
@@ -314,9 +493,9 @@ class FilterStackCall final : public Call {
314
493
  };
315
494
 
316
495
  FilterStackCall(Arena* arena, const grpc_call_create_args& args)
317
- : Call(arena, args.server_transport_data == nullptr, args.send_deadline),
496
+ : Call(arena, args.server_transport_data == nullptr, args.send_deadline,
497
+ args.channel->Ref()),
318
498
  cq_(args.cq),
319
- channel_(args.channel->Ref()),
320
499
  stream_op_payload_(context_) {}
321
500
 
322
501
  static void ReleaseCall(void* call, grpc_error_handle);
@@ -347,7 +526,6 @@ class FilterStackCall final : public Call {
347
526
  CallCombiner call_combiner_;
348
527
  grpc_completion_queue* cq_;
349
528
  grpc_polling_entity pollent_;
350
- RefCountedPtr<Channel> channel_;
351
529
  gpr_cycle_counter start_time_ = gpr_get_cycle_counter();
352
530
 
353
531
  /** has grpc_call_unref been called */
@@ -376,9 +554,6 @@ class FilterStackCall final : public Call {
376
554
  Element 0 is initial metadata, element 1 is trailing metadata. */
377
555
  grpc_metadata_array* buffered_metadata_[2] = {};
378
556
 
379
- // A char* indicating the peer name.
380
- gpr_atm peer_string_ = 0;
381
-
382
557
  /* Call data useful used for reporting. Only valid after the call has
383
558
  * completed */
384
559
  grpc_call_final_info final_info_;
@@ -443,95 +618,25 @@ class FilterStackCall final : public Call {
443
618
  gpr_atm recv_state_ = 0;
444
619
  };
445
620
 
446
- Call::ParentCall* Call::GetOrCreateParentCall() {
447
- ParentCall* p = parent_call_.load(std::memory_order_acquire);
448
- if (p == nullptr) {
449
- p = arena_->New<ParentCall>();
450
- ParentCall* expected = nullptr;
451
- if (!parent_call_.compare_exchange_strong(expected, p,
452
- std::memory_order_release,
453
- std::memory_order_relaxed)) {
454
- p->~ParentCall();
455
- p = expected;
456
- }
457
- }
458
- return p;
459
- }
460
-
461
- Call::ParentCall* Call::parent_call() {
462
- return parent_call_.load(std::memory_order_acquire);
463
- }
464
-
465
- absl::Status Call::InitParent(Call* parent, uint32_t propagation_mask) {
466
- child_ = arena()->New<ChildCall>(parent);
467
-
468
- parent->InternalRef("child");
469
- GPR_ASSERT(is_client_);
470
- GPR_ASSERT(!parent->is_client_);
471
-
472
- if (propagation_mask & GRPC_PROPAGATE_DEADLINE) {
473
- send_deadline_ = std::min(send_deadline_, parent->send_deadline_);
474
- }
475
- /* for now GRPC_PROPAGATE_TRACING_CONTEXT *MUST* be passed with
476
- * GRPC_PROPAGATE_STATS_CONTEXT */
477
- /* TODO(ctiller): This should change to use the appropriate census start_op
478
- * call. */
479
- if (propagation_mask & GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT) {
480
- if (0 == (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT)) {
481
- return absl::UnknownError(
482
- "Census tracing propagation requested without Census context "
483
- "propagation");
484
- }
485
- ContextSet(GRPC_CONTEXT_TRACING, parent->ContextGet(GRPC_CONTEXT_TRACING),
486
- nullptr);
487
- } else if (propagation_mask & GRPC_PROPAGATE_CENSUS_STATS_CONTEXT) {
488
- return absl::UnknownError(
489
- "Census context propagation requested without Census tracing "
490
- "propagation");
491
- }
492
- if (propagation_mask & GRPC_PROPAGATE_CANCELLATION) {
493
- cancellation_is_inherited_ = true;
494
- }
495
- return absl::OkStatus();
496
- }
497
-
498
- void Call::PublishToParent(Call* parent) {
499
- ChildCall* cc = child_;
500
- ParentCall* pc = parent->GetOrCreateParentCall();
501
- MutexLock lock(&pc->child_list_mu);
502
- if (pc->first_child == nullptr) {
503
- pc->first_child = this;
504
- cc->sibling_next = cc->sibling_prev = this;
505
- } else {
506
- cc->sibling_next = pc->first_child;
507
- cc->sibling_prev = pc->first_child->child_->sibling_prev;
508
- cc->sibling_next->child_->sibling_prev =
509
- cc->sibling_prev->child_->sibling_next = this;
510
- }
511
- if (parent->Completed()) {
512
- CancelWithError(GRPC_ERROR_CANCELLED);
513
- }
514
- }
515
-
516
621
  grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
517
622
  grpc_call** out_call) {
518
623
  Channel* channel = args->channel.get();
519
624
 
520
625
  auto add_init_error = [](grpc_error_handle* composite,
521
626
  grpc_error_handle new_err) {
522
- if (GRPC_ERROR_IS_NONE(new_err)) return;
523
- if (GRPC_ERROR_IS_NONE(*composite)) {
524
- *composite = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Call creation failed");
627
+ if (new_err.ok()) return;
628
+ if (composite->ok()) {
629
+ *composite = GRPC_ERROR_CREATE("Call creation failed");
525
630
  }
526
631
  *composite = grpc_error_add_child(*composite, new_err);
527
632
  };
528
633
 
529
634
  Arena* arena;
530
635
  FilterStackCall* call;
531
- grpc_error_handle error = GRPC_ERROR_NONE;
636
+ grpc_error_handle error;
532
637
  grpc_channel_stack* channel_stack = channel->channel_stack();
533
638
  size_t initial_size = channel->CallSizeEstimate();
534
- GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size);
639
+ global_stats().IncrementCallInitialSize(initial_size);
535
640
  size_t call_alloc_size =
536
641
  GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(FilterStackCall)) +
537
642
  channel_stack->call_stack_size;
@@ -548,8 +653,8 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
548
653
  call->final_op_.client.status_details = nullptr;
549
654
  call->final_op_.client.status = nullptr;
550
655
  call->final_op_.client.error_string = nullptr;
551
- GRPC_STATS_INC_CLIENT_CALLS_CREATED();
552
- path = grpc_slice_ref_internal(args->path->c_slice());
656
+ global_stats().IncrementClientCallsCreated();
657
+ path = CSliceRef(args->path->c_slice());
553
658
  call->send_initial_metadata_.Set(HttpPathMetadata(),
554
659
  std::move(*args->path));
555
660
  if (args->authority.has_value()) {
@@ -557,7 +662,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
557
662
  std::move(*args->authority));
558
663
  }
559
664
  } else {
560
- GRPC_STATS_INC_SERVER_CALLS_CREATED();
665
+ global_stats().IncrementServerCallsCreated();
561
666
  call->final_op_.server.cancelled = nullptr;
562
667
  call->final_op_.server.core_server = args->server;
563
668
  }
@@ -580,8 +685,8 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
580
685
  call->PublishToParent(parent);
581
686
  }
582
687
 
583
- if (!GRPC_ERROR_IS_NONE(error)) {
584
- call->CancelWithError(GRPC_ERROR_REF(error));
688
+ if (!error.ok()) {
689
+ call->CancelWithError(error);
585
690
  }
586
691
  if (args->cq != nullptr) {
587
692
  GPR_ASSERT(args->pollset_set_alternative == nullptr &&
@@ -613,7 +718,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
613
718
  }
614
719
  }
615
720
 
616
- grpc_slice_unref_internal(path);
721
+ CSliceUnref(path);
617
722
 
618
723
  return error;
619
724
  }
@@ -632,11 +737,7 @@ void FilterStackCall::SetCompletionQueue(grpc_completion_queue* cq) {
632
737
  }
633
738
 
634
739
  void FilterStackCall::ReleaseCall(void* call, grpc_error_handle /*error*/) {
635
- auto* c = static_cast<FilterStackCall*>(call);
636
- RefCountedPtr<Channel> channel = std::move(c->channel_);
637
- Arena* arena = c->arena();
638
- c->~FilterStackCall();
639
- channel->UpdateCallSizeEstimate(arena->Destroy());
740
+ static_cast<FilterStackCall*>(call)->DeleteThis();
640
741
  }
641
742
 
642
743
  void FilterStackCall::DestroyCall(void* call, grpc_error_handle /*error*/) {
@@ -656,7 +757,7 @@ void FilterStackCall::DestroyCall(void* call, grpc_error_handle /*error*/) {
656
757
  grpc_error_get_status(status_error, c->send_deadline(),
657
758
  &c->final_info_.final_status, nullptr, nullptr,
658
759
  &(c->final_info_.error_string));
659
- c->status_error_.set(GRPC_ERROR_NONE);
760
+ c->status_error_.set(absl::OkStatus());
660
761
  c->final_info_.stats.latency =
661
762
  gpr_cycle_counter_sub(gpr_get_cycle_counter(), c->start_time_);
662
763
  grpc_call_stack_destroy(c->call_stack(), &c->final_info_,
@@ -664,25 +765,6 @@ void FilterStackCall::DestroyCall(void* call, grpc_error_handle /*error*/) {
664
765
  grpc_schedule_on_exec_ctx));
665
766
  }
666
767
 
667
- void Call::MaybeUnpublishFromParent() {
668
- ChildCall* cc = child_;
669
- if (cc == nullptr) return;
670
-
671
- ParentCall* pc = cc->parent->parent_call();
672
- {
673
- MutexLock lock(&pc->child_list_mu);
674
- if (this == pc->first_child) {
675
- pc->first_child = cc->sibling_next;
676
- if (this == pc->first_child) {
677
- pc->first_child = nullptr;
678
- }
679
- }
680
- cc->sibling_prev->child_->sibling_next = cc->sibling_next;
681
- cc->sibling_next->child_->sibling_prev = cc->sibling_prev;
682
- }
683
- cc->parent->InternalUnref("child");
684
- }
685
-
686
768
  void FilterStackCall::ExternalUnref() {
687
769
  if (GPR_LIKELY(!ext_ref_.Unref())) return;
688
770
 
@@ -697,7 +779,7 @@ void FilterStackCall::ExternalUnref() {
697
779
  destroy_called_ = true;
698
780
  bool cancel = gpr_atm_acq_load(&received_final_op_atm_) == 0;
699
781
  if (cancel) {
700
- CancelWithError(GRPC_ERROR_CANCELLED);
782
+ CancelWithError(absl::CancelledError());
701
783
  } else {
702
784
  // Unset the call combiner cancellation closure. This has the
703
785
  // effect of scheduling the previously set cancellation closure, if
@@ -708,14 +790,6 @@ void FilterStackCall::ExternalUnref() {
708
790
  InternalUnref("destroy");
709
791
  }
710
792
 
711
- char* FilterStackCall::GetPeer() {
712
- char* peer_string = reinterpret_cast<char*>(gpr_atm_acq_load(&peer_string_));
713
- if (peer_string != nullptr) return gpr_strdup(peer_string);
714
- peer_string = grpc_channel_get_target(channel_->c_ptr());
715
- if (peer_string != nullptr) return peer_string;
716
- return gpr_strdup("unknown");
717
- }
718
-
719
793
  // start_batch_closure points to a caller-allocated closure to be used
720
794
  // for entering the call combiner.
721
795
  void FilterStackCall::ExecuteBatch(grpc_transport_stream_op_batch* batch,
@@ -735,7 +809,7 @@ void FilterStackCall::ExecuteBatch(grpc_transport_stream_op_batch* batch,
735
809
  GRPC_CLOSURE_INIT(start_batch_closure, execute_batch_in_call_combiner, batch,
736
810
  grpc_schedule_on_exec_ctx);
737
811
  GRPC_CALL_COMBINER_START(call_combiner(), start_batch_closure,
738
- GRPC_ERROR_NONE, "executing batch");
812
+ absl::OkStatus(), "executing batch");
739
813
  }
740
814
 
741
815
  namespace {
@@ -758,16 +832,15 @@ static void done_termination(void* arg, grpc_error_handle /*error*/) {
758
832
 
759
833
  void FilterStackCall::CancelWithError(grpc_error_handle error) {
760
834
  if (!gpr_atm_rel_cas(&cancelled_with_error_, 0, 1)) {
761
- GRPC_ERROR_UNREF(error);
762
835
  return;
763
836
  }
764
- gpr_atm_rel_store(&peer_string_, 0);
837
+ ClearPeerString();
765
838
  InternalRef("termination");
766
839
  // Inform the call combiner of the cancellation, so that it can cancel
767
840
  // any in-flight asynchronous actions that may be holding the call
768
841
  // combiner. This ensures that the cancel_stream batch can be sent
769
842
  // down the filter stack in a timely manner.
770
- call_combiner_.Cancel(GRPC_ERROR_REF(error));
843
+ call_combiner_.Cancel(error);
771
844
  CancelState* state = new CancelState;
772
845
  state->call = this;
773
846
  GRPC_CLOSURE_INIT(&state->finish_batch, done_termination, state,
@@ -779,19 +852,10 @@ void FilterStackCall::CancelWithError(grpc_error_handle error) {
779
852
  ExecuteBatch(op, &state->start_batch);
780
853
  }
781
854
 
782
- void Call::CancelWithStatus(grpc_status_code status, const char* description) {
783
- // copying 'description' is needed to ensure the grpc_call_cancel_with_status
784
- // guarantee that can be short-lived.
785
- CancelWithError(grpc_error_set_int(
786
- grpc_error_set_str(GRPC_ERROR_CREATE_FROM_COPIED_STRING(description),
787
- GRPC_ERROR_STR_GRPC_MESSAGE, description),
788
- GRPC_ERROR_INT_GRPC_STATUS, status));
789
- }
790
-
791
855
  void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
792
856
  if (GRPC_TRACE_FLAG_ENABLED(grpc_call_error_trace)) {
793
857
  gpr_log(GPR_DEBUG, "set_final_status %s", is_client() ? "CLI" : "SVR");
794
- gpr_log(GPR_DEBUG, "%s", grpc_error_std_string(error).c_str());
858
+ gpr_log(GPR_DEBUG, "%s", StatusToString(error).c_str());
795
859
  }
796
860
  if (is_client()) {
797
861
  std::string status_details;
@@ -801,8 +865,7 @@ void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
801
865
  *final_op_.client.status_details =
802
866
  grpc_slice_from_cpp_string(std::move(status_details));
803
867
  status_error_.set(error);
804
- GRPC_ERROR_UNREF(error);
805
- channelz::ChannelNode* channelz_channel = channel_->channelz_node();
868
+ channelz::ChannelNode* channelz_channel = channel()->channelz_node();
806
869
  if (channelz_channel != nullptr) {
807
870
  if (*final_op_.client.status != GRPC_STATUS_OK) {
808
871
  channelz_channel->RecordCallFailed();
@@ -812,7 +875,7 @@ void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
812
875
  }
813
876
  } else {
814
877
  *final_op_.server.cancelled =
815
- !GRPC_ERROR_IS_NONE(error) || !sent_server_trailing_metadata_;
878
+ !error.ok() || !sent_server_trailing_metadata_;
816
879
  channelz::ServerNode* channelz_node =
817
880
  final_op_.server.core_server->channelz_node();
818
881
  if (channelz_node != nullptr) {
@@ -822,7 +885,6 @@ void FilterStackCall::SetFinalStatus(grpc_error_handle error) {
822
885
  channelz_node->RecordCallSucceeded();
823
886
  }
824
887
  }
825
- GRPC_ERROR_UNREF(error);
826
888
  }
827
889
  }
828
890
 
@@ -848,8 +910,7 @@ bool FilterStackCall::PrepareApplicationMetadata(size_t count,
848
910
  // Filter "content-length metadata"
849
911
  continue;
850
912
  }
851
- batch->Append(StringViewFromSlice(md->key),
852
- Slice(grpc_slice_ref_internal(md->value)),
913
+ batch->Append(StringViewFromSlice(md->key), Slice(CSliceRef(md->value)),
853
914
  [md](absl::string_view error, const Slice& value) {
854
915
  gpr_log(GPR_DEBUG, "Append error: %s",
855
916
  absl::StrCat("key=", StringViewFromSlice(md->key),
@@ -945,39 +1006,37 @@ void FilterStackCall::RecvInitialFilter(grpc_metadata_batch* b) {
945
1006
 
946
1007
  void FilterStackCall::RecvTrailingFilter(grpc_metadata_batch* b,
947
1008
  grpc_error_handle batch_error) {
948
- if (!GRPC_ERROR_IS_NONE(batch_error)) {
1009
+ if (!batch_error.ok()) {
949
1010
  SetFinalStatus(batch_error);
950
1011
  } else {
951
1012
  absl::optional<grpc_status_code> grpc_status =
952
1013
  b->Take(GrpcStatusMetadata());
953
1014
  if (grpc_status.has_value()) {
954
1015
  grpc_status_code status_code = *grpc_status;
955
- grpc_error_handle error = GRPC_ERROR_NONE;
1016
+ grpc_error_handle error;
956
1017
  if (status_code != GRPC_STATUS_OK) {
957
1018
  char* peer = GetPeer();
958
1019
  error = grpc_error_set_int(
959
- GRPC_ERROR_CREATE_FROM_CPP_STRING(
960
- absl::StrCat("Error received from peer ", peer)),
961
- GRPC_ERROR_INT_GRPC_STATUS, static_cast<intptr_t>(status_code));
1020
+ GRPC_ERROR_CREATE(absl::StrCat("Error received from peer ", peer)),
1021
+ StatusIntProperty::kRpcStatus, static_cast<intptr_t>(status_code));
962
1022
  gpr_free(peer);
963
1023
  }
964
1024
  auto grpc_message = b->Take(GrpcMessageMetadata());
965
1025
  if (grpc_message.has_value()) {
966
- error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE,
1026
+ error = grpc_error_set_str(error, StatusStrProperty::kGrpcMessage,
967
1027
  grpc_message->as_string_view());
968
- } else if (!GRPC_ERROR_IS_NONE(error)) {
969
- error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "");
1028
+ } else if (!error.ok()) {
1029
+ error = grpc_error_set_str(error, StatusStrProperty::kGrpcMessage, "");
970
1030
  }
971
- SetFinalStatus(GRPC_ERROR_REF(error));
972
- GRPC_ERROR_UNREF(error);
1031
+ SetFinalStatus(error);
973
1032
  } else if (!is_client()) {
974
- SetFinalStatus(GRPC_ERROR_NONE);
1033
+ SetFinalStatus(absl::OkStatus());
975
1034
  } else {
976
1035
  gpr_log(GPR_DEBUG,
977
1036
  "Received trailing metadata with no error and no status");
978
- SetFinalStatus(grpc_error_set_int(
979
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("No status received"),
980
- GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNKNOWN));
1037
+ SetFinalStatus(grpc_error_set_int(GRPC_ERROR_CREATE("No status received"),
1038
+ StatusIntProperty::kRpcStatus,
1039
+ GRPC_STATUS_UNKNOWN));
981
1040
  }
982
1041
  }
983
1042
  PublishAppMetadata(b, true);
@@ -1041,38 +1100,17 @@ FilterStackCall::BatchControl* FilterStackCall::ReuseOrAllocateBatchControl(
1041
1100
  return bctl;
1042
1101
  }
1043
1102
 
1044
- void Call::PropagateCancellationToChildren() {
1045
- ParentCall* pc = parent_call();
1046
- if (pc != nullptr) {
1047
- Call* child;
1048
- MutexLock lock(&pc->child_list_mu);
1049
- child = pc->first_child;
1050
- if (child != nullptr) {
1051
- do {
1052
- Call* next_child_call = child->child_->sibling_next;
1053
- if (child->cancellation_is_inherited_) {
1054
- child->InternalRef("propagate_cancel");
1055
- child->CancelWithError(GRPC_ERROR_CANCELLED);
1056
- child->InternalUnref("propagate_cancel");
1057
- }
1058
- child = next_child_call;
1059
- } while (child != pc->first_child);
1060
- }
1061
- }
1062
- }
1063
-
1064
1103
  void FilterStackCall::BatchControl::PostCompletion() {
1065
1104
  FilterStackCall* call = call_;
1066
- grpc_error_handle error = GRPC_ERROR_REF(batch_error_.get());
1105
+ grpc_error_handle error = batch_error_.get();
1067
1106
 
1068
1107
  if (op_.send_initial_metadata) {
1069
1108
  call->send_initial_metadata_.Clear();
1070
1109
  }
1071
1110
  if (op_.send_message) {
1072
- if (op_.payload->send_message.stream_write_closed &&
1073
- GRPC_ERROR_IS_NONE(error)) {
1111
+ if (op_.payload->send_message.stream_write_closed && error.ok()) {
1074
1112
  error = grpc_error_add_child(
1075
- error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
1113
+ error, GRPC_ERROR_CREATE(
1076
1114
  "Attempt to send message after stream was closed."));
1077
1115
  }
1078
1116
  call->sending_message_ = false;
@@ -1085,15 +1123,13 @@ void FilterStackCall::BatchControl::PostCompletion() {
1085
1123
  /* propagate cancellation to any interested children */
1086
1124
  gpr_atm_rel_store(&call->received_final_op_atm_, 1);
1087
1125
  call->PropagateCancellationToChildren();
1088
- GRPC_ERROR_UNREF(error);
1089
- error = GRPC_ERROR_NONE;
1126
+ error = absl::OkStatus();
1090
1127
  }
1091
- if (!GRPC_ERROR_IS_NONE(error) && op_.recv_message &&
1092
- *call->receiving_buffer_ != nullptr) {
1128
+ if (!error.ok() && op_.recv_message && *call->receiving_buffer_ != nullptr) {
1093
1129
  grpc_byte_buffer_destroy(*call->receiving_buffer_);
1094
1130
  *call->receiving_buffer_ = nullptr;
1095
1131
  }
1096
- batch_error_.set(GRPC_ERROR_NONE);
1132
+ batch_error_.set(absl::OkStatus());
1097
1133
 
1098
1134
  if (completion_data_.notify_tag.is_closure) {
1099
1135
  /* unrefs error */
@@ -1149,18 +1185,17 @@ void FilterStackCall::BatchControl::ProcessDataAfterMetadata() {
1149
1185
  void FilterStackCall::BatchControl::ReceivingStreamReady(
1150
1186
  grpc_error_handle error) {
1151
1187
  FilterStackCall* call = call_;
1152
- if (!GRPC_ERROR_IS_NONE(error)) {
1188
+ if (!error.ok()) {
1153
1189
  call->receiving_slice_buffer_.reset();
1154
1190
  if (batch_error_.ok()) {
1155
1191
  batch_error_.set(error);
1156
1192
  }
1157
- call->CancelWithError(GRPC_ERROR_REF(error));
1193
+ call->CancelWithError(error);
1158
1194
  }
1159
1195
  /* If recv_state is kRecvNone, we will save the batch_control
1160
1196
  * object with rel_cas, and will not use it after the cas. Its corresponding
1161
1197
  * acq_load is in receiving_initial_metadata_ready() */
1162
- if (!GRPC_ERROR_IS_NONE(error) ||
1163
- !call->receiving_slice_buffer_.has_value() ||
1198
+ if (!error.ok() || !call->receiving_slice_buffer_.has_value() ||
1164
1199
  !gpr_atm_rel_cas(&call->recv_state_, kRecvNone,
1165
1200
  reinterpret_cast<gpr_atm>(this))) {
1166
1201
  ProcessDataAfterMetadata();
@@ -1192,7 +1227,7 @@ void FilterStackCall::BatchControl::ValidateFilteredMetadata() {
1192
1227
  FilterStackCall* call = call_;
1193
1228
 
1194
1229
  const grpc_compression_options compression_options =
1195
- call->channel_->compression_options();
1230
+ call->channel()->compression_options();
1196
1231
  const grpc_compression_algorithm compression_algorithm =
1197
1232
  call->incoming_compression_algorithm_;
1198
1233
  if (GPR_UNLIKELY(!CompressionAlgorithmSet::FromUint32(
@@ -1217,7 +1252,7 @@ void FilterStackCall::BatchControl::ReceivingInitialMetadataReady(
1217
1252
 
1218
1253
  GRPC_CALL_COMBINER_STOP(call->call_combiner(), "recv_initial_metadata_ready");
1219
1254
 
1220
- if (GRPC_ERROR_IS_NONE(error)) {
1255
+ if (error.ok()) {
1221
1256
  grpc_metadata_batch* md = &call->recv_initial_metadata_;
1222
1257
  call->RecvInitialFilter(md);
1223
1258
 
@@ -1232,7 +1267,7 @@ void FilterStackCall::BatchControl::ReceivingInitialMetadataReady(
1232
1267
  if (batch_error_.ok()) {
1233
1268
  batch_error_.set(error);
1234
1269
  }
1235
- call->CancelWithError(GRPC_ERROR_REF(error));
1270
+ call->CancelWithError(error);
1236
1271
  }
1237
1272
 
1238
1273
  grpc_closure* saved_rsr_closure = nullptr;
@@ -1263,7 +1298,7 @@ void FilterStackCall::BatchControl::ReceivingInitialMetadataReady(
1263
1298
  }
1264
1299
  }
1265
1300
  if (saved_rsr_closure != nullptr) {
1266
- Closure::Run(DEBUG_LOCATION, saved_rsr_closure, GRPC_ERROR_REF(error));
1301
+ Closure::Run(DEBUG_LOCATION, saved_rsr_closure, error);
1267
1302
  }
1268
1303
 
1269
1304
  FinishStep();
@@ -1274,7 +1309,7 @@ void FilterStackCall::BatchControl::ReceivingTrailingMetadataReady(
1274
1309
  GRPC_CALL_COMBINER_STOP(call_->call_combiner(),
1275
1310
  "recv_trailing_metadata_ready");
1276
1311
  grpc_metadata_batch* md = &call_->recv_trailing_metadata_;
1277
- call_->RecvTrailingFilter(md, GRPC_ERROR_REF(error));
1312
+ call_->RecvTrailingFilter(md, error);
1278
1313
  FinishStep();
1279
1314
  }
1280
1315
 
@@ -1283,12 +1318,30 @@ void FilterStackCall::BatchControl::FinishBatch(grpc_error_handle error) {
1283
1318
  if (batch_error_.ok()) {
1284
1319
  batch_error_.set(error);
1285
1320
  }
1286
- if (!GRPC_ERROR_IS_NONE(error)) {
1287
- call_->CancelWithError(GRPC_ERROR_REF(error));
1321
+ if (!error.ok()) {
1322
+ call_->CancelWithError(error);
1288
1323
  }
1289
1324
  FinishStep();
1290
1325
  }
1291
1326
 
1327
+ namespace {
1328
+ void EndOpImmediately(grpc_completion_queue* cq, void* notify_tag,
1329
+ bool is_notify_tag_closure) {
1330
+ if (!is_notify_tag_closure) {
1331
+ GPR_ASSERT(grpc_cq_begin_op(cq, notify_tag));
1332
+ grpc_cq_end_op(
1333
+ cq, notify_tag, absl::OkStatus(),
1334
+ [](void*, grpc_cq_completion* completion) { gpr_free(completion); },
1335
+ nullptr,
1336
+ static_cast<grpc_cq_completion*>(
1337
+ gpr_malloc(sizeof(grpc_cq_completion))));
1338
+ } else {
1339
+ Closure::Run(DEBUG_LOCATION, static_cast<grpc_closure*>(notify_tag),
1340
+ absl::OkStatus());
1341
+ }
1342
+ }
1343
+ } // namespace
1344
+
1292
1345
  grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1293
1346
  void* notify_tag,
1294
1347
  bool is_notify_tag_closure) {
@@ -1312,18 +1365,7 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1312
1365
  GRPC_CALL_LOG_BATCH(GPR_INFO, ops, nops);
1313
1366
 
1314
1367
  if (nops == 0) {
1315
- if (!is_notify_tag_closure) {
1316
- GPR_ASSERT(grpc_cq_begin_op(cq_, notify_tag));
1317
- grpc_cq_end_op(
1318
- cq_, notify_tag, GRPC_ERROR_NONE,
1319
- [](void*, grpc_cq_completion* completion) { gpr_free(completion); },
1320
- nullptr,
1321
- static_cast<grpc_cq_completion*>(
1322
- gpr_malloc(sizeof(grpc_cq_completion))));
1323
- } else {
1324
- Closure::Run(DEBUG_LOCATION, static_cast<grpc_closure*>(notify_tag),
1325
- GRPC_ERROR_NONE);
1326
- }
1368
+ EndOpImmediately(cq_, notify_tag, is_notify_tag_closure);
1327
1369
  error = GRPC_CALL_OK;
1328
1370
  goto done;
1329
1371
  }
@@ -1371,7 +1413,7 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1371
1413
  level_set = true;
1372
1414
  } else {
1373
1415
  const grpc_compression_options copts =
1374
- channel_->compression_options();
1416
+ channel()->compression_options();
1375
1417
  if (copts.default_level.is_set) {
1376
1418
  level_set = true;
1377
1419
  effective_compression_level = copts.default_level.level;
@@ -1416,7 +1458,8 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1416
1458
  stream_op_payload->send_initial_metadata.send_initial_metadata =
1417
1459
  &send_initial_metadata_;
1418
1460
  if (is_client()) {
1419
- stream_op_payload->send_initial_metadata.peer_string = &peer_string_;
1461
+ stream_op_payload->send_initial_metadata.peer_string =
1462
+ peer_string_atm_ptr();
1420
1463
  }
1421
1464
  has_send_ops = true;
1422
1465
  break;
@@ -1505,11 +1548,10 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1505
1548
 
1506
1549
  grpc_error_handle status_error =
1507
1550
  op->data.send_status_from_server.status == GRPC_STATUS_OK
1508
- ? GRPC_ERROR_NONE
1551
+ ? absl::OkStatus()
1509
1552
  : grpc_error_set_int(
1510
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
1511
- "Server returned error"),
1512
- GRPC_ERROR_INT_GRPC_STATUS,
1553
+ GRPC_ERROR_CREATE("Server returned error"),
1554
+ StatusIntProperty::kRpcStatus,
1513
1555
  static_cast<intptr_t>(
1514
1556
  op->data.send_status_from_server.status));
1515
1557
  if (op->data.send_status_from_server.status_details != nullptr) {
@@ -1517,16 +1559,15 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1517
1559
  GrpcMessageMetadata(),
1518
1560
  Slice(grpc_slice_copy(
1519
1561
  *op->data.send_status_from_server.status_details)));
1520
- if (!GRPC_ERROR_IS_NONE(status_error)) {
1562
+ if (!status_error.ok()) {
1521
1563
  status_error = grpc_error_set_str(
1522
- status_error, GRPC_ERROR_STR_GRPC_MESSAGE,
1564
+ status_error, StatusStrProperty::kGrpcMessage,
1523
1565
  StringViewFromSlice(
1524
1566
  *op->data.send_status_from_server.status_details));
1525
1567
  }
1526
1568
  }
1527
1569
 
1528
1570
  status_error_.set(status_error);
1529
- GRPC_ERROR_UNREF(status_error);
1530
1571
 
1531
1572
  send_trailing_metadata_.Set(GrpcStatusMetadata(),
1532
1573
  op->data.send_status_from_server.status);
@@ -1569,7 +1610,8 @@ grpc_call_error FilterStackCall::StartBatch(const grpc_op* ops, size_t nops,
1569
1610
  stream_op_payload->recv_initial_metadata.trailing_metadata_available =
1570
1611
  &is_trailers_only_;
1571
1612
  } else {
1572
- stream_op_payload->recv_initial_metadata.peer_string = &peer_string_;
1613
+ stream_op_payload->recv_initial_metadata.peer_string =
1614
+ peer_string_atm_ptr();
1573
1615
  }
1574
1616
  ++num_recv_ops;
1575
1617
  break;
@@ -1740,8 +1782,1085 @@ void FilterStackCall::ContextSet(grpc_context_index elem, void* value,
1740
1782
  context_[elem].destroy = destroy;
1741
1783
  }
1742
1784
 
1785
+ ///////////////////////////////////////////////////////////////////////////////
1786
+ // Metadata validation helpers
1787
+
1788
+ namespace {
1789
+ bool ValidateMetadata(size_t count, grpc_metadata* metadata) {
1790
+ for (size_t i = 0; i < count; i++) {
1791
+ grpc_metadata* md = &metadata[i];
1792
+ if (!GRPC_LOG_IF_ERROR("validate_metadata",
1793
+ grpc_validate_header_key_is_legal(md->key))) {
1794
+ return false;
1795
+ } else if (!grpc_is_binary_header_internal(md->key) &&
1796
+ !GRPC_LOG_IF_ERROR(
1797
+ "validate_metadata",
1798
+ grpc_validate_header_nonbin_value_is_legal(md->value))) {
1799
+ return false;
1800
+ } else if (GRPC_SLICE_LENGTH(md->value) >= UINT32_MAX) {
1801
+ // HTTP2 hpack encoding has a maximum limit.
1802
+ return false;
1803
+ }
1804
+ }
1805
+ return true;
1806
+ }
1807
+ } // namespace
1808
+
1809
+ ///////////////////////////////////////////////////////////////////////////////
1810
+ // PromiseBasedCall
1811
+ // Will be folded into Call once the promise conversion is done
1812
+
1813
+ class PromiseBasedCall : public Call, public Activity, public Wakeable {
1814
+ public:
1815
+ PromiseBasedCall(Arena* arena, const grpc_call_create_args& args);
1816
+
1817
+ void ContextSet(grpc_context_index elem, void* value,
1818
+ void (*destroy)(void* value)) override;
1819
+ void* ContextGet(grpc_context_index elem) const override;
1820
+ void SetCompletionQueue(grpc_completion_queue* cq) override;
1821
+
1822
+ // Implementation of call refcounting: move this to DualRefCounted once we
1823
+ // don't need to maintain FilterStackCall compatibility
1824
+ void ExternalRef() final {
1825
+ refs_.fetch_add(MakeRefPair(1, 0), std::memory_order_relaxed);
1826
+ }
1827
+ void ExternalUnref() final {
1828
+ const uint64_t prev_ref_pair =
1829
+ refs_.fetch_add(MakeRefPair(-1, 1), std::memory_order_acq_rel);
1830
+ const uint32_t strong_refs = GetStrongRefs(prev_ref_pair);
1831
+ if (GPR_UNLIKELY(strong_refs == 1)) {
1832
+ Orphan();
1833
+ }
1834
+ // Now drop the weak ref.
1835
+ InternalUnref("external_ref");
1836
+ }
1837
+ void InternalRef(const char*) final {
1838
+ refs_.fetch_add(MakeRefPair(0, 1), std::memory_order_relaxed);
1839
+ }
1840
+ void InternalUnref(const char*) final {
1841
+ const uint64_t prev_ref_pair =
1842
+ refs_.fetch_sub(MakeRefPair(0, 1), std::memory_order_acq_rel);
1843
+ if (GPR_UNLIKELY(prev_ref_pair == MakeRefPair(0, 1))) {
1844
+ DeleteThis();
1845
+ }
1846
+ }
1847
+
1848
+ // Activity methods
1849
+ void ForceImmediateRepoll() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) override;
1850
+ Waker MakeOwningWaker() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) override {
1851
+ InternalRef("wakeup");
1852
+ // If ASAN is defined, we leverage it to detect dropped Waker objects.
1853
+ // Usually Waker must be destroyed or woken up, but (especially with arenas)
1854
+ // it's not uncommon to create a Waker and then do neither. In that case it's
1855
+ // incredibly fraught to diagnose where the dropped reference to this object was
1856
+ // created. Instead, leverage ASAN and create a new object per expected wakeup.
1857
+ // Now when we drop such an object ASAN will fail and we'll get a callstack to
1858
+ // the creation of the waker in question.
1859
+ #if defined(__has_feature)
1860
+ #if __has_feature(address_sanitizer)
1861
+ #define GRPC_CALL_USES_ASAN_WAKER
1862
+ class AsanWaker final : public Wakeable {
1863
+ public:
1864
+ explicit AsanWaker(PromiseBasedCall* call) : call_(call) {}
1865
+
1866
+ void Wakeup() override {
1867
+ call_->Wakeup();
1868
+ delete this;
1869
+ }
1870
+
1871
+ void Drop() override {
1872
+ call_->Drop();
1873
+ delete this;
1874
+ }
1875
+
1876
+ std::string ActivityDebugTag() const override {
1877
+ return call_->DebugTag();
1878
+ }
1879
+
1880
+ private:
1881
+ PromiseBasedCall* call_;
1882
+ };
1883
+ return Waker(new AsanWaker(this));
1884
+ #endif
1885
+ #endif
1886
+ #ifndef GRPC_CALL_USES_ASAN_WAKER
1887
+ return Waker(this);
1888
+ #endif
1889
+ }
1890
+ Waker MakeNonOwningWaker() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) override;
1891
+
1892
+ // Wakeable methods
1893
+ void Wakeup() override {
1894
+ channel()->event_engine()->Run([this] {
1895
+ ApplicationCallbackExecCtx app_exec_ctx;
1896
+ ExecCtx exec_ctx;
1897
+ {
1898
+ ScopedContext activity_context(this);
1899
+ MutexLock lock(&mu_);
1900
+ Update();
1901
+ }
1902
+ InternalUnref("wakeup");
1903
+ });
1904
+ }
1905
+ void Drop() override { InternalUnref("wakeup"); }
1906
+
1907
+ void RunInContext(absl::AnyInvocable<void()> fn) {
1908
+ if (Activity::current() == this) {
1909
+ fn();
1910
+ } else {
1911
+ InternalRef("in_context");
1912
+ channel()->event_engine()->Run([this, fn = std::move(fn)]() mutable {
1913
+ ApplicationCallbackExecCtx app_exec_ctx;
1914
+ ExecCtx exec_ctx;
1915
+ {
1916
+ ScopedContext activity_context(this);
1917
+ MutexLock lock(&mu_);
1918
+ fn();
1919
+ Update();
1920
+ }
1921
+ InternalUnref("in_context");
1922
+ });
1923
+ }
1924
+ }
1925
+
1926
+ grpc_compression_algorithm test_only_compression_algorithm() override {
1927
+ abort();
1928
+ }
1929
+ uint32_t test_only_message_flags() override { abort(); }
1930
+ uint32_t test_only_encodings_accepted_by_peer() override { abort(); }
1931
+ grpc_compression_algorithm compression_for_level(
1932
+ grpc_compression_level) override {
1933
+ abort();
1934
+ }
1935
+
1936
+ // This should return nullptr for the promise stack (and alternative means
1937
+ // for that functionality be invented)
1938
+ grpc_call_stack* call_stack() override { return nullptr; }
1939
+
1940
+ protected:
1941
+ class ScopedContext
1942
+ : public ScopedActivity,
1943
+ public promise_detail::Context<Arena>,
1944
+ public promise_detail::Context<grpc_call_context_element>,
1945
+ public promise_detail::Context<CallContext>,
1946
+ public promise_detail::Context<CallFinalization> {
1947
+ public:
1948
+ explicit ScopedContext(PromiseBasedCall* call)
1949
+ : ScopedActivity(call),
1950
+ promise_detail::Context<Arena>(call->arena()),
1951
+ promise_detail::Context<grpc_call_context_element>(call->context_),
1952
+ promise_detail::Context<CallContext>(&call->call_context_),
1953
+ promise_detail::Context<CallFinalization>(&call->finalization_) {}
1954
+ };
1955
+
1956
+ class Completion {
1957
+ public:
1958
+ Completion() : index_(kNullIndex) {}
1959
+ ~Completion() { GPR_ASSERT(index_ == kNullIndex); }
1960
+ explicit Completion(uint8_t index) : index_(index) {}
1961
+ Completion(const Completion& other) = delete;
1962
+ Completion& operator=(const Completion& other) = delete;
1963
+ Completion(Completion&& other) noexcept : index_(other.index_) {
1964
+ other.index_ = kNullIndex;
1965
+ }
1966
+ Completion& operator=(Completion&& other) noexcept {
1967
+ GPR_ASSERT(index_ == kNullIndex);
1968
+ index_ = other.index_;
1969
+ other.index_ = kNullIndex;
1970
+ return *this;
1971
+ }
1972
+
1973
+ uint8_t index() const { return index_; }
1974
+ uint8_t TakeIndex() { return std::exchange(index_, kNullIndex); }
1975
+ bool has_value() const { return index_ != kNullIndex; }
1976
+
1977
+ std::string ToString() const {
1978
+ return index_ == kNullIndex ? "null"
1979
+ : std::to_string(static_cast<int>(index_));
1980
+ }
1981
+
1982
+ private:
1983
+ enum : uint8_t { kNullIndex = 0xff };
1984
+ uint8_t index_;
1985
+ };
1986
+
1987
+ ~PromiseBasedCall() override {
1988
+ if (non_owning_wakeable_) non_owning_wakeable_->DropActivity();
1989
+ if (cq_) GRPC_CQ_INTERNAL_UNREF(cq_, "bind");
1990
+ }
1991
+
1992
+ // Enumerates why a Completion is still pending
1993
+ enum class PendingOp {
1994
+ // We're in the midst of starting a batch of operations
1995
+ kStartingBatch = 0,
1996
+ // The following correspond with the batch operations from above
1997
+ kReceiveInitialMetadata,
1998
+ kReceiveStatusOnClient,
1999
+ kSendMessage,
2000
+ kReceiveMessage,
2001
+ };
2002
+
2003
+ static constexpr const char* PendingOpString(PendingOp reason) {
2004
+ switch (reason) {
2005
+ case PendingOp::kStartingBatch:
2006
+ return "StartingBatch";
2007
+ case PendingOp::kReceiveInitialMetadata:
2008
+ return "ReceiveInitialMetadata";
2009
+ case PendingOp::kReceiveStatusOnClient:
2010
+ return "ReceiveStatusOnClient";
2011
+ case PendingOp::kSendMessage:
2012
+ return "SendMessage";
2013
+ case PendingOp::kReceiveMessage:
2014
+ return "ReceiveMessage";
2015
+ }
2016
+ return "Unknown";
2017
+ }
2018
+
2019
+ static constexpr uint8_t PendingOpBit(PendingOp reason) {
2020
+ return 1 << static_cast<int>(reason);
2021
+ }
2022
+
2023
+ Mutex* mu() const ABSL_LOCK_RETURNED(mu_) { return &mu_; }
2024
+
2025
+ // Begin work on a completion, recording the tag/closure to notify.
2026
+ // Use the op selected in \a ops to determine the index to allocate into.
2027
+ // Starts the "StartingBatch" PendingOp immediately.
2028
+ // Assumes at least one operation in \a ops.
2029
+ Completion StartCompletion(void* tag, bool is_closure, const grpc_op* ops)
2030
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
2031
+ // Add one pending op to the completion, and return it.
2032
+ Completion AddOpToCompletion(const Completion& completion, PendingOp reason)
2033
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
2034
+ // Finish one op on the completion. Must have been previously been added.
2035
+ // The completion as a whole finishes when all pending ops finish.
2036
+ void FinishOpOnCompletion(Completion* completion, PendingOp reason)
2037
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
2038
+ // Mark the completion as failed. Does not finish it.
2039
+ void FailCompletion(const Completion& completion);
2040
+ // Run the promise polling loop until it stalls.
2041
+ void Update() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_);
2042
+ // Update the promise state once.
2043
+ virtual void UpdateOnce() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) = 0;
2044
+ // Accept the stats from the context (call once we have proof the transport is
2045
+ // done with them).
2046
+ // Right now this means that promise based calls do not record correct stats
2047
+ // with census if they are cancelled.
2048
+ // TODO(ctiller): this should be remedied before promise based calls are
2049
+ // dexperimentalized.
2050
+ void AcceptTransportStatsFromContext() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
2051
+ final_stats_ = *call_context_.call_stats();
2052
+ }
2053
+
2054
+ grpc_completion_queue* cq() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) { return cq_; }
2055
+
2056
+ void CToMetadata(grpc_metadata* metadata, size_t count,
2057
+ grpc_metadata_batch* batch);
2058
+
2059
+ std::string ActivityDebugTag() const override { return DebugTag(); }
2060
+
2061
+ // At the end of the call run any finalization actions.
2062
+ void RunFinalization(grpc_status_code status, const char* status_details) {
2063
+ grpc_call_final_info final_info;
2064
+ final_info.stats = final_stats_;
2065
+ final_info.final_status = status;
2066
+ final_info.error_string = status_details;
2067
+ finalization_.Run(&final_info);
2068
+ }
2069
+
2070
+ private:
2071
+ union CompletionInfo {
2072
+ struct Pending {
2073
+ // Bitmask of PendingOps
2074
+ uint8_t pending_op_bits;
2075
+ bool is_closure;
2076
+ bool success;
2077
+ void* tag;
2078
+ } pending;
2079
+ grpc_cq_completion completion;
2080
+ };
2081
+
2082
+ class NonOwningWakable final : public Wakeable {
2083
+ public:
2084
+ explicit NonOwningWakable(PromiseBasedCall* call) : call_(call) {}
2085
+
2086
+ // Ref the Handle (not the activity).
2087
+ void Ref() { refs_.fetch_add(1, std::memory_order_relaxed); }
2088
+
2089
+ // Activity is going away... drop its reference and sever the connection
2090
+ // back.
2091
+ void DropActivity() ABSL_LOCKS_EXCLUDED(mu_) {
2092
+ auto unref = absl::MakeCleanup([this]() { Unref(); });
2093
+ MutexLock lock(&mu_);
2094
+ GPR_ASSERT(call_ != nullptr);
2095
+ call_ = nullptr;
2096
+ }
2097
+
2098
+ // Activity needs to wake up (if it still exists!) - wake it up, and drop
2099
+ // the ref that was kept for this handle.
2100
+ void Wakeup() override ABSL_LOCKS_EXCLUDED(mu_) {
2101
+ // Drop the ref to the handle at end of scope (we have one ref = one
2102
+ // wakeup semantics).
2103
+ auto unref = absl::MakeCleanup([this]() { Unref(); });
2104
+ ReleasableMutexLock lock(&mu_);
2105
+ // Note that activity refcount can drop to zero, but we could win the lock
2106
+ // against DropActivity, so we need to only increase activities refcount
2107
+ // if it is non-zero.
2108
+ if (call_ != nullptr && call_->RefIfNonZero()) {
2109
+ PromiseBasedCall* call = call_;
2110
+ lock.Release();
2111
+ // Activity still exists and we have a reference: wake it up, which will
2112
+ // drop the ref.
2113
+ call->Wakeup();
2114
+ }
2115
+ }
2116
+
2117
+ std::string ActivityDebugTag() const override {
2118
+ MutexLock lock(&mu_);
2119
+ return call_ == nullptr ? "<unknown>" : call_->DebugTag();
2120
+ }
2121
+
2122
+ void Drop() override { Unref(); }
2123
+
2124
+ private:
2125
+ // Unref the Handle (not the activity).
2126
+ void Unref() {
2127
+ if (1 == refs_.fetch_sub(1, std::memory_order_acq_rel)) {
2128
+ delete this;
2129
+ }
2130
+ }
2131
+
2132
+ mutable Mutex mu_;
2133
+ // We have two initial refs: one for the wakeup that this is created for,
2134
+ // and will be dropped by Wakeup, and the other for the activity which is
2135
+ // dropped by DropActivity.
2136
+ std::atomic<size_t> refs_{2};
2137
+ PromiseBasedCall* call_ ABSL_GUARDED_BY(mu_);
2138
+ };
2139
+
2140
+ static void OnDestroy(void* arg, grpc_error_handle) {
2141
+ auto* call = static_cast<PromiseBasedCall*>(arg);
2142
+ ScopedContext context(call);
2143
+ call->DeleteThis();
2144
+ }
2145
+
2146
+ // First 32 bits are strong refs, next 32 bits are weak refs.
2147
+ static uint64_t MakeRefPair(uint32_t strong, uint32_t weak) {
2148
+ return (static_cast<uint64_t>(strong) << 32) + static_cast<int64_t>(weak);
2149
+ }
2150
+ static uint32_t GetStrongRefs(uint64_t ref_pair) {
2151
+ return static_cast<uint32_t>(ref_pair >> 32);
2152
+ }
2153
+ static uint32_t GetWeakRefs(uint64_t ref_pair) {
2154
+ return static_cast<uint32_t>(ref_pair & 0xffffffffu);
2155
+ }
2156
+
2157
+ bool RefIfNonZero() {
2158
+ uint64_t prev_ref_pair = refs_.load(std::memory_order_acquire);
2159
+ do {
2160
+ const uint32_t strong_refs = GetStrongRefs(prev_ref_pair);
2161
+ if (strong_refs == 0) return false;
2162
+ } while (!refs_.compare_exchange_weak(
2163
+ prev_ref_pair, prev_ref_pair + MakeRefPair(1, 0),
2164
+ std::memory_order_acq_rel, std::memory_order_acquire));
2165
+ return true;
2166
+ }
2167
+
2168
+ mutable Mutex mu_;
2169
+ std::atomic<uint64_t> refs_{MakeRefPair(1, 0)};
2170
+ CallContext call_context_{this};
2171
+ bool keep_polling_ ABSL_GUARDED_BY(mu()) = false;
2172
+
2173
+ /* Contexts for various subsystems (security, tracing, ...). */
2174
+ grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
2175
+ grpc_completion_queue* cq_ ABSL_GUARDED_BY(mu_);
2176
+ NonOwningWakable* non_owning_wakeable_ ABSL_GUARDED_BY(mu_) = nullptr;
2177
+ CompletionInfo completion_info_[6];
2178
+ grpc_call_stats final_stats_{};
2179
+ CallFinalization finalization_;
2180
+ };
2181
+
2182
+ template <typename T>
2183
+ grpc_error_handle MakePromiseBasedCall(grpc_call_create_args* args,
2184
+ grpc_call** out_call) {
2185
+ Channel* channel = args->channel.get();
2186
+
2187
+ auto alloc = Arena::CreateWithAlloc(channel->CallSizeEstimate(), sizeof(T),
2188
+ channel->allocator());
2189
+ PromiseBasedCall* call = new (alloc.second) T(alloc.first, args);
2190
+ *out_call = call->c_ptr();
2191
+ GPR_DEBUG_ASSERT(Call::FromC(*out_call) == call);
2192
+ return absl::OkStatus();
2193
+ }
2194
+
2195
+ PromiseBasedCall::PromiseBasedCall(Arena* arena,
2196
+ const grpc_call_create_args& args)
2197
+ : Call(arena, args.server_transport_data == nullptr, args.send_deadline,
2198
+ args.channel->Ref()),
2199
+ cq_(args.cq) {
2200
+ if (args.cq != nullptr) {
2201
+ GPR_ASSERT(args.pollset_set_alternative == nullptr &&
2202
+ "Only one of 'cq' and 'pollset_set_alternative' should be "
2203
+ "non-nullptr.");
2204
+ GRPC_CQ_INTERNAL_REF(args.cq, "bind");
2205
+ call_context_.pollent_ =
2206
+ grpc_polling_entity_create_from_pollset(grpc_cq_pollset(args.cq));
2207
+ }
2208
+ if (args.pollset_set_alternative != nullptr) {
2209
+ call_context_.pollent_ = grpc_polling_entity_create_from_pollset_set(
2210
+ args.pollset_set_alternative);
2211
+ }
2212
+ }
2213
+
2214
+ Waker PromiseBasedCall::MakeNonOwningWaker() {
2215
+ if (non_owning_wakeable_ == nullptr) {
2216
+ non_owning_wakeable_ = new NonOwningWakable(this);
2217
+ } else {
2218
+ non_owning_wakeable_->Ref();
2219
+ }
2220
+ return Waker(non_owning_wakeable_);
2221
+ }
2222
+
2223
+ void PromiseBasedCall::CToMetadata(grpc_metadata* metadata, size_t count,
2224
+ grpc_metadata_batch* b) {
2225
+ for (size_t i = 0; i < count; i++) {
2226
+ grpc_metadata* md = &metadata[i];
2227
+ auto key = StringViewFromSlice(md->key);
2228
+ // Filter "content-length metadata"
2229
+ if (key == "content-length") continue;
2230
+ b->Append(key, Slice(CSliceRef(md->value)),
2231
+ [md](absl::string_view error, const Slice& value) {
2232
+ gpr_log(GPR_DEBUG, "Append error: %s",
2233
+ absl::StrCat("key=", StringViewFromSlice(md->key),
2234
+ " error=", error,
2235
+ " value=", value.as_string_view())
2236
+ .c_str());
2237
+ });
2238
+ }
2239
+ }
2240
+
2241
+ void PromiseBasedCall::ContextSet(grpc_context_index elem, void* value,
2242
+ void (*destroy)(void*)) {
2243
+ if (context_[elem].destroy != nullptr) {
2244
+ context_[elem].destroy(context_[elem].value);
2245
+ }
2246
+ context_[elem].value = value;
2247
+ context_[elem].destroy = destroy;
2248
+ }
2249
+
2250
+ void* PromiseBasedCall::ContextGet(grpc_context_index elem) const {
2251
+ return context_[elem].value;
2252
+ }
2253
+
2254
+ PromiseBasedCall::Completion PromiseBasedCall::StartCompletion(
2255
+ void* tag, bool is_closure, const grpc_op* ops) {
2256
+ Completion c(BatchSlotForOp(ops[0].op));
2257
+ if (grpc_call_trace.enabled()) {
2258
+ gpr_log(GPR_INFO, "%sStartCompletion %s tag=%p", DebugTag().c_str(),
2259
+ c.ToString().c_str(), tag);
2260
+ }
2261
+ if (!is_closure) {
2262
+ grpc_cq_begin_op(cq(), tag);
2263
+ }
2264
+ completion_info_[c.index()].pending = {
2265
+ PendingOpBit(PendingOp::kStartingBatch), is_closure, true, tag};
2266
+ return c;
2267
+ }
2268
+
2269
+ PromiseBasedCall::Completion PromiseBasedCall::AddOpToCompletion(
2270
+ const Completion& completion, PendingOp reason) {
2271
+ if (grpc_call_trace.enabled()) {
2272
+ gpr_log(GPR_INFO, "%sAddOpToCompletion %s %s", DebugTag().c_str(),
2273
+ completion.ToString().c_str(), PendingOpString(reason));
2274
+ }
2275
+ auto& pending_op_bits =
2276
+ completion_info_[completion.index()].pending.pending_op_bits;
2277
+ GPR_ASSERT((pending_op_bits & PendingOpBit(reason)) == 0);
2278
+ pending_op_bits |= PendingOpBit(reason);
2279
+ return Completion(completion.index());
2280
+ }
2281
+
2282
+ void PromiseBasedCall::FailCompletion(const Completion& completion) {
2283
+ if (grpc_call_trace.enabled()) {
2284
+ gpr_log(GPR_INFO, "%sFailCompletion %s", DebugTag().c_str(),
2285
+ completion.ToString().c_str());
2286
+ }
2287
+ completion_info_[completion.index()].pending.success = false;
2288
+ }
2289
+
2290
+ void PromiseBasedCall::FinishOpOnCompletion(Completion* completion,
2291
+ PendingOp reason) {
2292
+ if (grpc_call_trace.enabled()) {
2293
+ auto pending_op_bits =
2294
+ completion_info_[completion->index()].pending.pending_op_bits;
2295
+ bool success = completion_info_[completion->index()].pending.success;
2296
+ std::vector<const char*> pending;
2297
+ for (size_t i = 0; i < 8 * sizeof(pending_op_bits); i++) {
2298
+ if (static_cast<PendingOp>(i) == reason) continue;
2299
+ if (pending_op_bits & (1 << i)) {
2300
+ pending.push_back(PendingOpString(static_cast<PendingOp>(i)));
2301
+ }
2302
+ }
2303
+ gpr_log(
2304
+ GPR_INFO, "%sFinishOpOnCompletion %s %s %s", DebugTag().c_str(),
2305
+ completion->ToString().c_str(), PendingOpString(reason),
2306
+ (pending.empty()
2307
+ ? (success ? std::string("done") : std::string("failed"))
2308
+ : absl::StrFormat("pending_ops={%s}", absl::StrJoin(pending, ",")))
2309
+ .c_str());
2310
+ }
2311
+ const uint8_t i = completion->TakeIndex();
2312
+ GPR_ASSERT(i < GPR_ARRAY_SIZE(completion_info_));
2313
+ CompletionInfo::Pending& pending = completion_info_[i].pending;
2314
+ GPR_ASSERT(pending.pending_op_bits & PendingOpBit(reason));
2315
+ pending.pending_op_bits &= ~PendingOpBit(reason);
2316
+ auto error = pending.success ? absl::OkStatus() : absl::CancelledError();
2317
+ if (pending.pending_op_bits == 0) {
2318
+ if (pending.is_closure) {
2319
+ ExecCtx::Run(DEBUG_LOCATION, static_cast<grpc_closure*>(pending.tag),
2320
+ error);
2321
+ } else {
2322
+ grpc_cq_end_op(
2323
+ cq(), pending.tag, error, [](void*, grpc_cq_completion*) {}, nullptr,
2324
+ &completion_info_[i].completion);
2325
+ }
2326
+ }
2327
+ }
2328
+
2329
+ void PromiseBasedCall::Update() {
2330
+ keep_polling_ = false;
2331
+ do {
2332
+ UpdateOnce();
2333
+ } while (std::exchange(keep_polling_, false));
2334
+ }
2335
+
2336
+ void PromiseBasedCall::ForceImmediateRepoll() { keep_polling_ = true; }
2337
+
2338
+ void PromiseBasedCall::SetCompletionQueue(grpc_completion_queue* cq) {
2339
+ MutexLock lock(&mu_);
2340
+ cq_ = cq;
2341
+ GRPC_CQ_INTERNAL_REF(cq, "bind");
2342
+ call_context_.pollent_ =
2343
+ grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
2344
+ }
2345
+
2346
+ ///////////////////////////////////////////////////////////////////////////////
2347
+ // CallContext
2348
+
2349
+ void CallContext::RunInContext(absl::AnyInvocable<void()> fn) {
2350
+ call_->RunInContext(std::move(fn));
2351
+ }
2352
+
2353
+ void CallContext::IncrementRefCount(const char* reason) {
2354
+ call_->InternalRef(reason);
2355
+ }
2356
+
2357
+ void CallContext::Unref(const char* reason) { call_->InternalUnref(reason); }
2358
+
2359
+ ///////////////////////////////////////////////////////////////////////////////
2360
+ // ClientPromiseBasedCall
2361
+
2362
+ class ClientPromiseBasedCall final : public PromiseBasedCall {
2363
+ public:
2364
+ ClientPromiseBasedCall(Arena* arena, grpc_call_create_args* args)
2365
+ : PromiseBasedCall(arena, *args) {
2366
+ global_stats().IncrementClientCallsCreated();
2367
+ ScopedContext context(this);
2368
+ send_initial_metadata_ =
2369
+ GetContext<Arena>()->MakePooled<ClientMetadata>(GetContext<Arena>());
2370
+ send_initial_metadata_->Set(HttpPathMetadata(), std::move(*args->path));
2371
+ if (args->authority.has_value()) {
2372
+ send_initial_metadata_->Set(HttpAuthorityMetadata(),
2373
+ std::move(*args->authority));
2374
+ }
2375
+ if (auto* channelz_channel = channel()->channelz_node()) {
2376
+ channelz_channel->RecordCallStarted();
2377
+ }
2378
+ }
2379
+
2380
+ ~ClientPromiseBasedCall() override {
2381
+ ScopedContext context(this);
2382
+ send_initial_metadata_.reset();
2383
+ recv_status_on_client_ = absl::monostate();
2384
+ promise_ = ArenaPromise<ServerMetadataHandle>();
2385
+ // Need to destroy the pipes under the ScopedContext above, so we move them
2386
+ // out here and then allow the destructors to run at end of scope, but
2387
+ // before context.
2388
+ auto c2s = std::move(client_to_server_messages_);
2389
+ auto s2c = std::move(server_to_client_messages_);
2390
+ }
2391
+
2392
+ absl::string_view GetServerAuthority() const override { abort(); }
2393
+ void CancelWithError(grpc_error_handle error) override;
2394
+ bool Completed() override;
2395
+ void Orphan() override {
2396
+ MutexLock lock(mu());
2397
+ ScopedContext ctx(this);
2398
+ if (!completed_) Finish(ServerMetadataFromStatus(absl::CancelledError()));
2399
+ }
2400
+ bool is_trailers_only() const override {
2401
+ MutexLock lock(mu());
2402
+ return is_trailers_only_;
2403
+ }
2404
+ bool failed_before_recv_message() const override { abort(); }
2405
+
2406
+ grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
2407
+ bool is_notify_tag_closure) override;
2408
+
2409
+ std::string DebugTag() const override {
2410
+ return absl::StrFormat("CLIENT_CALL[%p]: ", this);
2411
+ }
2412
+
2413
+ private:
2414
+ // Poll the underlying promise (and sundry objects) once.
2415
+ void UpdateOnce() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu()) override;
2416
+ // Finish the call with the given status/trailing metadata.
2417
+ void Finish(ServerMetadataHandle trailing_metadata)
2418
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
2419
+ // Validate that a set of ops is valid for a client call.
2420
+ grpc_call_error ValidateBatch(const grpc_op* ops, size_t nops) const
2421
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
2422
+ // Commit a valid batch of operations to be executed.
2423
+ void CommitBatch(const grpc_op* ops, size_t nops,
2424
+ const Completion& completion)
2425
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
2426
+ // Start the underlying promise.
2427
+ void StartPromise(ClientMetadataHandle client_initial_metadata)
2428
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
2429
+ // Publish some metadata out to the application.
2430
+ static void PublishMetadataArray(grpc_metadata_array* array,
2431
+ ServerMetadata* md);
2432
+ // Publish status out to the application.
2433
+ void PublishStatus(
2434
+ grpc_op::grpc_op_data::grpc_op_recv_status_on_client op_args,
2435
+ ServerMetadataHandle trailing_metadata)
2436
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
2437
+ // Publish server initial metadata out to the application.
2438
+ void PublishInitialMetadata(ServerMetadata* metadata)
2439
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu());
2440
+
2441
+ ArenaPromise<ServerMetadataHandle> promise_ ABSL_GUARDED_BY(mu());
2442
+ Latch<ServerMetadata*> server_initial_metadata_ ABSL_GUARDED_BY(mu());
2443
+ Pipe<MessageHandle> client_to_server_messages_ ABSL_GUARDED_BY(mu()){arena()};
2444
+ Pipe<MessageHandle> server_to_client_messages_ ABSL_GUARDED_BY(mu()){arena()};
2445
+
2446
+ ClientMetadataHandle send_initial_metadata_;
2447
+ grpc_metadata_array* recv_initial_metadata_ ABSL_GUARDED_BY(mu()) = nullptr;
2448
+ grpc_byte_buffer** recv_message_ ABSL_GUARDED_BY(mu()) = nullptr;
2449
+ absl::variant<absl::monostate,
2450
+ grpc_op::grpc_op_data::grpc_op_recv_status_on_client,
2451
+ ServerMetadataHandle>
2452
+ recv_status_on_client_ ABSL_GUARDED_BY(mu());
2453
+ absl::optional<PipeSender<MessageHandle>::PushType> outstanding_send_
2454
+ ABSL_GUARDED_BY(mu());
2455
+ absl::optional<PipeReceiver<MessageHandle>::NextType> outstanding_recv_
2456
+ ABSL_GUARDED_BY(mu());
2457
+ absl::optional<Latch<ServerMetadata*>::WaitPromise>
2458
+ server_initial_metadata_ready_;
2459
+ absl::optional<grpc_compression_algorithm> incoming_compression_algorithm_;
2460
+ Completion recv_initial_metadata_completion_ ABSL_GUARDED_BY(mu());
2461
+ Completion recv_status_on_client_completion_ ABSL_GUARDED_BY(mu());
2462
+ Completion send_message_completion_ ABSL_GUARDED_BY(mu());
2463
+ Completion recv_message_completion_ ABSL_GUARDED_BY(mu());
2464
+ bool completed_ ABSL_GUARDED_BY(mu()) = false;
2465
+ bool is_trailers_only_ ABSL_GUARDED_BY(mu());
2466
+ };
2467
+
2468
+ void ClientPromiseBasedCall::StartPromise(
2469
+ ClientMetadataHandle client_initial_metadata) {
2470
+ GPR_ASSERT(!promise_.has_value());
2471
+ promise_ = channel()->channel_stack()->MakeClientCallPromise(CallArgs{
2472
+ std::move(client_initial_metadata),
2473
+ &server_initial_metadata_,
2474
+ &client_to_server_messages_.receiver,
2475
+ &server_to_client_messages_.sender,
2476
+ });
2477
+ }
2478
+
2479
+ void ClientPromiseBasedCall::CancelWithError(grpc_error_handle error) {
2480
+ MutexLock lock(mu());
2481
+ ScopedContext context(this);
2482
+ Finish(ServerMetadataFromStatus(grpc_error_to_absl_status(error)));
2483
+ }
2484
+
2485
+ grpc_call_error ClientPromiseBasedCall::ValidateBatch(const grpc_op* ops,
2486
+ size_t nops) const {
2487
+ BitSet<8> got_ops;
2488
+ for (size_t op_idx = 0; op_idx < nops; op_idx++) {
2489
+ const grpc_op& op = ops[op_idx];
2490
+ switch (op.op) {
2491
+ case GRPC_OP_SEND_INITIAL_METADATA:
2492
+ if (!AreInitialMetadataFlagsValid(op.flags)) {
2493
+ return GRPC_CALL_ERROR_INVALID_FLAGS;
2494
+ }
2495
+ if (!ValidateMetadata(op.data.send_initial_metadata.count,
2496
+ op.data.send_initial_metadata.metadata)) {
2497
+ return GRPC_CALL_ERROR_INVALID_METADATA;
2498
+ }
2499
+ break;
2500
+ case GRPC_OP_SEND_MESSAGE:
2501
+ if (!AreWriteFlagsValid(op.flags)) {
2502
+ return GRPC_CALL_ERROR_INVALID_FLAGS;
2503
+ }
2504
+ break;
2505
+ case GRPC_OP_RECV_INITIAL_METADATA:
2506
+ case GRPC_OP_RECV_MESSAGE:
2507
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
2508
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
2509
+ if (op.flags != 0) return GRPC_CALL_ERROR_INVALID_FLAGS;
2510
+ break;
2511
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
2512
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
2513
+ return GRPC_CALL_ERROR_NOT_ON_CLIENT;
2514
+ }
2515
+ if (got_ops.is_set(op.op)) return GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
2516
+ got_ops.set(op.op);
2517
+ }
2518
+ return GRPC_CALL_OK;
2519
+ }
2520
+
2521
+ void ClientPromiseBasedCall::CommitBatch(const grpc_op* ops, size_t nops,
2522
+ const Completion& completion) {
2523
+ for (size_t op_idx = 0; op_idx < nops; op_idx++) {
2524
+ const grpc_op& op = ops[op_idx];
2525
+ switch (op.op) {
2526
+ case GRPC_OP_SEND_INITIAL_METADATA: {
2527
+ // compression not implemented
2528
+ GPR_ASSERT(
2529
+ !op.data.send_initial_metadata.maybe_compression_level.is_set);
2530
+ if (!completed_) {
2531
+ CToMetadata(op.data.send_initial_metadata.metadata,
2532
+ op.data.send_initial_metadata.count,
2533
+ send_initial_metadata_.get());
2534
+ StartPromise(std::move(send_initial_metadata_));
2535
+ }
2536
+ } break;
2537
+ case GRPC_OP_RECV_INITIAL_METADATA: {
2538
+ recv_initial_metadata_ =
2539
+ op.data.recv_initial_metadata.recv_initial_metadata;
2540
+ server_initial_metadata_ready_ = server_initial_metadata_.Wait();
2541
+ recv_initial_metadata_completion_ =
2542
+ AddOpToCompletion(completion, PendingOp::kReceiveInitialMetadata);
2543
+ } break;
2544
+ case GRPC_OP_RECV_STATUS_ON_CLIENT: {
2545
+ recv_status_on_client_completion_ =
2546
+ AddOpToCompletion(completion, PendingOp::kReceiveStatusOnClient);
2547
+ if (auto* finished_metadata =
2548
+ absl::get_if<ServerMetadataHandle>(&recv_status_on_client_)) {
2549
+ PublishStatus(op.data.recv_status_on_client,
2550
+ std::move(*finished_metadata));
2551
+ } else {
2552
+ recv_status_on_client_ = op.data.recv_status_on_client;
2553
+ }
2554
+ } break;
2555
+ case GRPC_OP_SEND_MESSAGE: {
2556
+ GPR_ASSERT(!outstanding_send_.has_value());
2557
+ if (!completed_) {
2558
+ send_message_completion_ =
2559
+ AddOpToCompletion(completion, PendingOp::kSendMessage);
2560
+ SliceBuffer send;
2561
+ grpc_slice_buffer_swap(
2562
+ &op.data.send_message.send_message->data.raw.slice_buffer,
2563
+ send.c_slice_buffer());
2564
+ outstanding_send_.emplace(client_to_server_messages_.sender.Push(
2565
+ GetContext<Arena>()->MakePooled<Message>(std::move(send),
2566
+ op.flags)));
2567
+ } else {
2568
+ FailCompletion(completion);
2569
+ }
2570
+ } break;
2571
+ case GRPC_OP_RECV_MESSAGE: {
2572
+ GPR_ASSERT(!outstanding_recv_.has_value());
2573
+ recv_message_ = op.data.recv_message.recv_message;
2574
+ recv_message_completion_ =
2575
+ AddOpToCompletion(completion, PendingOp::kReceiveMessage);
2576
+ outstanding_recv_.emplace(server_to_client_messages_.receiver.Next());
2577
+ } break;
2578
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT: {
2579
+ client_to_server_messages_.sender.Close();
2580
+ } break;
2581
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
2582
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
2583
+ abort(); // unreachable
2584
+ }
2585
+ }
2586
+ }
2587
+
2588
+ grpc_call_error ClientPromiseBasedCall::StartBatch(const grpc_op* ops,
2589
+ size_t nops,
2590
+ void* notify_tag,
2591
+ bool is_notify_tag_closure) {
2592
+ MutexLock lock(mu());
2593
+ ScopedContext activity_context(this);
2594
+ if (nops == 0) {
2595
+ EndOpImmediately(cq(), notify_tag, is_notify_tag_closure);
2596
+ return GRPC_CALL_OK;
2597
+ }
2598
+ const grpc_call_error validation_result = ValidateBatch(ops, nops);
2599
+ if (validation_result != GRPC_CALL_OK) {
2600
+ return validation_result;
2601
+ }
2602
+ Completion completion =
2603
+ StartCompletion(notify_tag, is_notify_tag_closure, ops);
2604
+ CommitBatch(ops, nops, completion);
2605
+ Update();
2606
+ FinishOpOnCompletion(&completion, PendingOp::kStartingBatch);
2607
+ return GRPC_CALL_OK;
2608
+ }
2609
+
2610
+ void ClientPromiseBasedCall::PublishInitialMetadata(ServerMetadata* metadata) {
2611
+ incoming_compression_algorithm_ =
2612
+ metadata->Take(GrpcEncodingMetadata()).value_or(GRPC_COMPRESS_NONE);
2613
+ server_initial_metadata_ready_.reset();
2614
+ GPR_ASSERT(recv_initial_metadata_ != nullptr);
2615
+ PublishMetadataArray(std::exchange(recv_initial_metadata_, nullptr),
2616
+ metadata);
2617
+ FinishOpOnCompletion(&recv_initial_metadata_completion_,
2618
+ PendingOp::kReceiveInitialMetadata);
2619
+ }
2620
+
2621
+ void ClientPromiseBasedCall::UpdateOnce() {
2622
+ if (grpc_call_trace.enabled()) {
2623
+ auto present_and_completion_text =
2624
+ [](const char* caption, bool has,
2625
+ const Completion& completion) -> std::string {
2626
+ if (has) {
2627
+ if (completion.has_value()) {
2628
+ return absl::StrCat(caption, ":",
2629
+ static_cast<int>(completion.index()), " ");
2630
+ } else {
2631
+ return absl::StrCat(caption,
2632
+ ":!!BUG:operation is present, no completion!! ");
2633
+ }
2634
+ } else {
2635
+ if (!completion.has_value()) {
2636
+ return "";
2637
+ } else {
2638
+ return absl::StrCat(
2639
+ caption, ":no-op:", static_cast<int>(completion.index()), " ");
2640
+ }
2641
+ }
2642
+ };
2643
+ gpr_log(
2644
+ GPR_INFO, "%sUpdateOnce: %s%s%shas_promise=%s", DebugTag().c_str(),
2645
+ present_and_completion_text("server_initial_metadata_ready",
2646
+ server_initial_metadata_ready_.has_value(),
2647
+ recv_initial_metadata_completion_)
2648
+ .c_str(),
2649
+ present_and_completion_text("outstanding_send",
2650
+ outstanding_send_.has_value(),
2651
+ send_message_completion_)
2652
+ .c_str(),
2653
+ present_and_completion_text("outstanding_recv",
2654
+ outstanding_recv_.has_value(),
2655
+ recv_message_completion_)
2656
+ .c_str(),
2657
+ promise_.has_value() ? "true" : "false");
2658
+ }
2659
+ if (send_message_completion_.has_value()) {
2660
+ FinishOpOnCompletion(&send_message_completion_, PendingOp::kSendMessage);
2661
+ }
2662
+ if (server_initial_metadata_ready_.has_value()) {
2663
+ Poll<ServerMetadata**> r = (*server_initial_metadata_ready_)();
2664
+ if (ServerMetadata*** server_initial_metadata =
2665
+ absl::get_if<ServerMetadata**>(&r)) {
2666
+ PublishInitialMetadata(**server_initial_metadata);
2667
+ } else if (completed_) {
2668
+ ServerMetadata no_metadata{GetContext<Arena>()};
2669
+ PublishInitialMetadata(&no_metadata);
2670
+ }
2671
+ }
2672
+ if (outstanding_send_.has_value()) {
2673
+ Poll<bool> r = (*outstanding_send_)();
2674
+ if (const bool* result = absl::get_if<bool>(&r)) {
2675
+ outstanding_send_.reset();
2676
+ if (!*result) {
2677
+ FailCompletion(send_message_completion_);
2678
+ Finish(ServerMetadataFromStatus(absl::Status(
2679
+ absl::StatusCode::kInternal, "Failed to send message to server")));
2680
+ }
2681
+ }
2682
+ }
2683
+ if (promise_.has_value()) {
2684
+ Poll<ServerMetadataHandle> r = promise_();
2685
+ if (grpc_call_trace.enabled()) {
2686
+ gpr_log(GPR_INFO, "%sUpdateOnce: promise returns %s", DebugTag().c_str(),
2687
+ PollToString(r, [](const ServerMetadataHandle& h) {
2688
+ return h->DebugString();
2689
+ }).c_str());
2690
+ }
2691
+ if (auto* result = absl::get_if<ServerMetadataHandle>(&r)) {
2692
+ AcceptTransportStatsFromContext();
2693
+ Finish(std::move(*result));
2694
+ }
2695
+ }
2696
+ if (incoming_compression_algorithm_.has_value() &&
2697
+ outstanding_recv_.has_value()) {
2698
+ Poll<NextResult<MessageHandle>> r = (*outstanding_recv_)();
2699
+ if (auto* result = absl::get_if<NextResult<MessageHandle>>(&r)) {
2700
+ outstanding_recv_.reset();
2701
+ if (result->has_value()) {
2702
+ MessageHandle& message = **result;
2703
+ if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) &&
2704
+ (incoming_compression_algorithm_ != GRPC_COMPRESS_NONE)) {
2705
+ *recv_message_ = grpc_raw_compressed_byte_buffer_create(
2706
+ nullptr, 0, *incoming_compression_algorithm_);
2707
+ } else {
2708
+ *recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0);
2709
+ }
2710
+ grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(),
2711
+ &(*recv_message_)->data.raw.slice_buffer);
2712
+ if (grpc_call_trace.enabled()) {
2713
+ gpr_log(GPR_INFO,
2714
+ "%sUpdateOnce: outstanding_recv finishes: received %" PRIdPTR
2715
+ " byte message",
2716
+ DebugTag().c_str(),
2717
+ (*recv_message_)->data.raw.slice_buffer.length);
2718
+ }
2719
+ } else {
2720
+ if (grpc_call_trace.enabled()) {
2721
+ gpr_log(
2722
+ GPR_INFO,
2723
+ "%sUpdateOnce: outstanding_recv finishes: received end-of-stream",
2724
+ DebugTag().c_str());
2725
+ }
2726
+ *recv_message_ = nullptr;
2727
+ }
2728
+ FinishOpOnCompletion(&recv_message_completion_,
2729
+ PendingOp::kReceiveMessage);
2730
+ } else if (completed_) {
2731
+ if (grpc_call_trace.enabled()) {
2732
+ gpr_log(GPR_INFO,
2733
+ "%sUpdateOnce: outstanding_recv finishes: promise has "
2734
+ "completed without queuing a message, forcing end-of-stream",
2735
+ DebugTag().c_str());
2736
+ }
2737
+ outstanding_recv_.reset();
2738
+ *recv_message_ = nullptr;
2739
+ FinishOpOnCompletion(&recv_message_completion_,
2740
+ PendingOp::kReceiveMessage);
2741
+ }
2742
+ }
2743
+ }
2744
+
2745
+ void ClientPromiseBasedCall::Finish(ServerMetadataHandle trailing_metadata) {
2746
+ if (grpc_call_trace.enabled()) {
2747
+ gpr_log(GPR_INFO, "%sFinish: %s", DebugTag().c_str(),
2748
+ trailing_metadata->DebugString().c_str());
2749
+ }
2750
+ promise_ = ArenaPromise<ServerMetadataHandle>();
2751
+ completed_ = true;
2752
+ if (recv_initial_metadata_ != nullptr) {
2753
+ ForceImmediateRepoll();
2754
+ }
2755
+ const bool pending_initial_metadata =
2756
+ server_initial_metadata_ready_.has_value();
2757
+ server_initial_metadata_ready_.reset();
2758
+ Poll<ServerMetadata**> r = server_initial_metadata_.Wait()();
2759
+ if (auto* result = absl::get_if<ServerMetadata**>(&r)) {
2760
+ if (pending_initial_metadata) PublishInitialMetadata(**result);
2761
+ is_trailers_only_ = false;
2762
+ } else {
2763
+ if (pending_initial_metadata) {
2764
+ ServerMetadata no_metadata{GetContext<Arena>()};
2765
+ PublishInitialMetadata(&no_metadata);
2766
+ }
2767
+ is_trailers_only_ = true;
2768
+ }
2769
+ if (auto* channelz_channel = channel()->channelz_node()) {
2770
+ if (trailing_metadata->get(GrpcStatusMetadata())
2771
+ .value_or(GRPC_STATUS_UNKNOWN) == GRPC_STATUS_OK) {
2772
+ channelz_channel->RecordCallSucceeded();
2773
+ } else {
2774
+ channelz_channel->RecordCallFailed();
2775
+ }
2776
+ }
2777
+ if (auto* status_request =
2778
+ absl::get_if<grpc_op::grpc_op_data::grpc_op_recv_status_on_client>(
2779
+ &recv_status_on_client_)) {
2780
+ PublishStatus(*status_request, std::move(trailing_metadata));
2781
+ } else {
2782
+ recv_status_on_client_ = std::move(trailing_metadata);
2783
+ }
2784
+ }
2785
+
2786
+ namespace {
2787
+ std::string MakeErrorString(const ServerMetadata* trailing_metadata) {
2788
+ std::string out = absl::StrCat(
2789
+ trailing_metadata->get(GrpcStatusFromWire()).value_or(false)
2790
+ ? "Error received from peer"
2791
+ : "Error generated by client",
2792
+ "grpc_status: ",
2793
+ grpc_status_code_to_string(trailing_metadata->get(GrpcStatusMetadata())
2794
+ .value_or(GRPC_STATUS_UNKNOWN)));
2795
+ if (const Slice* message =
2796
+ trailing_metadata->get_pointer(GrpcMessageMetadata())) {
2797
+ absl::StrAppend(&out, "\ngrpc_message: ", message->as_string_view());
2798
+ }
2799
+ if (auto annotations = trailing_metadata->get_pointer(GrpcStatusContext())) {
2800
+ absl::StrAppend(&out, "\nStatus Context:");
2801
+ for (const std::string& annotation : *annotations) {
2802
+ absl::StrAppend(&out, "\n ", annotation);
2803
+ }
2804
+ }
2805
+ return out;
2806
+ }
2807
+ } // namespace
2808
+
2809
+ void ClientPromiseBasedCall::PublishStatus(
2810
+ grpc_op::grpc_op_data::grpc_op_recv_status_on_client op_args,
2811
+ ServerMetadataHandle trailing_metadata) {
2812
+ const grpc_status_code status = trailing_metadata->get(GrpcStatusMetadata())
2813
+ .value_or(GRPC_STATUS_UNKNOWN);
2814
+ *op_args.status = status;
2815
+ absl::string_view message_string;
2816
+ if (Slice* message = trailing_metadata->get_pointer(GrpcMessageMetadata())) {
2817
+ message_string = message->as_string_view();
2818
+ *op_args.status_details = message->Ref().TakeCSlice();
2819
+ } else {
2820
+ *op_args.status_details = grpc_empty_slice();
2821
+ }
2822
+ if (message_string.empty()) {
2823
+ RunFinalization(status, nullptr);
2824
+ } else {
2825
+ std::string error_string(message_string);
2826
+ RunFinalization(status, error_string.c_str());
2827
+ }
2828
+ if (op_args.error_string != nullptr && status != GRPC_STATUS_OK) {
2829
+ *op_args.error_string =
2830
+ gpr_strdup(MakeErrorString(trailing_metadata.get()).c_str());
2831
+ }
2832
+ PublishMetadataArray(op_args.trailing_metadata, trailing_metadata.get());
2833
+ FinishOpOnCompletion(&recv_status_on_client_completion_,
2834
+ PendingOp::kReceiveStatusOnClient);
2835
+ }
2836
+
2837
+ void ClientPromiseBasedCall::PublishMetadataArray(grpc_metadata_array* array,
2838
+ ServerMetadata* md) {
2839
+ const auto md_count = md->count();
2840
+ if (md_count > array->capacity) {
2841
+ array->capacity =
2842
+ std::max(array->capacity + md->count(), array->capacity * 3 / 2);
2843
+ array->metadata = static_cast<grpc_metadata*>(
2844
+ gpr_realloc(array->metadata, sizeof(grpc_metadata) * array->capacity));
2845
+ }
2846
+ PublishToAppEncoder encoder(array);
2847
+ md->Encode(&encoder);
2848
+ }
2849
+
2850
+ bool ClientPromiseBasedCall::Completed() {
2851
+ MutexLock lock(mu());
2852
+ return completed_;
2853
+ }
2854
+
2855
+ gpr_atm* CallContext::peer_string_atm_ptr() {
2856
+ return call_->peer_string_atm_ptr();
2857
+ }
2858
+
1743
2859
  } // namespace grpc_core
1744
2860
 
2861
+ ///////////////////////////////////////////////////////////////////////////////
2862
+ // C-based API
2863
+
1745
2864
  void* grpc_call_arena_alloc(grpc_call* call, size_t size) {
1746
2865
  grpc_core::ExecCtx exec_ctx;
1747
2866
  return grpc_core::Call::FromC(call)->arena()->Alloc(size);
@@ -1753,6 +2872,13 @@ size_t grpc_call_get_initial_size_estimate() {
1753
2872
 
1754
2873
  grpc_error_handle grpc_call_create(grpc_call_create_args* args,
1755
2874
  grpc_call** out_call) {
2875
+ if (grpc_core::IsPromiseBasedClientCallEnabled() &&
2876
+ args->channel->is_promising()) {
2877
+ if (args->server_transport_data == nullptr) {
2878
+ return grpc_core::MakePromiseBasedCall<grpc_core::ClientPromiseBasedCall>(
2879
+ args, out_call);
2880
+ }
2881
+ }
1756
2882
  return grpc_core::FilterStackCall::Create(args, out_call);
1757
2883
  }
1758
2884
 
@@ -1764,6 +2890,7 @@ void grpc_call_set_completion_queue(grpc_call* call,
1764
2890
  void grpc_call_ref(grpc_call* c) { grpc_core::Call::FromC(c)->ExternalRef(); }
1765
2891
 
1766
2892
  void grpc_call_unref(grpc_call* c) {
2893
+ grpc_core::ExecCtx exec_ctx;
1767
2894
  grpc_core::Call::FromC(c)->ExternalUnref();
1768
2895
  }
1769
2896
 
@@ -1780,7 +2907,7 @@ grpc_call_error grpc_call_cancel(grpc_call* call, void* reserved) {
1780
2907
  GPR_ASSERT(reserved == nullptr);
1781
2908
  grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
1782
2909
  grpc_core::ExecCtx exec_ctx;
1783
- grpc_core::Call::FromC(call)->CancelWithError(GRPC_ERROR_CANCELLED);
2910
+ grpc_core::Call::FromC(call)->CancelWithError(absl::CancelledError());
1784
2911
  return GRPC_CALL_OK;
1785
2912
  }
1786
2913
 
@@ -1800,7 +2927,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call* c,
1800
2927
  }
1801
2928
 
1802
2929
  void grpc_call_cancel_internal(grpc_call* call) {
1803
- grpc_core::Call::FromC(call)->CancelWithError(GRPC_ERROR_CANCELLED);
2930
+ grpc_core::Call::FromC(call)->CancelWithError(absl::CancelledError());
1804
2931
  }
1805
2932
 
1806
2933
  grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(