grpc 1.74.1 → 1.75.0.pre1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +83 -41
  3. data/include/grpc/credentials.h +7 -1
  4. data/src/core/call/client_call.cc +4 -4
  5. data/src/core/call/filter_fusion.h +1230 -0
  6. data/src/core/call/metadata.cc +22 -0
  7. data/src/core/call/metadata.h +24 -2
  8. data/src/core/channelz/channelz.cc +10 -17
  9. data/src/core/channelz/channelz.h +58 -19
  10. data/src/core/channelz/channelz_registry.cc +0 -162
  11. data/src/core/channelz/channelz_registry.h +14 -7
  12. data/src/core/channelz/property_list.cc +19 -23
  13. data/src/core/channelz/property_list.h +3 -1
  14. data/src/core/channelz/v2tov1/convert.cc +683 -0
  15. data/src/core/channelz/v2tov1/convert.h +58 -0
  16. data/src/core/channelz/v2tov1/legacy_api.cc +425 -0
  17. data/src/core/channelz/v2tov1/legacy_api.h +32 -0
  18. data/src/core/channelz/v2tov1/property_list.cc +118 -0
  19. data/src/core/channelz/v2tov1/property_list.h +52 -0
  20. data/src/core/client_channel/client_channel_filter.cc +5 -4
  21. data/src/core/client_channel/client_channel_filter.h +2 -2
  22. data/src/core/client_channel/client_channel_internal.h +2 -1
  23. data/src/core/client_channel/load_balanced_call_destination.cc +6 -5
  24. data/src/core/client_channel/subchannel.cc +14 -6
  25. data/src/core/client_channel/subchannel.h +2 -0
  26. data/src/core/config/core_configuration.cc +3 -1
  27. data/src/core/config/core_configuration.h +12 -0
  28. data/src/core/credentials/transport/alts/alts_credentials.cc +5 -0
  29. data/src/core/credentials/transport/alts/check_gcp_environment_windows.cc +2 -0
  30. data/src/core/credentials/transport/channel_creds_registry_init.cc +3 -1
  31. data/src/core/credentials/transport/ssl/ssl_credentials.cc +1 -1
  32. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +8 -3
  33. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +29 -24
  34. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +19 -8
  35. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +96 -54
  36. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.h +15 -2
  37. data/src/core/credentials/transport/tls/spiffe_utils.cc +371 -0
  38. data/src/core/credentials/transport/tls/spiffe_utils.h +171 -0
  39. data/src/core/credentials/transport/tls/ssl_utils.cc +11 -10
  40. data/src/core/credentials/transport/tls/ssl_utils.h +4 -2
  41. data/src/core/credentials/transport/tls/tls_credentials.cc +2 -0
  42. data/src/core/credentials/transport/tls/tls_security_connector.cc +11 -26
  43. data/src/core/credentials/transport/tls/tls_security_connector.h +12 -12
  44. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +1 -2
  45. data/src/core/ext/filters/http/client/http_client_filter.cc +3 -6
  46. data/src/core/ext/filters/http/client_authority_filter.cc +1 -2
  47. data/src/core/ext/filters/http/message_compress/compression_filter.cc +8 -8
  48. data/src/core/ext/filters/http/server/http_server_filter.cc +3 -6
  49. data/src/core/ext/filters/message_size/message_size_filter.cc +4 -4
  50. data/src/core/ext/filters/rbac/rbac_filter.cc +1 -1
  51. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +3 -5
  52. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +3 -2
  53. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  54. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -0
  55. data/src/core/ext/transport/chttp2/transport/frame.cc +89 -6
  56. data/src/core/ext/transport/chttp2/transport/frame.h +38 -0
  57. data/src/core/ext/transport/chttp2/transport/header_assembler.h +5 -14
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -1
  59. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +294 -78
  60. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +128 -9
  61. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +11 -38
  62. data/src/core/ext/transport/chttp2/transport/http2_settings.h +52 -35
  63. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.cc +61 -0
  64. data/src/core/ext/transport/chttp2/transport/http2_settings_manager.h +142 -0
  65. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +81 -3
  66. data/src/core/ext/transport/chttp2/transport/http2_transport.h +12 -1
  67. data/src/core/ext/transport/chttp2/transport/message_assembler.h +2 -2
  68. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -1
  69. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +2 -1
  70. data/src/core/ext/transport/chttp2/transport/ping_promise.h +22 -5
  71. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +607 -0
  72. data/src/core/ext/transport/chttp2/transport/writable_streams.h +254 -0
  73. data/src/core/ext/transport/chttp2/transport/writing.cc +6 -4
  74. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb.h +4959 -0
  75. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.c +1111 -0
  76. data/src/core/ext/upb-gen/src/proto/grpc/channelz/channelz.upb_minitable.h +108 -0
  77. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +142 -54
  78. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +18 -14
  79. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +2 -2
  80. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.c +716 -0
  81. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/channelz.upbdefs.h +227 -0
  82. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +86 -88
  83. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +2 -2
  84. data/src/core/filter/auth/auth_filters.h +2 -2
  85. data/src/core/filter/fused_filters.cc +154 -0
  86. data/src/core/handshaker/security/legacy_secure_endpoint.cc +1 -1
  87. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +965 -0
  88. data/src/core/handshaker/security/secure_endpoint.cc +28 -13
  89. data/src/core/handshaker/security/secure_endpoint.h +8 -0
  90. data/src/core/lib/channel/promise_based_filter.cc +15 -25
  91. data/src/core/lib/channel/promise_based_filter.h +6 -5
  92. data/src/core/lib/event_engine/ares_resolver.h +3 -1
  93. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +9 -5
  94. data/src/core/lib/event_engine/cf_engine/cf_engine.h +2 -1
  95. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +263 -0
  96. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.h +107 -0
  97. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.cc +31 -3
  98. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +12 -0
  99. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +12 -10
  100. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +6 -4
  101. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +15 -14
  102. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -5
  103. data/src/core/lib/event_engine/posix_engine/event_poller.h +0 -8
  104. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +11 -5
  105. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.h +3 -2
  106. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +1 -0
  107. data/src/core/lib/event_engine/posix_engine/lockfree_event.cc +4 -4
  108. data/src/core/lib/event_engine/posix_engine/lockfree_event.h +3 -4
  109. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +2 -2
  110. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +188 -199
  111. data/src/core/lib/event_engine/posix_engine/posix_engine.h +30 -45
  112. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +1 -1
  113. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +1 -1
  114. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +2 -1
  115. data/src/core/lib/experiments/experiments.cc +120 -6
  116. data/src/core/lib/experiments/experiments.h +46 -3
  117. data/src/core/lib/iomgr/combiner.cc +1 -1
  118. data/src/core/lib/iomgr/exec_ctx.h +3 -9
  119. data/src/core/lib/iomgr/socket_mutator.cc +1 -1
  120. data/src/core/lib/iomgr/socket_utils_posix.cc +1 -1
  121. data/src/core/lib/iomgr/socket_utils_posix.h +1 -1
  122. data/src/core/lib/iomgr/tcp_client_posix.cc +1 -1
  123. data/src/core/lib/iomgr/tcp_posix.cc +3 -3
  124. data/src/core/lib/promise/activity.h +2 -2
  125. data/src/core/lib/promise/mpsc.cc +8 -8
  126. data/src/core/lib/promise/party.cc +7 -7
  127. data/src/core/lib/promise/party.h +4 -4
  128. data/src/core/lib/promise/poll.h +10 -0
  129. data/src/core/lib/resource_quota/memory_quota.cc +90 -3
  130. data/src/core/lib/resource_quota/memory_quota.h +20 -9
  131. data/src/core/lib/resource_quota/periodic_update.cc +14 -0
  132. data/src/core/lib/resource_quota/periodic_update.h +8 -0
  133. data/src/core/lib/resource_quota/resource_quota.cc +15 -4
  134. data/src/core/lib/resource_quota/resource_quota.h +3 -0
  135. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -2
  136. data/src/core/lib/surface/call.cc +5 -5
  137. data/src/core/lib/surface/call.h +6 -5
  138. data/src/core/lib/surface/completion_queue.cc +2 -4
  139. data/src/core/lib/surface/filter_stack_call.cc +1 -1
  140. data/src/core/lib/surface/version.cc +2 -2
  141. data/src/core/lib/transport/promise_endpoint.cc +2 -2
  142. data/src/core/lib/transport/promise_endpoint.h +3 -3
  143. data/src/core/load_balancing/endpoint_list.cc +29 -2
  144. data/src/core/load_balancing/grpclb/client_load_reporting_filter.cc +3 -3
  145. data/src/core/load_balancing/grpclb/client_load_reporting_filter.h +1 -1
  146. data/src/core/load_balancing/pick_first/pick_first.cc +12 -5
  147. data/src/core/load_balancing/xds/xds_cluster_impl.cc +5 -3
  148. data/src/core/net/socket_mutator.cc +19 -0
  149. data/src/core/net/socket_mutator.h +25 -0
  150. data/src/core/plugin_registry/grpc_plugin_registry.cc +6 -0
  151. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver.h +6 -1
  152. data/src/core/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +2 -1
  153. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.cc +8 -5
  154. data/src/core/resolver/dns/c_ares/grpc_ares_wrapper.h +2 -1
  155. data/src/core/resolver/xds/xds_dependency_manager.cc +1 -1
  156. data/src/core/server/server.cc +1 -1
  157. data/src/core/server/server_call_tracer_filter.cc +0 -66
  158. data/src/core/server/server_call_tracer_filter.h +64 -0
  159. data/src/core/server/server_config_selector_filter.cc +1 -1
  160. data/src/core/service_config/service_config_channel_arg_filter.cc +3 -60
  161. data/src/core/service_config/service_config_channel_arg_filter.h +82 -0
  162. data/src/core/telemetry/call_tracer.cc +20 -14
  163. data/src/core/telemetry/call_tracer.h +22 -17
  164. data/src/core/telemetry/metrics.h +8 -8
  165. data/src/core/telemetry/stats_data.cc +151 -151
  166. data/src/core/telemetry/stats_data.h +87 -87
  167. data/src/core/transport/auth_context.cc +20 -0
  168. data/src/core/transport/auth_context.h +4 -0
  169. data/src/core/transport/auth_context_comparator_registry.h +69 -0
  170. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +2 -3
  171. data/src/core/tsi/ssl_transport_security.cc +202 -32
  172. data/src/core/tsi/ssl_transport_security.h +19 -10
  173. data/src/core/tsi/ssl_transport_security_utils.cc +21 -0
  174. data/src/core/tsi/ssl_transport_security_utils.h +4 -0
  175. data/src/core/util/http_client/httpcli_security_connector.cc +3 -1
  176. data/src/core/util/latent_see.cc +178 -146
  177. data/src/core/util/latent_see.h +245 -188
  178. data/src/core/util/single_set_ptr.h +5 -2
  179. data/src/core/util/useful.h +91 -0
  180. data/src/core/util/windows/directory_reader.cc +1 -0
  181. data/src/core/util/windows/thd.cc +1 -3
  182. data/src/core/util/work_serializer.cc +1 -1
  183. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.cc +32 -5
  184. data/src/core/xds/grpc/file_watcher_certificate_provider_factory.h +5 -0
  185. data/src/core/xds/grpc/xds_certificate_provider.cc +5 -6
  186. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  187. data/src/ruby/lib/grpc/version.rb +1 -1
  188. data/third_party/cares/cares/include/ares.h +925 -460
  189. data/third_party/cares/cares/include/ares_dns.h +86 -71
  190. data/third_party/cares/cares/include/ares_dns_record.h +1118 -0
  191. data/third_party/cares/cares/include/ares_nameser.h +215 -189
  192. data/third_party/cares/cares/include/ares_version.h +37 -14
  193. data/third_party/cares/cares/src/lib/ares_addrinfo2hostent.c +305 -0
  194. data/third_party/cares/cares/src/lib/ares_addrinfo_localhost.c +245 -0
  195. data/third_party/cares/cares/src/lib/ares_android.c +216 -164
  196. data/third_party/cares/cares/src/lib/ares_android.h +25 -14
  197. data/third_party/cares/cares/src/lib/ares_cancel.c +68 -44
  198. data/third_party/cares/cares/src/lib/ares_close_sockets.c +137 -0
  199. data/third_party/cares/cares/src/lib/ares_conn.c +511 -0
  200. data/third_party/cares/cares/src/lib/ares_conn.h +196 -0
  201. data/third_party/cares/cares/src/lib/ares_cookie.c +461 -0
  202. data/third_party/cares/cares/src/lib/ares_data.c +93 -181
  203. data/third_party/cares/cares/src/lib/ares_data.h +50 -39
  204. data/third_party/cares/cares/src/lib/ares_destroy.c +127 -89
  205. data/third_party/cares/cares/src/lib/ares_free_hostent.c +35 -24
  206. data/third_party/cares/cares/src/lib/ares_free_string.c +24 -16
  207. data/third_party/cares/cares/src/lib/ares_freeaddrinfo.c +45 -38
  208. data/third_party/cares/cares/src/lib/ares_getaddrinfo.c +549 -663
  209. data/third_party/cares/cares/src/lib/ares_getenv.c +25 -15
  210. data/third_party/cares/cares/src/lib/ares_getenv.h +26 -18
  211. data/third_party/cares/cares/src/lib/ares_gethostbyaddr.c +163 -221
  212. data/third_party/cares/cares/src/lib/ares_gethostbyname.c +222 -223
  213. data/third_party/cares/cares/src/lib/ares_getnameinfo.c +328 -338
  214. data/third_party/cares/cares/src/lib/ares_hosts_file.c +952 -0
  215. data/third_party/cares/cares/src/lib/ares_inet_net_pton.h +25 -19
  216. data/third_party/cares/cares/src/lib/ares_init.c +425 -2091
  217. data/third_party/cares/cares/src/lib/ares_ipv6.h +63 -33
  218. data/third_party/cares/cares/src/lib/ares_library_init.c +110 -54
  219. data/third_party/cares/cares/src/lib/ares_metrics.c +261 -0
  220. data/third_party/cares/cares/src/lib/ares_options.c +418 -332
  221. data/third_party/cares/cares/src/lib/ares_parse_into_addrinfo.c +179 -0
  222. data/third_party/cares/cares/src/lib/ares_private.h +558 -356
  223. data/third_party/cares/cares/src/lib/ares_process.c +1224 -1369
  224. data/third_party/cares/cares/src/lib/ares_qcache.c +430 -0
  225. data/third_party/cares/cares/src/lib/ares_query.c +126 -121
  226. data/third_party/cares/cares/src/lib/ares_search.c +564 -262
  227. data/third_party/cares/cares/src/lib/ares_send.c +264 -93
  228. data/third_party/cares/cares/src/lib/ares_set_socket_functions.c +588 -0
  229. data/third_party/cares/cares/src/lib/ares_setup.h +115 -111
  230. data/third_party/cares/cares/src/lib/ares_socket.c +425 -0
  231. data/third_party/cares/cares/src/lib/ares_socket.h +163 -0
  232. data/third_party/cares/cares/src/lib/ares_sortaddrinfo.c +447 -0
  233. data/third_party/cares/cares/src/lib/ares_strerror.c +83 -48
  234. data/third_party/cares/cares/src/lib/ares_sysconfig.c +639 -0
  235. data/third_party/cares/cares/src/lib/ares_sysconfig_files.c +839 -0
  236. data/third_party/cares/cares/src/lib/ares_sysconfig_mac.c +373 -0
  237. data/third_party/cares/cares/src/lib/ares_sysconfig_win.c +621 -0
  238. data/third_party/cares/cares/src/lib/ares_timeout.c +136 -73
  239. data/third_party/cares/cares/src/lib/ares_update_servers.c +1362 -0
  240. data/third_party/cares/cares/src/lib/ares_version.c +29 -4
  241. data/third_party/cares/cares/src/lib/config-dos.h +88 -89
  242. data/third_party/cares/cares/src/lib/config-win32.h +122 -77
  243. data/third_party/cares/cares/src/lib/dsa/ares_array.c +394 -0
  244. data/third_party/cares/cares/src/lib/dsa/ares_htable.c +447 -0
  245. data/third_party/cares/cares/src/lib/dsa/ares_htable.h +174 -0
  246. data/third_party/cares/cares/src/lib/dsa/ares_htable_asvp.c +224 -0
  247. data/third_party/cares/cares/src/lib/dsa/ares_htable_dict.c +228 -0
  248. data/third_party/cares/cares/src/lib/dsa/ares_htable_strvp.c +210 -0
  249. data/third_party/cares/cares/src/lib/dsa/ares_htable_szvp.c +188 -0
  250. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpstr.c +186 -0
  251. data/third_party/cares/cares/src/lib/dsa/ares_htable_vpvp.c +194 -0
  252. data/third_party/cares/cares/src/lib/dsa/ares_llist.c +382 -0
  253. data/third_party/cares/cares/src/lib/dsa/ares_slist.c +479 -0
  254. data/third_party/cares/cares/src/lib/dsa/ares_slist.h +207 -0
  255. data/third_party/cares/cares/src/lib/event/ares_event.h +191 -0
  256. data/third_party/cares/cares/src/lib/event/ares_event_configchg.c +743 -0
  257. data/third_party/cares/cares/src/lib/event/ares_event_epoll.c +192 -0
  258. data/third_party/cares/cares/src/lib/event/ares_event_kqueue.c +248 -0
  259. data/third_party/cares/cares/src/lib/event/ares_event_poll.c +140 -0
  260. data/third_party/cares/cares/src/lib/event/ares_event_select.c +159 -0
  261. data/third_party/cares/cares/src/lib/event/ares_event_thread.c +567 -0
  262. data/third_party/cares/cares/src/lib/event/ares_event_wake_pipe.c +166 -0
  263. data/third_party/cares/cares/src/lib/event/ares_event_win32.c +978 -0
  264. data/third_party/cares/cares/src/lib/event/ares_event_win32.h +161 -0
  265. data/third_party/cares/cares/src/lib/include/ares_array.h +276 -0
  266. data/third_party/cares/cares/src/lib/include/ares_buf.h +732 -0
  267. data/third_party/cares/cares/src/lib/include/ares_htable_asvp.h +130 -0
  268. data/third_party/cares/cares/src/lib/include/ares_htable_dict.h +123 -0
  269. data/third_party/cares/cares/src/lib/include/ares_htable_strvp.h +130 -0
  270. data/third_party/cares/cares/src/lib/include/ares_htable_szvp.h +118 -0
  271. data/third_party/cares/cares/src/lib/include/ares_htable_vpstr.h +111 -0
  272. data/third_party/cares/cares/src/lib/include/ares_htable_vpvp.h +128 -0
  273. data/third_party/cares/cares/src/lib/include/ares_llist.h +239 -0
  274. data/third_party/cares/cares/src/lib/include/ares_mem.h +38 -0
  275. data/third_party/cares/cares/src/lib/include/ares_str.h +244 -0
  276. data/third_party/cares/cares/src/lib/inet_net_pton.c +202 -157
  277. data/third_party/cares/cares/src/lib/inet_ntop.c +87 -69
  278. data/third_party/cares/cares/src/lib/legacy/ares_create_query.c +78 -0
  279. data/third_party/cares/cares/src/lib/legacy/ares_expand_name.c +99 -0
  280. data/third_party/cares/cares/src/lib/legacy/ares_expand_string.c +107 -0
  281. data/third_party/cares/cares/src/lib/legacy/ares_fds.c +80 -0
  282. data/third_party/cares/cares/src/lib/legacy/ares_getsock.c +85 -0
  283. data/third_party/cares/cares/src/lib/legacy/ares_parse_a_reply.c +107 -0
  284. data/third_party/cares/cares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
  285. data/third_party/cares/cares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
  286. data/third_party/cares/cares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
  287. data/third_party/cares/cares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
  288. data/third_party/cares/cares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
  289. data/third_party/cares/cares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
  290. data/third_party/cares/cares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
  291. data/third_party/cares/cares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
  292. data/third_party/cares/cares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
  293. data/third_party/cares/cares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
  294. data/third_party/cares/cares/src/lib/record/ares_dns_mapping.c +982 -0
  295. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.c +307 -0
  296. data/third_party/cares/cares/src/lib/record/ares_dns_multistring.h +72 -0
  297. data/third_party/cares/cares/src/lib/record/ares_dns_name.c +673 -0
  298. data/third_party/cares/cares/src/lib/record/ares_dns_parse.c +1329 -0
  299. data/third_party/cares/cares/src/lib/record/ares_dns_private.h +273 -0
  300. data/third_party/cares/cares/src/lib/record/ares_dns_record.c +1661 -0
  301. data/third_party/cares/cares/src/lib/record/ares_dns_write.c +1229 -0
  302. data/third_party/cares/cares/src/lib/str/ares_buf.c +1498 -0
  303. data/third_party/cares/cares/src/lib/str/ares_str.c +508 -0
  304. data/third_party/cares/cares/src/lib/str/ares_strsplit.c +90 -0
  305. data/third_party/cares/cares/src/lib/str/ares_strsplit.h +51 -0
  306. data/third_party/cares/cares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
  307. data/third_party/cares/cares/src/lib/util/ares_iface_ips.c +628 -0
  308. data/third_party/cares/cares/src/lib/util/ares_iface_ips.h +139 -0
  309. data/third_party/cares/cares/src/lib/util/ares_math.c +158 -0
  310. data/third_party/cares/cares/src/lib/util/ares_math.h +45 -0
  311. data/third_party/cares/cares/src/lib/util/ares_rand.c +389 -0
  312. data/third_party/cares/cares/src/lib/util/ares_rand.h +36 -0
  313. data/third_party/cares/cares/src/lib/util/ares_threads.c +614 -0
  314. data/third_party/cares/cares/src/lib/util/ares_threads.h +60 -0
  315. data/third_party/cares/cares/src/lib/util/ares_time.h +48 -0
  316. data/third_party/cares/cares/src/lib/util/ares_timeval.c +95 -0
  317. data/third_party/cares/cares/src/lib/util/ares_uri.c +1626 -0
  318. data/third_party/cares/cares/src/lib/util/ares_uri.h +252 -0
  319. data/third_party/cares/cares/src/lib/windows_port.c +16 -9
  320. metadata +121 -49
  321. data/src/core/util/ring_buffer.h +0 -122
  322. data/third_party/cares/cares/include/ares_rules.h +0 -125
  323. data/third_party/cares/cares/src/lib/ares__addrinfo2hostent.c +0 -266
  324. data/third_party/cares/cares/src/lib/ares__addrinfo_localhost.c +0 -240
  325. data/third_party/cares/cares/src/lib/ares__close_sockets.c +0 -61
  326. data/third_party/cares/cares/src/lib/ares__get_hostent.c +0 -260
  327. data/third_party/cares/cares/src/lib/ares__parse_into_addrinfo.c +0 -229
  328. data/third_party/cares/cares/src/lib/ares__read_line.c +0 -73
  329. data/third_party/cares/cares/src/lib/ares__readaddrinfo.c +0 -258
  330. data/third_party/cares/cares/src/lib/ares__sortaddrinfo.c +0 -507
  331. data/third_party/cares/cares/src/lib/ares__timeval.c +0 -111
  332. data/third_party/cares/cares/src/lib/ares_create_query.c +0 -197
  333. data/third_party/cares/cares/src/lib/ares_expand_name.c +0 -311
  334. data/third_party/cares/cares/src/lib/ares_expand_string.c +0 -67
  335. data/third_party/cares/cares/src/lib/ares_fds.c +0 -59
  336. data/third_party/cares/cares/src/lib/ares_getsock.c +0 -66
  337. data/third_party/cares/cares/src/lib/ares_iphlpapi.h +0 -221
  338. data/third_party/cares/cares/src/lib/ares_llist.c +0 -63
  339. data/third_party/cares/cares/src/lib/ares_llist.h +0 -39
  340. data/third_party/cares/cares/src/lib/ares_mkquery.c +0 -24
  341. data/third_party/cares/cares/src/lib/ares_nowarn.c +0 -260
  342. data/third_party/cares/cares/src/lib/ares_nowarn.h +0 -61
  343. data/third_party/cares/cares/src/lib/ares_parse_a_reply.c +0 -90
  344. data/third_party/cares/cares/src/lib/ares_parse_aaaa_reply.c +0 -92
  345. data/third_party/cares/cares/src/lib/ares_parse_caa_reply.c +0 -199
  346. data/third_party/cares/cares/src/lib/ares_parse_mx_reply.c +0 -164
  347. data/third_party/cares/cares/src/lib/ares_parse_naptr_reply.c +0 -183
  348. data/third_party/cares/cares/src/lib/ares_parse_ns_reply.c +0 -177
  349. data/third_party/cares/cares/src/lib/ares_parse_ptr_reply.c +0 -228
  350. data/third_party/cares/cares/src/lib/ares_parse_soa_reply.c +0 -179
  351. data/third_party/cares/cares/src/lib/ares_parse_srv_reply.c +0 -168
  352. data/third_party/cares/cares/src/lib/ares_parse_txt_reply.c +0 -214
  353. data/third_party/cares/cares/src/lib/ares_parse_uri_reply.c +0 -184
  354. data/third_party/cares/cares/src/lib/ares_platform.c +0 -11042
  355. data/third_party/cares/cares/src/lib/ares_platform.h +0 -43
  356. data/third_party/cares/cares/src/lib/ares_rand.c +0 -279
  357. data/third_party/cares/cares/src/lib/ares_strcasecmp.c +0 -66
  358. data/third_party/cares/cares/src/lib/ares_strcasecmp.h +0 -30
  359. data/third_party/cares/cares/src/lib/ares_strdup.c +0 -42
  360. data/third_party/cares/cares/src/lib/ares_strdup.h +0 -24
  361. data/third_party/cares/cares/src/lib/ares_strsplit.c +0 -94
  362. data/third_party/cares/cares/src/lib/ares_strsplit.h +0 -42
  363. data/third_party/cares/cares/src/lib/ares_writev.c +0 -79
  364. data/third_party/cares/cares/src/lib/ares_writev.h +0 -36
  365. data/third_party/cares/cares/src/lib/bitncmp.c +0 -59
  366. data/third_party/cares/cares/src/lib/bitncmp.h +0 -26
  367. data/third_party/cares/cares/src/lib/setup_once.h +0 -554
  368. data/third_party/cares/cares/src/tools/ares_getopt.h +0 -53
