grpc 1.73.0 → 1.74.0

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 (499) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +38 -17
  3. data/include/grpc/create_channel_from_endpoint.h +54 -0
  4. data/include/grpc/credentials.h +11 -5
  5. data/include/grpc/event_engine/event_engine.h +74 -17
  6. data/include/grpc/grpc_posix.h +20 -1
  7. data/include/grpc/impl/channel_arg_names.h +2 -4
  8. data/include/grpc/module.modulemap +1 -0
  9. data/include/grpc/support/json.h +24 -0
  10. data/src/core/call/interception_chain.h +7 -11
  11. data/src/core/channelz/channel_trace.cc +213 -115
  12. data/src/core/channelz/channel_trace.h +380 -86
  13. data/src/core/channelz/channelz.cc +270 -181
  14. data/src/core/channelz/channelz.h +168 -55
  15. data/src/core/channelz/channelz_registry.cc +2 -1
  16. data/src/core/channelz/channelz_registry.h +24 -0
  17. data/src/core/channelz/property_list.cc +357 -0
  18. data/src/core/channelz/property_list.h +202 -0
  19. data/src/core/channelz/ztrace_collector.h +3 -2
  20. data/src/core/client_channel/backup_poller.cc +17 -2
  21. data/src/core/client_channel/client_channel.cc +17 -28
  22. data/src/core/client_channel/client_channel_filter.cc +19 -29
  23. data/src/core/client_channel/config_selector.h +8 -2
  24. data/src/core/client_channel/dynamic_filters.cc +5 -6
  25. data/src/core/client_channel/dynamic_filters.h +1 -1
  26. data/src/core/client_channel/global_subchannel_pool.cc +4 -1
  27. data/src/core/client_channel/retry_filter.cc +21 -27
  28. data/src/core/client_channel/retry_filter.h +10 -7
  29. data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
  30. data/src/core/client_channel/retry_filter_legacy_call_data.h +1 -1
  31. data/src/core/client_channel/retry_interceptor.cc +30 -44
  32. data/src/core/client_channel/retry_interceptor.h +18 -17
  33. data/src/core/client_channel/retry_throttle.cc +46 -61
  34. data/src/core/client_channel/retry_throttle.h +17 -39
  35. data/src/core/client_channel/subchannel.cc +43 -19
  36. data/src/core/client_channel/subchannel.h +8 -0
  37. data/src/core/config/config_vars.cc +2 -0
  38. data/src/core/config/core_configuration.cc +1 -0
  39. data/src/core/config/core_configuration.h +11 -0
  40. data/src/core/credentials/call/call_creds_registry.h +125 -0
  41. data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
  42. data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +6 -48
  43. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
  44. data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
  45. data/src/core/credentials/call/jwt_util.cc +70 -0
  46. data/src/core/credentials/call/jwt_util.h +32 -0
  47. data/src/core/credentials/transport/channel_creds_registry_init.cc +1 -1
  48. data/src/core/credentials/transport/google_default/google_default_credentials.cc +72 -4
  49. data/src/core/credentials/transport/ssl/ssl_credentials.cc +0 -1
  50. data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -0
  51. data/src/core/credentials/transport/xds/xds_credentials.cc +0 -3
  52. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +8 -8
  53. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +16 -16
  54. data/src/core/ext/filters/http/client_authority_filter.cc +2 -4
  55. data/src/core/ext/filters/http/message_compress/compression_filter.h +25 -22
  56. data/src/core/ext/filters/http/server/http_server_filter.h +12 -11
  57. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +120 -35
  58. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -5
  59. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +162 -115
  60. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -3
  61. data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
  62. data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
  63. data/src/core/ext/transport/chttp2/transport/flow_control.h +22 -17
  64. data/src/core/ext/transport/chttp2/transport/frame.cc +10 -0
  65. data/src/core/ext/transport/chttp2/transport/frame.h +2 -2
  66. data/src/core/ext/transport/chttp2/transport/frame_data.cc +1 -1
  67. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -8
  68. data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -5
  69. data/src/core/ext/transport/chttp2/transport/header_assembler.h +299 -0
  70. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
  71. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
  72. data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +12 -1
  73. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1017 -0
  74. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +593 -0
  75. data/src/core/ext/transport/chttp2/transport/http2_settings.h +19 -22
  76. data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
  77. data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
  78. data/src/core/ext/transport/chttp2/transport/http2_status.h +6 -1
  79. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +43 -0
  80. data/src/core/ext/transport/chttp2/transport/http2_transport.h +65 -0
  81. data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +0 -29
  82. data/src/core/ext/transport/chttp2/transport/internal.h +18 -8
  83. data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
  84. data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
  85. data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
  86. data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -4
  87. data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
  88. data/src/core/ext/transport/chttp2/transport/ping_promise.cc +151 -0
  89. data/src/core/ext/transport/chttp2/transport/ping_promise.h +180 -0
  90. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +5 -9
  91. data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +11 -0
  92. data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
  93. data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
  94. data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
  95. data/src/core/ext/transport/chttp2/transport/writing.cc +37 -11
  96. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
  97. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
  98. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
  99. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
  100. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
  101. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
  102. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +984 -0
  103. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +226 -0
  104. data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
  105. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
  106. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
  107. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +135 -0
  108. data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
  109. data/src/core/filter/auth/auth_filters.h +0 -25
  110. data/src/core/filter/auth/client_auth_filter.cc +0 -118
  111. data/src/core/filter/filter_args.h +9 -23
  112. data/src/core/handshaker/handshaker.cc +23 -14
  113. data/src/core/handshaker/handshaker.h +3 -0
  114. data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
  115. data/src/core/handshaker/security/legacy_secure_endpoint.cc +6 -5
  116. data/src/core/handshaker/security/secure_endpoint.cc +70 -25
  117. data/src/core/handshaker/security/security_handshaker.cc +4 -1
  118. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
  119. data/src/core/lib/channel/channel_args.cc +15 -0
  120. data/src/core/lib/channel/channel_args.h +3 -0
  121. data/src/core/lib/channel/channel_stack.cc +22 -23
  122. data/src/core/lib/channel/channel_stack.h +9 -7
  123. data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
  124. data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
  125. data/src/core/lib/channel/promise_based_filter.h +5 -5
  126. data/src/core/lib/debug/trace_impl.h +0 -1
  127. data/src/core/lib/event_engine/ares_resolver.cc +165 -46
  128. data/src/core/lib/event_engine/ares_resolver.h +48 -2
  129. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +3 -1
  130. data/src/core/lib/event_engine/cf_engine/cf_engine.h +1 -4
  131. data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +2 -6
  132. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
  133. data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
  134. data/src/core/lib/event_engine/event_engine.cc +7 -0
  135. data/src/core/lib/event_engine/extensions/channelz.h +10 -6
  136. data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
  137. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +130 -162
  138. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +11 -15
  139. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +75 -117
  140. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -9
  141. data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -15
  142. data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +0 -18
  143. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
  144. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
  145. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +29 -19
  146. data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
  147. data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
  148. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +145 -92
  149. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -19
  150. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +333 -116
  151. data/src/core/lib/event_engine/posix_engine/posix_engine.h +61 -18
  152. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +45 -37
  153. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
  154. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +32 -142
  155. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -5
  156. data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
  157. data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
  158. data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
  159. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
  160. data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
  161. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -719
  162. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +10 -170
  163. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
  164. data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
  165. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
  166. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
  167. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
  168. data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
  169. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -62
  170. data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
  171. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
  172. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
  173. data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
  174. data/src/core/lib/event_engine/shim.cc +9 -0
  175. data/src/core/lib/event_engine/shim.h +3 -0
  176. data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
  177. data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
  178. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -2
  179. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -2
  180. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +4 -0
  181. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
  182. data/src/core/lib/event_engine/windows/windows_endpoint.h +2 -6
  183. data/src/core/lib/event_engine/windows/windows_engine.cc +0 -1
  184. data/src/core/lib/event_engine/windows/windows_engine.h +1 -3
  185. data/src/core/lib/event_engine/windows/windows_listener.cc +14 -2
  186. data/src/core/lib/experiments/experiments.cc +45 -93
  187. data/src/core/lib/experiments/experiments.h +21 -51
  188. data/src/core/lib/iomgr/endpoint.cc +4 -3
  189. data/src/core/lib/iomgr/endpoint.h +7 -4
  190. data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
  191. data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -2
  192. data/src/core/lib/iomgr/ev_poll_posix.cc +7 -2
  193. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +4 -6
  194. data/src/core/lib/iomgr/tcp_posix.cc +12 -6
  195. data/src/core/lib/iomgr/tcp_windows.cc +3 -2
  196. data/src/core/lib/promise/activity.h +1 -0
  197. data/src/core/lib/promise/arena_promise.h +23 -7
  198. data/src/core/lib/promise/detail/promise_factory.h +10 -0
  199. data/src/core/lib/promise/detail/promise_like.h +118 -11
  200. data/src/core/lib/promise/detail/promise_variant.h +50 -0
  201. data/src/core/lib/promise/detail/seq_state.h +687 -548
  202. data/src/core/lib/promise/if.h +20 -0
  203. data/src/core/lib/promise/inter_activity_latch.h +147 -0
  204. data/src/core/lib/promise/inter_activity_mutex.h +547 -0
  205. data/src/core/lib/promise/loop.h +65 -3
  206. data/src/core/lib/promise/map.h +24 -0
  207. data/src/core/lib/promise/match_promise.h +103 -0
  208. data/src/core/lib/promise/mpsc.cc +425 -0
  209. data/src/core/lib/promise/mpsc.h +490 -0
  210. data/src/core/lib/promise/party.cc +50 -1
  211. data/src/core/lib/promise/party.h +66 -1
  212. data/src/core/lib/promise/race.h +31 -0
  213. data/src/core/lib/promise/seq.h +4 -1
  214. data/src/core/lib/promise/status_flag.h +7 -0
  215. data/src/core/lib/promise/try_seq.h +4 -1
  216. data/src/core/lib/promise/wait_set.cc +28 -0
  217. data/src/core/lib/promise/wait_set.h +86 -0
  218. data/src/core/lib/resource_quota/arena.h +19 -0
  219. data/src/core/lib/slice/slice.h +5 -0
  220. data/src/core/lib/surface/channel_create.cc +88 -13
  221. data/src/core/lib/surface/channel_create.h +4 -0
  222. data/src/core/lib/surface/channel_init.cc +164 -47
  223. data/src/core/lib/surface/channel_init.h +64 -1
  224. data/src/core/lib/surface/filter_stack_call.cc +18 -9
  225. data/src/core/lib/surface/init.cc +6 -15
  226. data/src/core/lib/surface/legacy_channel.cc +3 -5
  227. data/src/core/lib/surface/legacy_channel.h +3 -1
  228. data/src/core/lib/surface/version.cc +2 -2
  229. data/src/core/lib/transport/promise_endpoint.cc +110 -0
  230. data/src/core/lib/transport/promise_endpoint.h +307 -0
  231. data/src/core/load_balancing/child_policy_handler.cc +2 -4
  232. data/src/core/load_balancing/delegating_helper.h +2 -3
  233. data/src/core/load_balancing/health_check_client.cc +1 -5
  234. data/src/core/load_balancing/lb_policy.h +1 -3
  235. data/src/core/load_balancing/oob_backend_metric.cc +1 -5
  236. data/src/core/load_balancing/pick_first/pick_first.cc +3 -0
  237. data/src/core/load_balancing/xds/cds.cc +10 -1
  238. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
  239. data/src/core/resolver/xds/xds_config.cc +6 -3
  240. data/src/core/resolver/xds/xds_config.h +9 -4
  241. data/src/core/resolver/xds/xds_dependency_manager.cc +21 -6
  242. data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
  243. data/src/core/resolver/xds/xds_resolver.cc +31 -11
  244. data/src/core/server/server.cc +83 -12
  245. data/src/core/server/server.h +21 -2
  246. data/src/core/server/xds_server_config_fetcher.cc +63 -25
  247. data/src/core/service_config/service_config.h +1 -1
  248. data/src/core/service_config/service_config_impl.h +1 -1
  249. data/src/core/telemetry/context_list_entry.cc +38 -0
  250. data/src/core/telemetry/context_list_entry.h +42 -12
  251. data/src/core/telemetry/stats_data.cc +233 -207
  252. data/src/core/telemetry/stats_data.h +250 -153
  253. data/src/core/telemetry/tcp_tracer.h +1 -1
  254. data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
  255. data/src/core/tsi/fake_transport_security.cc +17 -0
  256. data/src/core/tsi/ssl_transport_security.cc +2 -0
  257. data/src/core/tsi/transport_security_grpc.cc +8 -0
  258. data/src/core/tsi/transport_security_grpc.h +15 -0
  259. data/src/core/util/backoff.cc +1 -5
  260. data/src/core/util/backoff.h +1 -0
  261. data/src/core/util/down_cast.h +1 -1
  262. data/src/core/util/function_signature.h +15 -1
  263. data/src/core/util/http_client/httpcli.cc +12 -5
  264. data/src/core/util/http_client/httpcli.h +4 -1
  265. data/src/core/util/latent_see.h +8 -5
  266. data/src/core/util/log.cc +4 -0
  267. data/src/core/util/memory_usage.h +268 -0
  268. data/src/core/util/per_cpu.cc +2 -0
  269. data/src/core/util/per_cpu.h +7 -0
  270. data/src/core/util/shared_bit_gen.h +20 -0
  271. data/src/core/util/single_set_ptr.h +2 -2
  272. data/src/core/util/upb_utils.h +42 -0
  273. data/src/core/util/uri.cc +3 -2
  274. data/src/core/util/useful.h +53 -2
  275. data/src/core/util/wait_for_single_owner.cc +31 -0
  276. data/src/core/util/wait_for_single_owner.h +24 -0
  277. data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -0
  278. data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
  279. data/src/core/xds/grpc/xds_client_grpc.cc +6 -2
  280. data/src/core/xds/grpc/xds_common_types_parser.cc +138 -50
  281. data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
  282. data/src/core/xds/grpc/xds_http_filter.h +7 -0
  283. data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
  284. data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
  285. data/src/core/xds/grpc/xds_route_config_parser.cc +15 -38
  286. data/src/core/xds/grpc/xds_server_grpc.cc +63 -13
  287. data/src/core/xds/grpc/xds_server_grpc.h +10 -2
  288. data/src/core/xds/grpc/xds_server_grpc_interface.h +4 -0
  289. data/src/core/xds/grpc/xds_transport_grpc.cc +18 -0
  290. data/src/core/xds/xds_client/xds_bootstrap.h +2 -0
  291. data/src/core/xds/xds_client/xds_client.cc +26 -5
  292. data/src/ruby/ext/grpc/extconf.rb +2 -0
  293. data/src/ruby/ext/grpc/rb_call.c +1 -8
  294. data/src/ruby/ext/grpc/rb_channel.c +72 -568
  295. data/src/ruby/ext/grpc/rb_channel.h +0 -3
  296. data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
  297. data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
  298. data/src/ruby/ext/grpc/rb_grpc.c +9 -5
  299. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
  300. data/src/ruby/ext/grpc/rb_loader.c +0 -4
  301. data/src/ruby/ext/grpc/rb_server.c +31 -50
  302. data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
  303. data/src/ruby/lib/grpc/version.rb +1 -1
  304. data/src/ruby/spec/core_spec.rb +22 -0
  305. data/src/ruby/spec/generic/active_call_spec.rb +1 -1
  306. data/third_party/abseil-cpp/absl/algorithm/container.h +2 -19
  307. data/third_party/abseil-cpp/absl/base/attributes.h +76 -7
  308. data/third_party/abseil-cpp/absl/base/call_once.h +11 -12
  309. data/third_party/abseil-cpp/absl/base/config.h +20 -129
  310. data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
  311. data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
  312. data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
  313. data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
  314. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
  315. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
  316. data/third_party/abseil-cpp/absl/base/internal/{nullability_impl.h → nullability_deprecated.h} +45 -8
  317. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
  318. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
  319. data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
  320. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
  321. data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
  322. data/third_party/abseil-cpp/absl/base/nullability.h +84 -72
  323. data/third_party/abseil-cpp/absl/base/options.h +3 -80
  324. data/third_party/abseil-cpp/absl/base/policy_checks.h +7 -7
  325. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
  326. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
  327. data/third_party/abseil-cpp/absl/container/btree_map.h +4 -2
  328. data/third_party/abseil-cpp/absl/container/btree_set.h +4 -2
  329. data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -14
  330. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +5 -0
  331. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +6 -1
  332. data/third_party/abseil-cpp/absl/container/inlined_vector.h +8 -5
  333. data/third_party/abseil-cpp/absl/container/internal/btree.h +132 -29
  334. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +175 -71
  335. data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
  336. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
  337. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +9 -10
  338. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
  339. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
  340. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
  341. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
  342. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
  343. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
  344. data/third_party/abseil-cpp/absl/container/internal/layout.h +26 -42
  345. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
  346. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1354 -183
  347. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +881 -1424
  348. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
  349. data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
  350. data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
  351. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
  352. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
  353. data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
  354. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
  355. data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
  356. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
  357. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
  358. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
  359. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
  360. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
  361. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
  362. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
  363. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
  364. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
  365. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
  366. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
  367. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
  368. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
  369. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +19 -9
  370. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
  371. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
  372. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +2 -2
  373. data/third_party/abseil-cpp/absl/flags/flag.h +4 -3
  374. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
  375. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +2 -1
  376. data/third_party/abseil-cpp/absl/flags/internal/flag.h +7 -6
  377. data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
  378. data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
  379. data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
  380. data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
  381. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
  382. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
  383. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
  384. data/third_party/abseil-cpp/absl/hash/hash.h +18 -0
  385. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +1 -5
  386. data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -61
  387. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +25 -68
  388. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
  389. data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
  390. data/third_party/abseil-cpp/absl/log/check.h +2 -1
  391. data/third_party/abseil-cpp/absl/log/globals.h +4 -5
  392. data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
  393. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +22 -22
  394. data/third_party/abseil-cpp/absl/log/internal/check_op.h +65 -62
  395. data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
  396. data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
  397. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +85 -43
  398. data/third_party/abseil-cpp/absl/log/internal/log_message.h +84 -59
  399. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
  400. data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -2
  401. data/third_party/abseil-cpp/absl/log/internal/proto.h +3 -3
  402. data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
  403. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
  404. data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
  405. data/third_party/abseil-cpp/absl/log/log.h +48 -35
  406. data/third_party/abseil-cpp/absl/log/log_sink_registry.h +2 -2
  407. data/third_party/abseil-cpp/absl/meta/type_traits.h +46 -175
  408. data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
  409. data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
  410. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
  411. data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
  412. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
  413. data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
  414. data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
  415. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
  416. data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
  417. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
  418. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
  419. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
  420. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
  421. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
  422. data/third_party/abseil-cpp/absl/random/random.h +88 -53
  423. data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
  424. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
  425. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
  426. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
  427. data/third_party/abseil-cpp/absl/status/status.cc +4 -8
  428. data/third_party/abseil-cpp/absl/status/status.h +8 -8
  429. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
  430. data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
  431. data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
  432. data/third_party/abseil-cpp/absl/strings/ascii.cc +9 -9
  433. data/third_party/abseil-cpp/absl/strings/ascii.h +18 -18
  434. data/third_party/abseil-cpp/absl/strings/charconv.cc +21 -22
  435. data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
  436. data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
  437. data/third_party/abseil-cpp/absl/strings/cord.h +94 -83
  438. data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
  439. data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
  440. data/third_party/abseil-cpp/absl/strings/escaping.cc +130 -149
  441. data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
  442. data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
  443. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +6 -8
  444. data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
  445. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
  446. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
  447. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
  448. data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
  449. data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
  450. data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
  451. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
  452. data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
  453. data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
  454. data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
  455. data/third_party/abseil-cpp/absl/strings/numbers.cc +53 -32
  456. data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
  457. data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
  458. data/third_party/abseil-cpp/absl/strings/str_cat.h +32 -32
  459. data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
  460. data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
  461. data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
  462. data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
  463. data/third_party/abseil-cpp/absl/strings/string_view.h +27 -32
  464. data/third_party/abseil-cpp/absl/strings/strip.h +4 -4
  465. data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
  466. data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
  467. data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
  468. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
  469. data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
  470. data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
  471. data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
  472. data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
  473. data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
  474. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +1 -1
  475. data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
  476. data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
  477. data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
  478. data/third_party/abseil-cpp/absl/time/duration.cc +12 -7
  479. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
  480. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
  481. data/third_party/abseil-cpp/absl/time/time.h +20 -15
  482. data/third_party/abseil-cpp/absl/types/optional.h +7 -747
  483. data/third_party/abseil-cpp/absl/types/span.h +13 -11
  484. data/third_party/abseil-cpp/absl/types/variant.h +5 -784
  485. data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
  486. metadata +72 -20
  487. data/src/core/lib/event_engine/forkable.cc +0 -105
  488. data/src/core/lib/event_engine/forkable.h +0 -67
  489. data/src/core/lib/iomgr/python_util.h +0 -46
  490. data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
  491. data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
  492. data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
  493. data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
  494. data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
  495. data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
  496. data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
  497. data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
  498. data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
  499. data/third_party/abseil-cpp/absl/types/internal/variant.h +0 -1622