@@ -0,0 +1,607 @@
1
+ //
2
+ //
3
+ // Copyright 2025 gRPC authors.
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ //
17
+ //
18
+
19
+ #ifndef GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_STREAM_DATA_QUEUE_H
20
+ #define GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_STREAM_DATA_QUEUE_H
21
+
22
+ #include <queue>
23
+
24
+ #include "absl/log/check.h"
25
+ #include "absl/log/log.h"
26
+ #include "src/core/ext/transport/chttp2/transport/header_assembler.h"
27
+ #include "src/core/ext/transport/chttp2/transport/message_assembler.h"
28
+
29
+ namespace grpc_core {
30
+ namespace http2 {
31
+
32
+ #define GRPC_STREAM_DATA_QUEUE_DEBUG VLOG(2)
33
+
34
+ // SimpleQueue is a NOT thread safe.
35
+ // Note: SimpleQueue is a single producer single consumer queue.
36
+ template <typename T>
37
+ class SimpleQueue {
38
+ public:
39
+ struct EnqueueResult {
40
+ absl::Status status;
41
+ bool became_non_empty;
42
+ };
43
+
44
+ explicit SimpleQueue(const uint32_t max_tokens) : max_tokens_(max_tokens) {}
45
+ SimpleQueue(SimpleQueue&& rhs) = delete;
46
+ SimpleQueue& operator=(SimpleQueue&& rhs) = delete;
47
+ SimpleQueue(const SimpleQueue&) = delete;
48
+ SimpleQueue& operator=(const SimpleQueue&) = delete;
49
+
50
+ // A promise that resolves when the data is enqueued.
51
+ // If tokens_consumed_ is 0 or the new tokens fit within max_tokens_, then
52
+ // allow the enqueue to go through. Otherwise, return pending. Here, we are
53
+ // using tokens_consumed over queue_.empty() because there can be enqueues
54
+ // with tokens = 0. Enqueues with tokens = 0 are primarily for sending
55
+ // metadata as flow control does not apply to them. This function is NOT
56
+ // thread safe.
57
+ auto Enqueue(T& data, const uint32_t tokens) {
58
+ return PollEnqueue(data, tokens);
59
+ }
60
+
61
+ // Sync function to dequeue the next entry. Returns nullopt if the queue is
62
+ // empty or if the front of the queue has more tokens than
63
+ // allowed_dequeue_tokens. When allow_oversized_dequeue parameter is set to
64
+ // true, it allows an item to be dequeued even if its token cost is greater
65
+ // than allowed_dequeue_tokens. It does not cause the item itself to be
66
+ // partially dequeued; either the entire item is returned or nullopt is
67
+ // returned. This function is NOT thread safe.
68
+ std::optional<T> Dequeue(const uint32_t allowed_dequeue_tokens,
69
+ const bool allow_oversized_dequeue) {
70
+ return DequeueInternal(allowed_dequeue_tokens, allow_oversized_dequeue);
71
+ }
72
+
73
+ // Dequeues the next entry immediately ignoring the tokens. If the queue is
74
+ // empty, returns nullopt. This function is NOT thread safe.
75
+ std::optional<T> ImmediateDequeue() {
76
+ return DequeueInternal(std::numeric_limits<uint32_t>::max(), true);
77
+ }
78
+
79
+ // Returns true if the queue is empty. This function is NOT thread safe.
80
+ bool TestOnlyIsEmpty() const { return IsEmpty(); }
81
+
82
+ private:
83
+ Poll<EnqueueResult> PollEnqueue(T& data, const uint32_t tokens) {
84
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Enqueueing data. Data tokens: " << tokens;
85
+ const uint32_t max_tokens_consumed_threshold =
86
+ max_tokens_ >= tokens ? max_tokens_ - tokens : 0;
87
+ if (tokens_consumed_ == 0 ||
88
+ tokens_consumed_ <= max_tokens_consumed_threshold) {
89
+ tokens_consumed_ += tokens;
90
+ queue_.emplace(Entry{std::move(data), tokens});
91
+ GRPC_STREAM_DATA_QUEUE_DEBUG
92
+ << "Enqueue successful. Data tokens: " << tokens
93
+ << " Current tokens consumed: " << tokens_consumed_;
94
+ return EnqueueResult{absl::OkStatus(),
95
+ /*became_non_empty=*/queue_.size() == 1};
96
+ }
97
+
98
+ GRPC_STREAM_DATA_QUEUE_DEBUG
99
+ << "Token threshold reached. Data tokens: " << tokens
100
+ << " Tokens consumed: " << tokens_consumed_
101
+ << " Max tokens: " << max_tokens_;
102
+ waker_ = GetContext<Activity>()->MakeNonOwningWaker();
103
+ return Pending{};
104
+ }
105
+
106
+ std::optional<T> DequeueInternal(const uint32_t allowed_dequeue_tokens,
107
+ const bool allow_oversized_dequeue) {
108
+ if (queue_.empty() || (queue_.front().tokens > allowed_dequeue_tokens &&
109
+ !allow_oversized_dequeue)) {
110
+ GRPC_STREAM_DATA_QUEUE_DEBUG
111
+ << "Dequeueing data. Queue size: " << queue_.size()
112
+ << " Max allowed dequeue tokens: " << allowed_dequeue_tokens
113
+ << " Front tokens: "
114
+ << (!queue_.empty() ? std::to_string(queue_.front().tokens)
115
+ : std::string("NA"))
116
+ << " Allow oversized dequeue: " << allow_oversized_dequeue;
117
+ return std::nullopt;
118
+ }
119
+
120
+ auto entry = std::move(queue_.front());
121
+ queue_.pop();
122
+ tokens_consumed_ -= entry.tokens;
123
+ auto waker = std::move(waker_);
124
+ GRPC_STREAM_DATA_QUEUE_DEBUG
125
+ << "Dequeue successful. Data tokens released: " << entry.tokens
126
+ << " Current tokens consumed: " << tokens_consumed_;
127
+
128
+ // TODO(akshitpatel) : [PH2][P2] : Investigate a mechanism to only wake up
129
+ // if the sender will be able to send more data. There is a high chance that
130
+ // this queue is revamped soon and so not spending time on optimization
131
+ // right now.
132
+ waker.Wakeup();
133
+ return std::move(entry.data);
134
+ }
135
+
136
+ bool IsEmpty() const { return queue_.empty(); }
137
+
138
+ struct Entry {
139
+ T data;
140
+ uint32_t tokens;
141
+ };
142
+
143
+ std::queue<Entry> queue_;
144
+ // The maximum number of tokens that can be enqueued. This limit is used to
145
+ // exert back pressure on the sender. If the sender tries to enqueue more
146
+ // tokens than this limit, the enqueue promise will not resolve until the
147
+ // required number of tokens are consumed by the receiver. There is an
148
+ // exception to this rule: if the sender tries to enqueue an item when the
149
+ // queue has 0 tokens, the enqueue will always go through regardless of the
150
+ // number of tokens.
151
+ uint32_t max_tokens_;
152
+ // The number of tokens that have been enqueued in the queue but not yet
153
+ // dequeued.
154
+ uint32_t tokens_consumed_ = 0;
155
+ Waker waker_;
156
+ };
157
+
158
+ // StreamDataQueue is a thread safe.
159
+ // Note: StreamDataQueue is a single producer single
160
+ // consumer queue.
161
+ template <typename MetadataHandle>
162
+ class StreamDataQueue : public RefCounted<StreamDataQueue<MetadataHandle>> {
163
+ public:
164
+ explicit StreamDataQueue(const bool is_client, const uint32_t stream_id,
165
+ const uint32_t queue_size)
166
+ : stream_id_(stream_id),
167
+ is_client_(is_client),
168
+ queue_(queue_size),
169
+ initial_metadata_disassembler_(stream_id,
170
+ /*is_trailing_metadata=*/false),
171
+ trailing_metadata_disassembler_(stream_id,
172
+ /*is_trailing_metadata=*/true) {};
173
+ ~StreamDataQueue() = default;
174
+
175
+ StreamDataQueue(StreamDataQueue&& rhs) = delete;
176
+ StreamDataQueue& operator=(StreamDataQueue&& rhs) = delete;
177
+ StreamDataQueue(const StreamDataQueue&) = delete;
178
+ StreamDataQueue& operator=(const StreamDataQueue&) = delete;
179
+
180
+ //////////////////////////////////////////////////////////////////////////////
181
+ // Enqueue Helpers
182
+ // These enqueue helpers are based on following assumptions:
183
+ // 1. The ordering of initial metadata, messages and trailing metadata is
184
+ // taken care by the Callv-3 stack.
185
+ // 2. Initial metadata MUST be enqueued before the first message.
186
+ // 3. Initial metadata and trailing metadata are both optional. A server can
187
+ // skip initial metadata and a client will never send trailing metadata.
188
+ // 4. A server will never send half close.
189
+ // 5. Trailing metadata/HalfClose/ResetStream MUST be enqueued at most once
190
+ // per stream.
191
+ // 6. After trailing metadata/HalfClose only ResetStream MAY be enqueued.
192
+ // 7. The ResetStream MUST be the final thing that is queued.
193
+ // 8. Currently initial metadata is not expected to be enqueued with
194
+ // end_stream set. If the stream needs to be half closed, the client should
195
+ // enqueue a half close message.
196
+
197
+ // Enqueue Initial Metadata.
198
+ // 1. MUST be called at most once.
199
+ // 2. This MUST be called before any messages are enqueued.
200
+ // 3. MUST not be called after trailing metadata is enqueued.
201
+ // 4. This function is thread safe.
202
+ auto EnqueueInitialMetadata(MetadataHandle metadata) {
203
+ DCHECK(!is_initial_metadata_queued_);
204
+ DCHECK(!is_trailing_metadata_or_half_close_queued_);
205
+ DCHECK(metadata != nullptr);
206
+ DCHECK(!is_reset_stream_queued_);
207
+
208
+ is_initial_metadata_queued_ = true;
209
+ return [self = this->Ref(),
210
+ entry = QueueEntry{InitialMetadataType{
211
+ std::move(metadata)}}]() mutable -> Poll<absl::StatusOr<bool>> {
212
+ MutexLock lock(&self->mu_);
213
+ auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
214
+ if (result.ready()) {
215
+ GRPC_STREAM_DATA_QUEUE_DEBUG
216
+ << "Enqueued initial metadata for stream " << self->stream_id_
217
+ << " with status: " << result.value().status;
218
+ if (result.value().status.ok()) {
219
+ DCHECK(result.value().became_non_empty);
220
+ return self->UpdateWritableStateLocked(
221
+ result.value().became_non_empty);
222
+ }
223
+ return result.value().status;
224
+ }
225
+ return Pending{};
226
+ };
227
+ }
228
+
229
+ // Enqueue Trailing Metadata.
230
+ // 1. MUST be called at most once.
231
+ // 2. MUST be called only for a server.
232
+ // 3. This function is thread safe.
233
+ auto EnqueueTrailingMetadata(MetadataHandle metadata) {
234
+ DCHECK(metadata != nullptr);
235
+ DCHECK(!is_reset_stream_queued_);
236
+ DCHECK(!is_client_);
237
+ DCHECK(!is_trailing_metadata_or_half_close_queued_);
238
+
239
+ is_trailing_metadata_or_half_close_queued_ = true;
240
+ return [self = this->Ref(),
241
+ entry = QueueEntry{TrailingMetadataType{
242
+ std::move(metadata)}}]() mutable -> Poll<absl::StatusOr<bool>> {
243
+ MutexLock lock(&self->mu_);
244
+ auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
245
+ if (result.ready()) {
246
+ GRPC_STREAM_DATA_QUEUE_DEBUG
247
+ << "Enqueued trailing metadata for stream " << self->stream_id_
248
+ << " with status: " << result.value().status;
249
+ if (result.value().status.ok()) {
250
+ return self->UpdateWritableStateLocked(
251
+ result.value().became_non_empty);
252
+ }
253
+ return result.value().status;
254
+ }
255
+ return Pending{};
256
+ };
257
+ }
258
+
259
+ // Returns a promise that resolves when the message is enqueued. There may be
260
+ // delays in queueing the message if data queue is full.
261
+ // 1. MUST be called after initial metadata is enqueued.
262
+ // 2. MUST not be called after trailing metadata is enqueued.
263
+ // 3. This function is thread safe.
264
+ auto EnqueueMessage(MessageHandle message) {
265
+ DCHECK(is_initial_metadata_queued_);
266
+ DCHECK(message != nullptr);
267
+ DCHECK(!is_reset_stream_queued_);
268
+ DCHECK_LE(message->payload()->Length(),
269
+ std::numeric_limits<uint32_t>::max() - kGrpcHeaderSizeInBytes);
270
+ DCHECK(!is_trailing_metadata_or_half_close_queued_);
271
+
272
+ const uint32_t tokens =
273
+ message->payload()->Length() + kGrpcHeaderSizeInBytes;
274
+ return [self = this->Ref(), entry = QueueEntry{std::move(message)},
275
+ tokens]() mutable -> Poll<absl::StatusOr<bool>> {
276
+ MutexLock lock(&self->mu_);
277
+ auto result = self->queue_.Enqueue(entry, tokens);
278
+ if (result.ready()) {
279
+ GRPC_STREAM_DATA_QUEUE_DEBUG
280
+ << "Enqueued message for stream " << self->stream_id_
281
+ << " with status: " << result.value().status;
282
+ // TODO(akshitpatel) : [PH2][P2] : Add check for flow control tokens.
283
+ if (result.value().status.ok()) {
284
+ return self->UpdateWritableStateLocked(
285
+ result.value().became_non_empty);
286
+ }
287
+ return result.value().status;
288
+ }
289
+ return Pending{};
290
+ };
291
+ }
292
+
293
+ // Enqueue Half Closed.
294
+ // 1. MUST be called at most once.
295
+ // 2. MUST be called only for a client.
296
+ // 3. This function is thread safe.
297
+ auto EnqueueHalfClosed() {
298
+ DCHECK(is_initial_metadata_queued_);
299
+ DCHECK(is_client_);
300
+ DCHECK(!is_reset_stream_queued_);
301
+ DCHECK(!is_trailing_metadata_or_half_close_queued_);
302
+
303
+ is_trailing_metadata_or_half_close_queued_ = true;
304
+ return [self = this->Ref(), entry = QueueEntry{HalfClosed{}}]() mutable
305
+ -> Poll<absl::StatusOr<bool>> {
306
+ MutexLock lock(&self->mu_);
307
+ auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
308
+ if (result.ready()) {
309
+ GRPC_STREAM_DATA_QUEUE_DEBUG
310
+ << "Marking stream " << self->stream_id_ << " as half closed"
311
+ << " with status: " << result.value().status;
312
+ if (result.value().status.ok()) {
313
+ return self->UpdateWritableStateLocked(
314
+ result.value().became_non_empty);
315
+ }
316
+ return result.value().status;
317
+ }
318
+ return Pending{};
319
+ };
320
+ }
321
+
322
+ // Enqueue Reset Stream.
323
+ // 1. MUST be called at most once.
324
+ // 3. This function is thread safe.
325
+ auto EnqueueResetStream(uint32_t error_code) {
326
+ DCHECK(is_initial_metadata_queued_);
327
+ DCHECK(!is_reset_stream_queued_);
328
+
329
+ is_reset_stream_queued_ = true;
330
+ return [self = this->Ref(),
331
+ entry = QueueEntry{ResetStream{
332
+ error_code}}]() mutable -> Poll<absl::StatusOr<bool>> {
333
+ MutexLock lock(&self->mu_);
334
+ auto result = self->queue_.Enqueue(entry, /*tokens=*/0);
335
+ if (result.ready()) {
336
+ GRPC_STREAM_DATA_QUEUE_DEBUG
337
+ << "Enqueueing reset stream for stream " << self->stream_id_
338
+ << " with status: " << result.value().status;
339
+ if (result.value().status.ok()) {
340
+ return self->UpdateWritableStateLocked(
341
+ result.value().became_non_empty);
342
+ }
343
+ return result.value().status;
344
+ }
345
+ return Pending{};
346
+ };
347
+ }
348
+
349
+ //////////////////////////////////////////////////////////////////////////////
350
+ // Dequeue Helpers
351
+
352
+ // TODO(akshitpatel) : [PH2][P2] : Decide on whether it is needed to return
353
+ // the number of tokens consumed by one call of this function.
354
+ struct DequeueResult {
355
+ std::vector<Http2Frame> frames;
356
+ bool is_writable;
357
+ };
358
+
359
+ // TODO(akshitpatel) : [PH2][P4] : Measure the performance of this function
360
+ // and optimize it if needed.
361
+
362
+ // This function is deliberately a synchronous call. The caller of this
363
+ // function should not be blocked till we have enough data to return. This is
364
+ // because the caller needs to dequeue frames from multiple streams in a
365
+ // single cycle. The goal here is to return as much data as possible in one go
366
+ // with max_tokens as the upper limit. General idea: Out goal here is to push
367
+ // as much data as possible with max_tokens as the upper limit. Though we will
368
+ // not prefer sending incomplete messages. We handle the scenario of
369
+ // incomplete messages in the following way:
370
+ // 1. If we have sent x full messages and available flow control tokens cannot
371
+ // accommodate x+1 message, we will not dequeue the x+1st message and
372
+ // create frames for x messages.
373
+ // 2. If the flow control tokens cannot accommodate first message, we
374
+ // dequeue the first message from the queue and create frames for
375
+ // the partial first message (sum of payload of all returned frames <=
376
+ // max_fc_tokens).
377
+ // This function is thread safe.
378
+ absl::StatusOr<DequeueResult> DequeueFrames(const uint32_t max_fc_tokens,
379
+ const uint32_t max_frame_length,
380
+ HPackCompressor& encoder) {
381
+ MutexLock lock(&mu_);
382
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Dequeueing frames for stream "
383
+ << stream_id_
384
+ << " Max fc tokens: " << max_fc_tokens
385
+ << " Max frame length: " << max_frame_length
386
+ << " Message disassembler buffered length: "
387
+ << message_disassembler_.GetBufferedLength();
388
+
389
+ HandleDequeue handle_dequeue(max_fc_tokens, max_frame_length, encoder,
390
+ *this);
391
+ while (message_disassembler_.GetBufferedLength() <= max_fc_tokens) {
392
+ const uint32_t tokens_to_dequeue =
393
+ max_fc_tokens - message_disassembler_.GetBufferedLength();
394
+ std::optional<QueueEntry> queue_entry =
395
+ queue_.Dequeue(tokens_to_dequeue, /*allow_oversized_dequeue*/ (
396
+ message_disassembler_.GetBufferedLength() == 0 &&
397
+ tokens_to_dequeue > 0));
398
+ if (!queue_entry.has_value()) {
399
+ // Nothing more to dequeue right now.
400
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "No more data to dequeue";
401
+ break;
402
+ }
403
+ std::visit(handle_dequeue, std::move(*queue_entry));
404
+ }
405
+
406
+ // TODO(akshitpatel) : [PH2][P2] : Add a check for flow control tokens.
407
+ is_writable_ = false;
408
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Stream id: " << stream_id_
409
+ << " writable state changed to "
410
+ << is_writable_;
411
+ return DequeueResult{handle_dequeue.GetFrames(), is_writable_};
412
+ }
413
+
414
+ // Returns true if the queue is empty. This function is thread safe.
415
+ bool TestOnlyIsEmpty() {
416
+ MutexLock lock(&mu_);
417
+ return queue_.TestOnlyIsEmpty();
418
+ }
419
+
420
+ private:
421
+ struct InitialMetadataType {
422
+ MetadataHandle metadata;
423
+ };
424
+ struct TrailingMetadataType {
425
+ MetadataHandle metadata;
426
+ };
427
+ struct HalfClosed {};
428
+ struct ResetStream {
429
+ uint32_t error_code;
430
+ };
431
+ using QueueEntry = std::variant<InitialMetadataType, TrailingMetadataType,
432
+ MessageHandle, HalfClosed, ResetStream>;
433
+
434
+ class HandleDequeue {
435
+ public:
436
+ HandleDequeue(uint32_t max_tokens, uint32_t max_frame_length,
437
+ HPackCompressor& encoder, StreamDataQueue& queue)
438
+ : queue_(queue),
439
+ max_frame_length_(max_frame_length),
440
+ max_fc_tokens_(max_tokens),
441
+ fc_tokens_available_(max_tokens),
442
+ encoder_(encoder) {}
443
+
444
+ void operator()(InitialMetadataType initial_metadata) {
445
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing initial metadata for sending";
446
+ queue_.initial_metadata_disassembler_.PrepareForSending(
447
+ std::move(initial_metadata.metadata), encoder_);
448
+ MaybeAppendInitialMetadataFrames();
449
+ }
450
+
451
+ void operator()(TrailingMetadataType trailing_metadata) {
452
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing trailing metadata for sending";
453
+ queue_.trailing_metadata_disassembler_.PrepareForSending(
454
+ std::move(trailing_metadata.metadata), encoder_);
455
+ }
456
+
457
+ void operator()(MessageHandle message) {
458
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing message for sending";
459
+ queue_.message_disassembler_.PrepareBatchedMessageForSending(
460
+ std::move(message));
461
+ }
462
+
463
+ void operator()(GRPC_UNUSED HalfClosed half_closed) {
464
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing end of stream for sending";
465
+ is_half_closed_ = true;
466
+ }
467
+
468
+ void operator()(ResetStream reset_stream) {
469
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Preparing reset stream for sending";
470
+ is_reset_stream_ = true;
471
+ error_code_ = reset_stream.error_code;
472
+ }
473
+
474
+ std::vector<Http2Frame> GetFrames() {
475
+ // TODO(akshitpatel) : [PH2][P3] : There is a second option here. We can
476
+ // only append messages here. Additionally, when Trailing
477
+ // Metadata/HalfClose/ResetStream is dequeued, we can first flush the
478
+ // buffered messages and then append the respective frames. This will
479
+ // ensure that we do not break the ordering of the queue.
480
+
481
+ // Order of appending frames is important. There may be scenarios where a
482
+ // reset stream frames is appended after HalfClose or Trailing Metadata.
483
+ MaybeAppendMessageFrames();
484
+ MaybeAppendEndOfStreamFrame();
485
+ MaybeAppendTrailingMetadataFrames();
486
+ MaybeAppendResetStreamFrame();
487
+ return std::move(frames_);
488
+ }
489
+
490
+ private:
491
+ inline void MaybeAppendInitialMetadataFrames() {
492
+ while (queue_.initial_metadata_disassembler_.HasMoreData()) {
493
+ DCHECK(!is_half_closed_);
494
+ DCHECK(!is_reset_stream_);
495
+ // TODO(akshitpatel) : [PH2][P2] : I do not think we need this.
496
+ // HasMoreData() should be enough.
497
+ bool is_end_headers = false;
498
+ frames_.emplace_back(queue_.initial_metadata_disassembler_.GetNextFrame(
499
+ max_frame_length_, is_end_headers));
500
+ }
501
+ }
502
+
503
+ inline void MaybeAppendTrailingMetadataFrames() {
504
+ while (queue_.trailing_metadata_disassembler_.HasMoreData()) {
505
+ DCHECK(!is_half_closed_);
506
+ DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
507
+ DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
508
+ 0u);
509
+ // TODO(akshitpatel) : [PH2][P2] : I do not think we need this.
510
+ // HasMoreData() should be enough.
511
+ bool is_end_headers = false;
512
+ frames_.emplace_back(
513
+ queue_.trailing_metadata_disassembler_.GetNextFrame(
514
+ max_frame_length_, is_end_headers));
515
+ }
516
+ }
517
+
518
+ inline void MaybeAppendEndOfStreamFrame() {
519
+ if (is_half_closed_) {
520
+ DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
521
+ DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
522
+ 0u);
523
+ DCHECK_EQ(queue_.trailing_metadata_disassembler_.GetBufferedLength(),
524
+ 0u);
525
+ frames_.emplace_back(Http2DataFrame{/*stream_id=*/queue_.stream_id_,
526
+ /*end_stream=*/true,
527
+ /*payload=*/SliceBuffer()});
528
+ }
529
+ }
530
+
531
+ inline void MaybeAppendMessageFrames() {
532
+ while (queue_.message_disassembler_.GetBufferedLength() > 0 &&
533
+ fc_tokens_available_ > 0) {
534
+ DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
535
+ 0u);
536
+ Http2DataFrame frame = queue_.message_disassembler_.GenerateNextFrame(
537
+ queue_.stream_id_,
538
+ std::min(fc_tokens_available_, max_frame_length_));
539
+ fc_tokens_available_ -= frame.payload.Length();
540
+ GRPC_STREAM_DATA_QUEUE_DEBUG
541
+ << "Appending message frame with length " << frame.payload.Length()
542
+ << "Available tokens: " << fc_tokens_available_;
543
+ frames_.emplace_back(std::move(frame));
544
+ }
545
+ }
546
+
547
+ inline void MaybeAppendResetStreamFrame() {
548
+ if (is_reset_stream_) {
549
+ // TODO(akshitpatel) : [PH2][P2] : Consider if we can send reset stream
550
+ // frame without flushing all the messages enqueued until now.
551
+ DCHECK_EQ(queue_.message_disassembler_.GetBufferedLength(), 0u);
552
+ DCHECK_EQ(queue_.initial_metadata_disassembler_.GetBufferedLength(),
553
+ 0u);
554
+ DCHECK_EQ(queue_.trailing_metadata_disassembler_.GetBufferedLength(),
555
+ 0u);
556
+ frames_.emplace_back(
557
+ Http2RstStreamFrame{queue_.stream_id_, error_code_});
558
+ }
559
+ }
560
+
561
+ StreamDataQueue& queue_;
562
+ const uint32_t max_frame_length_;
563
+ const uint32_t max_fc_tokens_;
564
+ uint32_t fc_tokens_available_;
565
+ bool is_half_closed_ = false;
566
+ bool is_reset_stream_ = false;
567
+ uint32_t error_code_ = static_cast<uint32_t>(Http2ErrorCode::kNoError);
568
+ std::vector<Http2Frame> frames_;
569
+ HPackCompressor& encoder_;
570
+ };
571
+
572
+ // Returns true if the queue is now writable. It is expected that the caller
573
+ // will hold the lock on the queue when calling this function.
574
+ bool UpdateWritableStateLocked(const bool became_non_empty)
575
+ ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
576
+ if (!is_writable_ && became_non_empty) {
577
+ GRPC_STREAM_DATA_QUEUE_DEBUG << "Stream id: " << stream_id_
578
+ << " writeable state changed to true";
579
+ is_writable_ = true;
580
+ return true;
581
+ }
582
+ return false;
583
+ }
584
+
585
+ const uint32_t stream_id_;
586
+ const bool is_client_;
587
+
588
+ // Accessed only during enqueue.
589
+ bool is_initial_metadata_queued_ = false;
590
+ bool is_trailing_metadata_or_half_close_queued_ = false;
591
+ bool is_reset_stream_queued_ = false;
592
+
593
+ // Access both during enqueue and dequeue.
594
+ Mutex mu_;
595
+ bool is_writable_ ABSL_GUARDED_BY(mu_) = false;
596
+ SimpleQueue<QueueEntry> queue_;
597
+
598
+ // Accessed only during dequeue.
599
+ HeaderDisassembler initial_metadata_disassembler_;
600
+ HeaderDisassembler trailing_metadata_disassembler_;
601
+ GrpcMessageDisassembler message_disassembler_;
602
+ };
603
+
604
+ } // namespace http2
605
+ } // namespace grpc_core
606
+
607
+ #endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_STREAM_DATA_QUEUE_H