@@ -0,0 +1,547 @@
1
+ // Copyright 2025 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef GRPC_SRC_CORE_LIB_PROMISE_INTER_ACTIVITY_MUTEX_H
16
+ #define GRPC_SRC_CORE_LIB_PROMISE_INTER_ACTIVITY_MUTEX_H
17
+
18
+ #include <atomic>
19
+ #include <utility>
20
+
21
+ #include "absl/log/log.h"
22
+ #include "src/core/lib/debug/trace.h"
23
+ #include "src/core/lib/promise/activity.h"
24
+ #include "src/core/lib/promise/poll.h"
25
+ #include "src/core/util/dump_args.h"
26
+
27
+ namespace grpc_core {
28
+
29
+ // An async mutex that can be used to synchronize between activities.
30
+ // Acquire() returns a promise that resolves to a Lock object that allows
31
+ // mutating the protected state.
32
+ // AcquireWhen() additionally takes a predicate that must be satisfied to
33
+ // acquire the lock.
34
+ // The lock is fair in that it will be granted to the oldest waiter that can
35
+ // acquire the lock.
36
+ template <typename T>
37
+ class InterActivityMutex {
38
+ public:
39
+ class Lock {
40
+ public:
41
+ Lock(const Lock&) = delete;
42
+ Lock& operator=(const Lock&) = delete;
43
+ Lock(Lock&& other) noexcept
44
+ : mutex_(std::exchange(other.mutex_, nullptr)) {}
45
+ Lock& operator=(Lock&& other) noexcept {
46
+ if (mutex_ != nullptr) mutex_->Unlock();
47
+ mutex_ = std::exchange(other.mutex_, nullptr);
48
+ return *this;
49
+ }
50
+ ~Lock() {
51
+ if (mutex_ != nullptr) mutex_->Unlock();
52
+ }
53
+
54
+ T& operator*() { return mutex_->value_; }
55
+ T* operator->() { return &mutex_->value_; }
56
+ const T& operator*() const { return mutex_->value_; }
57
+ const T* operator->() const { return &mutex_->value_; }
58
+
59
+ template <typename Sink>
60
+ friend void AbslStringify(Sink& sink, const Lock& lock) {
61
+ if (lock.mutex_ == nullptr) {
62
+ sink.Append("<unlocked>");
63
+ } else {
64
+ absl::Format(&sink, "%v", lock.mutex_->value_);
65
+ }
66
+ }
67
+
68
+ private:
69
+ friend class InterActivityMutex;
70
+ explicit Lock(InterActivityMutex* mutex) : mutex_(mutex) {
71
+ GRPC_TRACE_LOG(promise_primitives, INFO)
72
+ << "[mutex " << mutex_ << "] Lock acquired";
73
+ }
74
+ InterActivityMutex* mutex_;
75
+ };
76
+
77
+ InterActivityMutex() = default;
78
+ ~InterActivityMutex() {
79
+ // There should be no waiters at this point, but we may have some cancelled
80
+ // waiters that need to be cleaned up.
81
+ while (waiters_ != nullptr) {
82
+ Waiter* next = waiters_->next_;
83
+ // Asserts that the waiter is cancelled.
84
+ // If this is not the case, then there's a bug in the caller keeping
85
+ // an acquire promise alive after the mutex has been destroyed.
86
+ waiters_->RemovedFromQueue();
87
+ waiters_ = next;
88
+ }
89
+ }
90
+ explicit InterActivityMutex(T value) : value_(std::move(value)) {}
91
+
92
+ private:
93
+ template <typename F>
94
+ class Acquirer;
95
+ class Unlocker;
96
+
97
+ // Polymorphic waiter for the mutex.
98
+ // Created only after we can't acquire the mutex on the fast path (with a
99
+ // CAS). May outlive the acquire promise - if the acquisition is cancelled
100
+ // this object will still remain until the unlock path can see the
101
+ // cancellation and remove this object.
102
+ class Waiter {
103
+ public:
104
+ explicit Waiter(InterActivityMutex* mutex, Waiter* next = nullptr)
105
+ : mutex_(mutex), next_(next) {}
106
+
107
+ // Returns true if the waiter was cancelled.
108
+ bool WasAcquisitionCancelled() {
109
+ return state_.load(std::memory_order_relaxed) ==
110
+ State::kAcquisitionCancelled;
111
+ }
112
+
113
+ // Returns true if the waiter can acquire the mutex (the predicate is
114
+ // satisfied).
115
+ virtual bool CanAcquire() = 0;
116
+
117
+ // Notify that the CAS to add this to the waiter queue failed - deletes the
118
+ // waiter after checking internal invariants.
119
+ void FailedAddToQueue() {
120
+ DCHECK_EQ(state_, State::kWaiting);
121
+ delete this;
122
+ }
123
+
124
+ // Notify that the waiter has been removed from the queue - deletes the
125
+ // waiter after checking internal invariants.
126
+ void RemovedFromQueue() {
127
+ DCHECK_EQ(state_, State::kAcquisitionCancelled);
128
+ delete this;
129
+ }
130
+
131
+ // Notify that the acquisition promise has been cancelled.
132
+ // If still waiting, this marks the waiter as cancelled. It will be
133
+ // later deleted by the unlock path.
134
+ // If already acquired, this unlocks the mutex, finds a new owner, and
135
+ // deletes the waiter.
136
+ void AcquisitionCancelled() {
137
+ State prev_state = State::kWaiting;
138
+ while (true) {
139
+ GRPC_TRACE_LOG(promise_primitives, INFO)
140
+ << "[mutex " << mutex_ << " waiter " << this
141
+ << "] AcquisitionCancelled: " << GRPC_DUMP_ARGS(prev_state);
142
+ switch (prev_state) {
143
+ case State::kWaiting:
144
+ if (state_.compare_exchange_weak(prev_state,
145
+ State::kAcquisitionCancelled,
146
+ std::memory_order_acq_rel)) {
147
+ return;
148
+ }
149
+ break;
150
+ case State::kAcquisitionCancelled:
151
+ LOG(DFATAL) << "unreachable";
152
+ return;
153
+ case State::kAcquired:
154
+ mutex_->Unlock();
155
+ delete this;
156
+ return;
157
+ }
158
+ }
159
+ }
160
+
161
+ // Returns true if the waiter has acquired the mutex.
162
+ // If so, deletes the waiter.
163
+ bool CheckAcquired() {
164
+ bool acquired =
165
+ state_.load(std::memory_order_acquire) == State::kAcquired;
166
+ if (acquired) delete this;
167
+ return acquired;
168
+ }
169
+
170
+ // Notify that the waiter has acquired the mutex.
171
+ // If still waiting, this marks the waiter as acquired.
172
+ // If already cancelled, this unlocks the mutex, finds a new owner, and
173
+ // deletes the waiter.
174
+ void BecomeAcquired() {
175
+ State prev_state = State::kWaiting;
176
+ while (true) {
177
+ switch (prev_state) {
178
+ case State::kWaiting:
179
+ if (state_.compare_exchange_weak(prev_state, State::kAcquired,
180
+ std::memory_order_acq_rel)) {
181
+ waker_.Wakeup();
182
+ return;
183
+ }
184
+ break;
185
+ case State::kAcquisitionCancelled:
186
+ mutex_->Unlock();
187
+ delete this;
188
+ return;
189
+ case State::kAcquired:
190
+ LOG(DFATAL) << "unreachable";
191
+ return;
192
+ }
193
+ }
194
+ }
195
+
196
+ // Reverse the order of waiters in a subqueue.
197
+ // When waiters are added to the wait list, they are added in LIFO order
198
+ // to keep the CAS loop simple. To maintain fairness, we need them in FIFO
199
+ // order. This function reverses the order of the waiters in the subqueue.
200
+ Waiter* Reverse() {
201
+ // Use a vector to avoid a large recursion.
202
+ std::vector<Waiter*> waiters;
203
+ for (Waiter* waiter = this; waiter != nullptr; waiter = waiter->next_) {
204
+ waiters.push_back(waiter);
205
+ }
206
+ waiters[0]->next_ = nullptr;
207
+ for (size_t i = 1; i < waiters.size(); ++i) {
208
+ waiters[i]->next_ = waiters[i - 1];
209
+ }
210
+ return waiters[waiters.size() - 1];
211
+ }
212
+
213
+ protected:
214
+ const T& value() const { return mutex_->value_; }
215
+
216
+ virtual ~Waiter() = default;
217
+
218
+ private:
219
+ template <typename F>
220
+ friend class Acquirer;
221
+ friend class Unlocker;
222
+ friend class InterActivityMutex;
223
+
224
+ enum State {
225
+ // Waiter is waiting in the wait list
226
+ kWaiting,
227
+ // Acquirer has cancelled the acquisition promise.
228
+ kAcquisitionCancelled,
229
+ // Waiter has acquired the mutex.
230
+ kAcquired,
231
+ };
232
+
233
+ template <typename Sink>
234
+ friend void AbslStringify(Sink& sink, State state) {
235
+ switch (state) {
236
+ case State::kWaiting:
237
+ sink.Append("Waiting");
238
+ break;
239
+ case State::kAcquisitionCancelled:
240
+ sink.Append("AcquisitionCancelled");
241
+ break;
242
+ case State::kAcquired:
243
+ sink.Append("Acquired");
244
+ break;
245
+ }
246
+ }
247
+
248
+ std::atomic<State> state_{State::kWaiting};
249
+ InterActivityMutex* const mutex_;
250
+ Waiter* next_;
251
+ Waker waker_ = GetContext<Activity>()->MakeNonOwningWaker();
252
+ };
253
+
254
+ template <class F>
255
+ class WaiterImpl : public Waiter {
256
+ public:
257
+ WaiterImpl(InterActivityMutex* mutex, Waiter* next, F f)
258
+ : Waiter(mutex, next), f_(std::move(f)) {}
259
+ bool CanAcquire() override { return f_(this->value()); }
260
+
261
+ private:
262
+ GPR_NO_UNIQUE_ADDRESS F f_;
263
+ };
264
+
265
+ template <class F>
266
+ class Acquirer {
267
+ public:
268
+ explicit Acquirer(InterActivityMutex* mutex, F f)
269
+ : mutex_(mutex), f_(std::move(f)) {}
270
+ ~Acquirer() {
271
+ // Acquirer destroyed - but we may already hold the lock if we were never
272
+ // polled and acquired the fast path, or we may have a waiter in the wait
273
+ // queue that needs to be cancelled.
274
+ switch (state_) {
275
+ case State::kStart:
276
+ break;
277
+ case State::kFastLocked:
278
+ mutex_->Unlock();
279
+ break;
280
+ case State::kMovedFrom:
281
+ break;
282
+ case State::kWaiting:
283
+ waiter_->AcquisitionCancelled();
284
+ break;
285
+ }
286
+ }
287
+ Acquirer(const Acquirer&) = delete;
288
+ Acquirer& operator=(const Acquirer&) = delete;
289
+ Acquirer(Acquirer&& other) noexcept
290
+ : mutex_(other.mutex_),
291
+ prev_state_(other.prev_state_),
292
+ state_(std::exchange(other.state_, State::kMovedFrom)),
293
+ f_(std::move(other.f_)),
294
+ waiter_(other.waiter_) {}
295
+ Acquirer& operator=(Acquirer&& other) noexcept = delete;
296
+ Poll<Lock> operator()() {
297
+ GRPC_TRACE_LOG(promise_primitives, INFO)
298
+ << "[mutex " << mutex_ << " aquirerer " << this
299
+ << "] Poll: " << GRPC_DUMP_ARGS(state_);
300
+ switch (state_) {
301
+ case State::kStart:
302
+ return PollStart();
303
+ case State::kFastLocked:
304
+ return PollFastLocked();
305
+ case State::kWaiting:
306
+ return PollWaiting();
307
+ case State::kMovedFrom:
308
+ LOG(FATAL) << "Mutex acquirer already moved from";
309
+ }
310
+ }
311
+
312
+ private:
313
+ enum class State : uint8_t {
314
+ // Initial state if fast cas failed
315
+ kStart,
316
+ // Fast path succeeded, but we haven't checked if we can acquire the
317
+ // lock yet.
318
+ kFastLocked,
319
+ // Waiter is waiting in the wait list
320
+ kWaiting,
321
+ // Acquirer has been moved from
322
+ kMovedFrom
323
+ };
324
+
325
+ template <typename Sink>
326
+ friend void AbslStringify(Sink& sink, State state) {
327
+ switch (state) {
328
+ case State::kStart:
329
+ sink.Append("Start");
330
+ break;
331
+ case State::kFastLocked:
332
+ sink.Append("FastLocked");
333
+ break;
334
+ case State::kWaiting:
335
+ sink.Append("Waiting");
336
+ break;
337
+ case State::kMovedFrom:
338
+ sink.Append("MovedFrom");
339
+ break;
340
+ }
341
+ }
342
+
343
+ Poll<Lock> PollStart() {
344
+ while (true) {
345
+ GRPC_TRACE_LOG(promise_primitives, INFO)
346
+ << "[mutex " << mutex_ << " aquirerer " << this
347
+ << "] PollStart: " << GRPC_DUMP_ARGS(prev_state_);
348
+ if (prev_state_ == kUnlocked) {
349
+ // Fast path - try to acquire the lock.
350
+ if (mutex_->state_.compare_exchange_weak(prev_state_, kLocked,
351
+ std::memory_order_acq_rel)) {
352
+ return PollFastLocked();
353
+ }
354
+ } else if (prev_state_ == kLocked) {
355
+ // Lock is already acquired - but no waiters yet, try to add ourselves
356
+ // to the wait list
357
+ waiter_ = new WaiterImpl<F>(mutex_, nullptr, std::move(f_));
358
+ state_ = State::kWaiting;
359
+ if (mutex_->state_.compare_exchange_weak(
360
+ prev_state_, reinterpret_cast<uintptr_t>(waiter_),
361
+ std::memory_order_acq_rel)) {
362
+ return Pending{};
363
+ }
364
+ state_ = State::kStart;
365
+ waiter_->FailedAddToQueue();
366
+ } else {
367
+ // Lock is already acquired, try to add ourselves to the wait list
368
+ waiter_ = new WaiterImpl<F>(
369
+ mutex_, reinterpret_cast<Waiter*>(prev_state_), std::move(f_));
370
+ state_ = State::kWaiting;
371
+ if (mutex_->state_.compare_exchange_weak(
372
+ prev_state_, reinterpret_cast<uintptr_t>(waiter_),
373
+ std::memory_order_acq_rel)) {
374
+ return Pending{};
375
+ }
376
+ state_ = State::kStart;
377
+ waiter_->FailedAddToQueue();
378
+ }
379
+ }
380
+ }
381
+
382
+ Poll<Lock> PollFastLocked() {
383
+ // We've acquired the lock via the fast lock path, but have not
384
+ // yet checked if we can actually acquire the lock.
385
+ if (f_(mutex_->value_)) {
386
+ state_ = State::kMovedFrom;
387
+ return Lock(mutex_);
388
+ }
389
+ GRPC_TRACE_LOG(promise_primitives, INFO)
390
+ << "[mutex " << mutex_ << " acquirer " << this
391
+ << "]: PollFastLocked but not ready: insert waiter @ tail";
392
+ waiter_ = new WaiterImpl<F>(mutex_, nullptr, std::move(f_));
393
+ if (mutex_->waiters_ == nullptr) {
394
+ mutex_->waiters_ = waiter_;
395
+ } else {
396
+ Waiter* w = mutex_->waiters_;
397
+ while (w->next_ != nullptr) w = w->next_;
398
+ w->next_ = waiter_;
399
+ }
400
+ state_ = State::kWaiting;
401
+ if (mutex_->state_.compare_exchange_strong(prev_state_, kUnlocked,
402
+ std::memory_order_acq_rel)) {
403
+ return Pending{};
404
+ }
405
+ DCHECK_NE(prev_state_, kUnlocked);
406
+ // some other waiter was added to the queue while we were waiting
407
+ // go through the slow unlock path
408
+ mutex_->Unlock();
409
+ return Pending{};
410
+ }
411
+
412
+ Poll<Lock> PollWaiting() {
413
+ if (waiter_->CheckAcquired()) {
414
+ state_ = State::kMovedFrom;
415
+ return Lock(mutex_);
416
+ }
417
+ return Pending{};
418
+ }
419
+
420
+ InterActivityMutex* mutex_;
421
+ uintptr_t prev_state_ = kUnlocked;
422
+ State state_ = mutex_->state_.compare_exchange_weak(
423
+ prev_state_, kLocked, std::memory_order_acq_rel)
424
+ ? State::kFastLocked
425
+ : State::kStart;
426
+ GPR_NO_UNIQUE_ADDRESS F f_;
427
+ Waiter* waiter_;
428
+ };
429
+
430
+ public:
431
+ auto Acquire() {
432
+ return AcquireWhen([](const T&) { return true; });
433
+ }
434
+ template <typename F>
435
+ auto AcquireWhen(F f) {
436
+ return Acquirer<F>(this, std::move(f));
437
+ }
438
+
439
+ private:
440
+ static constexpr uintptr_t kUnlocked = 0;
441
+ static constexpr uintptr_t kLocked = 1;
442
+
443
+ class Unlocker {
444
+ public:
445
+ explicit Unlocker(InterActivityMutex* mutex) : mutex_(mutex) {}
446
+
447
+ void Run() {
448
+ while (DrainSeenWaiters() && MaybeRefillWaiters()) {
449
+ }
450
+ }
451
+
452
+ private:
453
+ bool DrainSeenWaiters() {
454
+ // First, check if any waiter can acquire the mutex.
455
+ while (waiter_ != nullptr) {
456
+ GRPC_TRACE_LOG(promise_primitives, INFO)
457
+ << "[mutex " << mutex_
458
+ << "] DrainSeenWaiters: " << GRPC_DUMP_ARGS(prev_waiter_, waiter_);
459
+ if (waiter_->WasAcquisitionCancelled()) {
460
+ GRPC_TRACE_LOG(promise_primitives, INFO)
461
+ << "[mutex " << mutex_
462
+ << "] DrainSeenWaiters acquisition cancelled: "
463
+ << GRPC_DUMP_ARGS(prev_waiter_, waiter_);
464
+ Waiter* next = waiter_->next_;
465
+ DCHECK_NE(next, waiter_);
466
+ if (prev_waiter_ == nullptr) {
467
+ DCHECK_EQ(mutex_->waiters_, waiter_);
468
+ mutex_->waiters_ = next;
469
+ } else {
470
+ DCHECK_EQ(prev_waiter_->next_, waiter_);
471
+ prev_waiter_->next_ = next;
472
+ }
473
+ waiter_->RemovedFromQueue();
474
+ waiter_ = next;
475
+ continue;
476
+ }
477
+ if (waiter_->CanAcquire()) {
478
+ GRPC_TRACE_LOG(promise_primitives, INFO)
479
+ << "[mutex " << mutex_
480
+ << "] DrainSeenWaiters acquisition successful: "
481
+ << GRPC_DUMP_ARGS(prev_waiter_, waiter_);
482
+ if (prev_waiter_ == nullptr) {
483
+ mutex_->waiters_ = waiter_->next_;
484
+ } else {
485
+ prev_waiter_->next_ = waiter_->next_;
486
+ }
487
+ waiter_->BecomeAcquired();
488
+ return false;
489
+ }
490
+ prev_waiter_ = waiter_;
491
+ waiter_ = waiter_->next_;
492
+ }
493
+ return true;
494
+ }
495
+
496
+ bool MaybeRefillWaiters() {
497
+ // Next, consider any waiters that were queued up.
498
+ // These will be in reverse order of addition to the queue, so we need to
499
+ // reverse them before processing.
500
+ auto prev_state = mutex_->state_.load(std::memory_order_acquire);
501
+ while (true) {
502
+ GRPC_TRACE_LOG(promise_primitives, INFO)
503
+ << "[mutex " << mutex_
504
+ << "] MaybeRefillWaiters: " << GRPC_DUMP_ARGS(prev_state);
505
+ DCHECK_NE(prev_state, kUnlocked);
506
+ if (prev_state == kLocked) {
507
+ if (mutex_->state_.compare_exchange_weak(prev_state, kUnlocked,
508
+ std::memory_order_acq_rel)) {
509
+ return false;
510
+ }
511
+ } else {
512
+ if (mutex_->state_.compare_exchange_weak(prev_state, kLocked,
513
+ std::memory_order_acq_rel)) {
514
+ Waiter* next = reinterpret_cast<Waiter*>(prev_state);
515
+ if (prev_waiter_ == nullptr) {
516
+ mutex_->waiters_ = next->Reverse();
517
+ waiter_ = mutex_->waiters_;
518
+ } else {
519
+ DCHECK_EQ(prev_waiter_->next_, nullptr);
520
+ prev_waiter_->next_ = next->Reverse();
521
+ waiter_ = prev_waiter_->next_;
522
+ }
523
+ return true;
524
+ }
525
+ }
526
+ }
527
+ }
528
+
529
+ InterActivityMutex* const mutex_;
530
+ Waiter* prev_waiter_ = nullptr;
531
+ Waiter* waiter_ = mutex_->waiters_;
532
+ };
533
+
534
+ void Unlock() {
535
+ GRPC_TRACE_LOG(promise_primitives, INFO)
536
+ << "[mutex " << this << "] Unlocking";
537
+ Unlocker(this).Run();
538
+ }
539
+
540
+ std::atomic<uintptr_t> state_{kUnlocked};
541
+ Waiter* waiters_ = nullptr;
542
+ T value_;
543
+ };
544
+
545
+ } // namespace grpc_core
546
+
547
+ #endif // GRPC_SRC_CORE_LIB_PROMISE_INTER_ACTIVITY_MUTEX_H
@@ -23,8 +23,10 @@
23
23
  #include "absl/status/status.h"
24
24
  #include "absl/status/statusor.h"
25
25
  #include "src/core/lib/debug/trace.h"
26
+ #include "src/core/lib/promise/activity.h"
26
27
  #include "src/core/lib/promise/detail/promise_factory.h"
27
28
  #include "src/core/lib/promise/poll.h"
29
+ #include "src/core/lib/promise/seq.h"
28
30
  #include "src/core/util/construct_destruct.h"
29
31
 
30
32
  namespace grpc_core {
@@ -40,7 +42,7 @@ namespace grpc_core {
40
42
  //
41
43
  // Running of the Loop combinator:
42
44
  //
43
- // 1. The input promise is guranteed to run at least once when the combinator
45
+ // 1. The input promise is guaranteed to run at least once when the combinator
44
46
  // is invoked.
45
47
  // 2. The Loop combinators execution will keep running input promise for
46
48
  // as long as the input promise returns the Continue() object.
@@ -123,7 +125,7 @@ struct LoopTraits<absl::StatusOr<LoopCtl<absl::Status>>> {
123
125
 
124
126
  } // namespace promise_detail
125
127
 
126
- template <typename F>
128
+ template <typename F, bool kYield>
127
129
  class Loop {
128
130
  private:
129
131
  static_assert(promise_detail::kIsRepeatedPromiseFactory<void, F>);
@@ -170,6 +172,13 @@ class Loop {
170
172
  << "loop[" << this << "] iteration complete, continue";
171
173
  Destruct(&promise_);
172
174
  Construct(&promise_, factory_.Make());
175
+ if constexpr (kYield) {
176
+ GRPC_TRACE_LOG(promise_primitives, INFO)
177
+ << "loop[" << this << "] iteration yield";
178
+ auto* activity = GetContext<Activity>();
179
+ activity->ForceImmediateRepoll(activity->CurrentParticipant());
180
+ return Pending();
181
+ }
173
182
  continue;
174
183
  }
175
184
  GRPC_TRACE_LOG(promise_primitives, INFO)
@@ -185,6 +194,21 @@ class Loop {
185
194
  }
186
195
  }
187
196
 
197
+ void ToProto(grpc_channelz_v2_Promise* promise_proto,
198
+ upb_Arena* arena) const {
199
+ auto* loop_promise =
200
+ grpc_channelz_v2_Promise_mutable_loop_promise(promise_proto, arena);
201
+ if constexpr (kYield) {
202
+ grpc_channelz_v2_Promise_Loop_set_yield(loop_promise, true);
203
+ }
204
+ PromiseAsProto(
205
+ promise_,
206
+ grpc_channelz_v2_Promise_Loop_mutable_promise(loop_promise, arena),
207
+ arena);
208
+ grpc_channelz_v2_Promise_Loop_set_loop_factory(
209
+ loop_promise, StdStringToUpbString(TypeName<Factory>()));
210
+ }
211
+
188
212
  private:
189
213
  GPR_NO_UNIQUE_ADDRESS Factory factory_;
190
214
  GPR_NO_UNIQUE_ADDRESS union {
@@ -194,7 +218,45 @@ class Loop {
194
218
  };
195
219
 
196
220
  template <typename F>
197
- Loop(F) -> Loop<F>;
221
+ Loop(F) -> Loop<F, false>;
222
+
223
+ // A version of Loop that yields the activity to another promise once per
224
+ // iteration.
225
+ template <typename F>
226
+ auto YieldingLoop(F f) {
227
+ return Loop<F, true>(std::move(f));
228
+ }
229
+
230
+ template <typename PromiseFactory>
231
+ auto NTimes(size_t times, PromiseFactory promise_factory) {
232
+ DCHECK_GT(times, 1u);
233
+ return Loop(
234
+ [i = size_t{0}, times,
235
+ promise_factory =
236
+ promise_detail::RepeatedPromiseFactory<size_t, PromiseFactory>(
237
+ std::move(promise_factory))]() mutable {
238
+ return Seq(promise_factory.Make(i), [&i, times](auto result) {
239
+ using Result = decltype(result);
240
+ LoopCtl<Result> lc = std::move(result);
241
+ ++i;
242
+ if (i != times) lc = Continue{};
243
+ return lc;
244
+ });
245
+ });
246
+ }
247
+
248
+ template <typename PromiseFactory>
249
+ auto WhilstSuccessful(PromiseFactory promise_factory) {
250
+ return Loop([promise_factory =
251
+ promise_detail::RepeatedPromiseFactory<void, PromiseFactory>(
252
+ std::move(promise_factory))]() mutable {
253
+ return Seq(promise_factory.Make(), [](auto result) {
254
+ using Result = decltype(result);
255
+ if (result.ok()) return LoopCtl<Result>(Continue());
256
+ return LoopCtl<Result>(std::move(result));
257
+ });
258
+ });
259
+ }
198
260
 
199
261
  } // namespace grpc_core
200
262
 
@@ -156,6 +156,18 @@ class Map {
156
156
  return Pending();
157
157
  }
158
158
 
159
+ void ToProto(grpc_channelz_v2_Promise* promise_proto,
160
+ upb_Arena* arena) const {
161
+ auto* map_promise =
162
+ grpc_channelz_v2_Promise_mutable_map_promise(promise_proto, arena);
163
+ PromiseAsProto(
164
+ promise_,
165
+ grpc_channelz_v2_Promise_Map_mutable_promise(map_promise, arena),
166
+ arena);
167
+ grpc_channelz_v2_Promise_Map_set_map_fn(
168
+ map_promise, StdStringToUpbString(TypeName<Fn>()));
169
+ }
170
+
159
171
  private:
160
172
  template <typename SomeOtherPromise, typename SomeOtherFn>
161
173
  friend class Map;
@@ -195,6 +207,18 @@ class Map<Map<Promise, Fn0>, Fn1> {
195
207
  return Pending();
196
208
  }
197
209
 
210
+ void ToProto(grpc_channelz_v2_Promise* promise_proto,
211
+ upb_Arena* arena) const {
212
+ auto* map_promise =
213
+ grpc_channelz_v2_Promise_mutable_map_promise(promise_proto, arena);
214
+ PromiseAsProto(
215
+ promise_,
216
+ grpc_channelz_v2_Promise_Map_mutable_promise(map_promise, arena),
217
+ arena);
218
+ grpc_channelz_v2_Promise_Map_set_map_fn(
219
+ map_promise, StdStringToUpbString(TypeName<FusedFn>()));
220
+ }
221
+
198
222
  private:
199
223
  template <typename SomeOtherPromise, typename SomeOtherFn>
200
224
  friend class Map;