grpc 1.60.2 → 1.61.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +208 -165
  3. data/include/grpc/event_engine/event_engine.h +59 -12
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
  5. data/include/grpc/event_engine/internal/slice_cast.h +12 -0
  6. data/include/grpc/event_engine/memory_allocator.h +3 -1
  7. data/include/grpc/event_engine/slice.h +5 -0
  8. data/include/grpc/grpc_security.h +22 -1
  9. data/include/grpc/impl/call.h +29 -0
  10. data/include/grpc/impl/channel_arg_names.h +12 -1
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
  14. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
  15. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
  16. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
  17. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
  18. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
  19. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
  20. data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
  21. data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
  22. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
  24. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
  26. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
  27. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
  29. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
  35. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
  37. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
  39. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
  48. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
  50. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
  51. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
  52. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
  53. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
  54. data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
  55. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
  56. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
  57. data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
  58. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
  59. data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
  60. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
  61. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
  63. data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
  64. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  65. data/src/core/ext/filters/http/client_authority_filter.h +12 -4
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
  67. data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
  68. data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
  69. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
  70. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
  71. data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
  72. data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
  73. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
  74. data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
  75. data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
  76. data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
  77. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
  78. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
  79. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
  80. data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
  81. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
  82. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
  83. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
  84. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  85. data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
  86. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
  87. data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
  88. data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
  89. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  90. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
  91. data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
  92. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
  93. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
  94. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
  95. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  96. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  97. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  98. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  99. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  103. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  104. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  105. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  106. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  107. data/src/core/ext/xds/xds_api.cc +31 -18
  108. data/src/core/ext/xds/xds_api.h +2 -2
  109. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  110. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  111. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  112. data/src/core/ext/xds/xds_client.cc +420 -414
  113. data/src/core/ext/xds/xds_client.h +31 -22
  114. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  115. data/src/core/ext/xds/xds_cluster.cc +104 -11
  116. data/src/core/ext/xds/xds_cluster.h +9 -1
  117. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  118. data/src/core/ext/xds/xds_common_types.cc +14 -10
  119. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  120. data/src/core/ext/xds/xds_endpoint.h +5 -1
  121. data/src/core/ext/xds/xds_health_status.cc +12 -2
  122. data/src/core/ext/xds/xds_health_status.h +4 -2
  123. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  124. data/src/core/ext/xds/xds_listener.cc +14 -8
  125. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  126. data/src/core/ext/xds/xds_route_config.cc +34 -22
  127. data/src/core/ext/xds/xds_route_config.h +1 -0
  128. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  129. data/src/core/ext/xds/xds_transport.h +3 -0
  130. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  131. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  132. data/src/core/lib/channel/call_tracer.cc +12 -0
  133. data/src/core/lib/channel/call_tracer.h +17 -3
  134. data/src/core/lib/channel/channel_args.cc +24 -14
  135. data/src/core/lib/channel/channel_args.h +74 -13
  136. data/src/core/lib/channel/channel_stack.cc +27 -0
  137. data/src/core/lib/channel/channel_stack.h +10 -10
  138. data/src/core/lib/channel/connected_channel.cc +64 -18
  139. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  140. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  141. data/src/core/lib/compression/compression_internal.cc +0 -3
  142. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  143. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  144. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  145. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  146. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  147. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  148. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  149. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  150. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  151. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  152. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  153. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  154. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  155. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  156. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  157. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  158. data/src/core/lib/experiments/config.cc +13 -0
  159. data/src/core/lib/experiments/config.h +3 -0
  160. data/src/core/lib/experiments/experiments.cc +245 -366
  161. data/src/core/lib/experiments/experiments.h +50 -156
  162. data/src/core/lib/gprpp/debug_location.h +13 -0
  163. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  164. data/src/core/lib/gprpp/orphanable.h +27 -0
  165. data/src/core/lib/gprpp/ref_counted.h +63 -22
  166. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  167. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  168. data/src/core/lib/gprpp/status_helper.cc +1 -2
  169. data/src/core/lib/iomgr/combiner.cc +15 -51
  170. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  171. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  173. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  174. data/src/core/lib/promise/activity.cc +17 -2
  175. data/src/core/lib/promise/activity.h +5 -4
  176. data/src/core/lib/promise/all_ok.h +80 -0
  177. data/src/core/lib/promise/detail/join_state.h +2077 -0
  178. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  179. data/src/core/lib/promise/detail/promise_like.h +8 -1
  180. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  181. data/src/core/lib/promise/detail/status.h +42 -5
  182. data/src/core/lib/promise/for_each.h +13 -1
  183. data/src/core/lib/promise/if.h +4 -0
  184. data/src/core/lib/promise/latch.h +6 -3
  185. data/src/core/lib/promise/party.cc +33 -31
  186. data/src/core/lib/promise/party.h +142 -6
  187. data/src/core/lib/promise/poll.h +39 -13
  188. data/src/core/lib/promise/promise.h +4 -0
  189. data/src/core/lib/promise/seq.h +107 -7
  190. data/src/core/lib/promise/status_flag.h +196 -0
  191. data/src/core/lib/promise/try_join.h +132 -0
  192. data/src/core/lib/promise/try_seq.h +132 -10
  193. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  194. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  195. data/src/core/lib/resource_quota/arena.h +2 -2
  196. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  197. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  198. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  199. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  200. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  201. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  203. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  207. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  208. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  209. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  210. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  211. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  212. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  213. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  214. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  215. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  216. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  217. data/src/core/lib/security/transport/auth_filters.h +71 -4
  218. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  219. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  220. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  221. data/src/core/lib/slice/slice_buffer.h +3 -0
  222. data/src/core/lib/surface/builtins.cc +1 -1
  223. data/src/core/lib/surface/call.cc +683 -196
  224. data/src/core/lib/surface/call.h +26 -13
  225. data/src/core/lib/surface/call_trace.cc +42 -1
  226. data/src/core/lib/surface/channel.cc +0 -1
  227. data/src/core/lib/surface/channel.h +0 -6
  228. data/src/core/lib/surface/channel_init.h +26 -0
  229. data/src/core/lib/surface/init.cc +14 -8
  230. data/src/core/lib/surface/server.cc +256 -237
  231. data/src/core/lib/surface/server.h +26 -54
  232. data/src/core/lib/surface/version.cc +2 -2
  233. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  234. data/src/core/lib/transport/call_final_info.cc +38 -0
  235. data/src/core/lib/transport/call_final_info.h +54 -0
  236. data/src/core/lib/transport/connectivity_state.cc +3 -2
  237. data/src/core/lib/transport/connectivity_state.h +4 -0
  238. data/src/core/lib/transport/metadata_batch.h +4 -4
  239. data/src/core/lib/transport/transport.cc +70 -19
  240. data/src/core/lib/transport/transport.h +395 -25
  241. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  242. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  243. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  244. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  245. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  246. data/src/core/tsi/ssl_transport_security.cc +65 -43
  247. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  248. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  249. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  252. data/src/ruby/lib/grpc/version.rb +1 -1
  253. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  254. data/third_party/zlib/adler32.c +5 -27
  255. data/third_party/zlib/compress.c +5 -16
  256. data/third_party/zlib/crc32.c +86 -162
  257. data/third_party/zlib/deflate.c +233 -336
  258. data/third_party/zlib/deflate.h +8 -8
  259. data/third_party/zlib/gzguts.h +11 -12
  260. data/third_party/zlib/infback.c +7 -23
  261. data/third_party/zlib/inffast.c +1 -4
  262. data/third_party/zlib/inffast.h +1 -1
  263. data/third_party/zlib/inflate.c +30 -99
  264. data/third_party/zlib/inftrees.c +6 -11
  265. data/third_party/zlib/inftrees.h +3 -3
  266. data/third_party/zlib/trees.c +224 -302
  267. data/third_party/zlib/uncompr.c +4 -12
  268. data/third_party/zlib/zconf.h +6 -2
  269. data/third_party/zlib/zlib.h +191 -188
  270. data/third_party/zlib/zutil.c +16 -44
  271. data/third_party/zlib/zutil.h +10 -10
  272. metadata +35 -13
  273. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  274. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  275. data/src/core/lib/transport/pid_controller.cc +0 -51
  276. data/src/core/lib/transport/pid_controller.h +0 -116
  277. data/third_party/upb/upb/collections/array.h +0 -17
  278. data/third_party/upb/upb/collections/map.h +0 -17
  279. data/third_party/upb/upb/upb.hpp +0 -18
@@ -219,7 +219,7 @@ class NonPolymorphicRefCount {
219
219
  // Default behavior: Delete the object.
220
220
  struct UnrefDelete {
221
221
  template <typename T>
222
- void operator()(T* p) {
222
+ void operator()(T* p) const {
223
223
  delete p;
224
224
  }
225
225
  };
@@ -231,7 +231,7 @@ struct UnrefDelete {
231
231
  // later by identifying entries for which RefIfNonZero() returns null.
232
232
  struct UnrefNoDelete {
233
233
  template <typename T>
234
- void operator()(T* /*p*/) {}
234
+ void operator()(T* /*p*/) const {}
235
235
  };
236
236
 
237
237
  // Call the object's dtor but do not delete it. This is useful for cases
@@ -239,7 +239,7 @@ struct UnrefNoDelete {
239
239
  // arena).
240
240
  struct UnrefCallDtor {
241
241
  template <typename T>
242
- void operator()(T* p) {
242
+ void operator()(T* p) const {
243
243
  p->~T();
244
244
  }
245
245
  };
@@ -276,35 +276,52 @@ class RefCounted : public Impl {
276
276
  public:
277
277
  using RefCountedChildType = Child;
278
278
 
279
+ // Not copyable nor movable.
280
+ RefCounted(const RefCounted&) = delete;
281
+ RefCounted& operator=(const RefCounted&) = delete;
282
+
279
283
  // Note: Depending on the Impl used, this dtor can be implicitly virtual.
280
284
  ~RefCounted() = default;
281
285
 
286
+ // Ref() for mutable types.
282
287
  GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref() {
283
288
  IncrementRefCount();
284
289
  return RefCountedPtr<Child>(static_cast<Child*>(this));
285
290
  }
286
-
287
291
  GRPC_MUST_USE_RESULT RefCountedPtr<Child> Ref(const DebugLocation& location,
288
292
  const char* reason) {
289
293
  IncrementRefCount(location, reason);
290
294
  return RefCountedPtr<Child>(static_cast<Child*>(this));
291
295
  }
292
296
 
293
- // TODO(roth): Once all of our code is converted to C++ and can use
294
- // RefCountedPtr<> instead of manual ref-counting, make this method
295
- // private, since it will only be used by RefCountedPtr<>, which is a
296
- // friend of this class.
297
- void Unref() {
298
- if (GPR_UNLIKELY(refs_.Unref())) {
299
- unref_behavior_(static_cast<Child*>(this));
300
- }
297
+ // Ref() for const types.
298
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> Ref() const {
299
+ IncrementRefCount();
300
+ return RefCountedPtr<const Child>(static_cast<const Child*>(this));
301
301
  }
302
- void Unref(const DebugLocation& location, const char* reason) {
303
- if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
304
- unref_behavior_(static_cast<Child*>(this));
305
- }
302
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> Ref(
303
+ const DebugLocation& location, const char* reason) const {
304
+ IncrementRefCount(location, reason);
305
+ return RefCountedPtr<const Child>(static_cast<const Child*>(this));
306
+ }
307
+
308
+ template <
309
+ typename Subclass,
310
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
311
+ RefCountedPtr<Subclass> RefAsSubclass() {
312
+ IncrementRefCount();
313
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
314
+ }
315
+ template <
316
+ typename Subclass,
317
+ std::enable_if_t<std::is_base_of<Child, Subclass>::value, bool> = true>
318
+ RefCountedPtr<Subclass> RefAsSubclass(const DebugLocation& location,
319
+ const char* reason) {
320
+ IncrementRefCount(location, reason);
321
+ return RefCountedPtr<Subclass>(static_cast<Subclass*>(this));
306
322
  }
307
323
 
324
+ // RefIfNonZero() for mutable types.
308
325
  GRPC_MUST_USE_RESULT RefCountedPtr<Child> RefIfNonZero() {
309
326
  return RefCountedPtr<Child>(refs_.RefIfNonZero() ? static_cast<Child*>(this)
310
327
  : nullptr);
@@ -316,9 +333,32 @@ class RefCounted : public Impl {
316
333
  : nullptr);
317
334
  }
318
335
 
319
- // Not copyable nor movable.
320
- RefCounted(const RefCounted&) = delete;
321
- RefCounted& operator=(const RefCounted&) = delete;
336
+ // RefIfNonZero() for const types.
337
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> RefIfNonZero() const {
338
+ return RefCountedPtr<const Child>(
339
+ refs_.RefIfNonZero() ? static_cast<const Child*>(this) : nullptr);
340
+ }
341
+ GRPC_MUST_USE_RESULT RefCountedPtr<const Child> RefIfNonZero(
342
+ const DebugLocation& location, const char* reason) const {
343
+ return RefCountedPtr<const Child>(refs_.RefIfNonZero(location, reason)
344
+ ? static_cast<const Child*>(this)
345
+ : nullptr);
346
+ }
347
+
348
+ // TODO(roth): Once all of our code is converted to C++ and can use
349
+ // RefCountedPtr<> instead of manual ref-counting, make this method
350
+ // private, since it will only be used by RefCountedPtr<>, which is a
351
+ // friend of this class.
352
+ void Unref() const {
353
+ if (GPR_UNLIKELY(refs_.Unref())) {
354
+ unref_behavior_(static_cast<const Child*>(this));
355
+ }
356
+ }
357
+ void Unref(const DebugLocation& location, const char* reason) const {
358
+ if (GPR_UNLIKELY(refs_.Unref(location, reason))) {
359
+ unref_behavior_(static_cast<const Child*>(this));
360
+ }
361
+ }
322
362
 
323
363
  protected:
324
364
  // Note: Tracing is a no-op on non-debug builds.
@@ -336,12 +376,13 @@ class RefCounted : public Impl {
336
376
  template <typename T>
337
377
  friend class RefCountedPtr;
338
378
 
339
- void IncrementRefCount() { refs_.Ref(); }
340
- void IncrementRefCount(const DebugLocation& location, const char* reason) {
379
+ void IncrementRefCount() const { refs_.Ref(); }
380
+ void IncrementRefCount(const DebugLocation& location,
381
+ const char* reason) const {
341
382
  refs_.Ref(location, reason);
342
383
  }
343
384
 
344
- RefCount refs_;
385
+ mutable RefCount refs_;
345
386
  GPR_NO_UNIQUE_ADDRESS UnrefBehavior unref_behavior_;
346
387
  };
347
388
 
@@ -43,7 +43,8 @@ class RefCountedPtr {
43
43
  RefCountedPtr(std::nullptr_t) {}
44
44
 
45
45
  // If value is non-null, we take ownership of a ref to it.
46
- template <typename Y>
46
+ template <typename Y,
47
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
47
48
  explicit RefCountedPtr(Y* value) : value_(value) {}
48
49
 
49
50
  // Move ctors.
@@ -51,7 +52,8 @@ class RefCountedPtr {
51
52
  value_ = other.value_;
52
53
  other.value_ = nullptr;
53
54
  }
54
- template <typename Y>
55
+ template <typename Y,
56
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
55
57
  // NOLINTNEXTLINE(google-explicit-constructor)
56
58
  RefCountedPtr(RefCountedPtr<Y>&& other) noexcept {
57
59
  value_ = static_cast<T*>(other.value_);
@@ -63,7 +65,8 @@ class RefCountedPtr {
63
65
  reset(std::exchange(other.value_, nullptr));
64
66
  return *this;
65
67
  }
66
- template <typename Y>
68
+ template <typename Y,
69
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
67
70
  RefCountedPtr& operator=(RefCountedPtr<Y>&& other) noexcept {
68
71
  reset(std::exchange(other.value_, nullptr));
69
72
  return *this;
@@ -74,7 +77,8 @@ class RefCountedPtr {
74
77
  if (other.value_ != nullptr) other.value_->IncrementRefCount();
75
78
  value_ = other.value_;
76
79
  }
77
- template <typename Y>
80
+ template <typename Y,
81
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
78
82
  // NOLINTNEXTLINE(google-explicit-constructor)
79
83
  RefCountedPtr(const RefCountedPtr<Y>& other) {
80
84
  static_assert(std::has_virtual_destructor<T>::value,
@@ -92,7 +96,8 @@ class RefCountedPtr {
92
96
  reset(other.value_);
93
97
  return *this;
94
98
  }
95
- template <typename Y>
99
+ template <typename Y,
100
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
96
101
  RefCountedPtr& operator=(const RefCountedPtr<Y>& other) {
97
102
  static_assert(std::has_virtual_destructor<T>::value,
98
103
  "T does not have a virtual dtor");
@@ -107,6 +112,12 @@ class RefCountedPtr {
107
112
  if (value_ != nullptr) value_->Unref();
108
113
  }
109
114
 
115
+ // An explicit copy method that supports ref-count tracing.
116
+ RefCountedPtr<T> Ref(const DebugLocation& location, const char* reason) {
117
+ if (value_ != nullptr) value_->IncrementRefCount(location, reason);
118
+ return RefCountedPtr<T>(value_);
119
+ }
120
+
110
121
  void swap(RefCountedPtr& other) { std::swap(value_, other.value_); }
111
122
 
112
123
  // If value is non-null, we take ownership of a ref to it.
@@ -119,13 +130,15 @@ class RefCountedPtr {
119
130
  T* old_value = std::exchange(value_, value);
120
131
  if (old_value != nullptr) old_value->Unref(location, reason);
121
132
  }
122
- template <typename Y>
133
+ template <typename Y,
134
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
123
135
  void reset(Y* value = nullptr) {
124
136
  static_assert(std::has_virtual_destructor<T>::value,
125
137
  "T does not have a virtual dtor");
126
138
  reset(static_cast<T*>(value));
127
139
  }
128
- template <typename Y>
140
+ template <typename Y,
141
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
129
142
  void reset(const DebugLocation& location, const char* reason,
130
143
  Y* value = nullptr) {
131
144
  static_assert(std::has_virtual_destructor<T>::value,
@@ -143,24 +156,34 @@ class RefCountedPtr {
143
156
  T& operator*() const { return *value_; }
144
157
  T* operator->() const { return value_; }
145
158
 
146
- template <typename Y>
159
+ template <typename Y,
160
+ std::enable_if_t<std::is_base_of<T, Y>::value, bool> = true>
161
+ RefCountedPtr<Y> TakeAsSubclass() {
162
+ return RefCountedPtr<Y>(static_cast<Y*>(release()));
163
+ }
164
+
165
+ template <typename Y,
166
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
147
167
  bool operator==(const RefCountedPtr<Y>& other) const {
148
168
  return value_ == other.value_;
149
169
  }
150
170
 
151
- template <typename Y>
171
+ template <typename Y,
172
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
152
173
  bool operator==(const Y* other) const {
153
174
  return value_ == other;
154
175
  }
155
176
 
156
177
  bool operator==(std::nullptr_t) const { return value_ == nullptr; }
157
178
 
158
- template <typename Y>
179
+ template <typename Y,
180
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
159
181
  bool operator!=(const RefCountedPtr<Y>& other) const {
160
182
  return value_ != other.value_;
161
183
  }
162
184
 
163
- template <typename Y>
185
+ template <typename Y,
186
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
164
187
  bool operator!=(const Y* other) const {
165
188
  return value_ != other;
166
189
  }
@@ -184,7 +207,8 @@ class WeakRefCountedPtr {
184
207
  WeakRefCountedPtr(std::nullptr_t) {}
185
208
 
186
209
  // If value is non-null, we take ownership of a ref to it.
187
- template <typename Y>
210
+ template <typename Y,
211
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
188
212
  explicit WeakRefCountedPtr(Y* value) {
189
213
  value_ = value;
190
214
  }
@@ -194,7 +218,8 @@ class WeakRefCountedPtr {
194
218
  value_ = other.value_;
195
219
  other.value_ = nullptr;
196
220
  }
197
- template <typename Y>
221
+ template <typename Y,
222
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
198
223
  // NOLINTNEXTLINE(google-explicit-constructor)
199
224
  WeakRefCountedPtr(WeakRefCountedPtr<Y>&& other) noexcept {
200
225
  value_ = static_cast<T*>(other.value_);
@@ -206,7 +231,8 @@ class WeakRefCountedPtr {
206
231
  reset(std::exchange(other.value_, nullptr));
207
232
  return *this;
208
233
  }
209
- template <typename Y>
234
+ template <typename Y,
235
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
210
236
  WeakRefCountedPtr& operator=(WeakRefCountedPtr<Y>&& other) noexcept {
211
237
  reset(std::exchange(other.value_, nullptr));
212
238
  return *this;
@@ -217,7 +243,8 @@ class WeakRefCountedPtr {
217
243
  if (other.value_ != nullptr) other.value_->IncrementWeakRefCount();
218
244
  value_ = other.value_;
219
245
  }
220
- template <typename Y>
246
+ template <typename Y,
247
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
221
248
  // NOLINTNEXTLINE(google-explicit-constructor)
222
249
  WeakRefCountedPtr(const WeakRefCountedPtr<Y>& other) {
223
250
  static_assert(std::has_virtual_destructor<T>::value,
@@ -235,7 +262,8 @@ class WeakRefCountedPtr {
235
262
  reset(other.value_);
236
263
  return *this;
237
264
  }
238
- template <typename Y>
265
+ template <typename Y,
266
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
239
267
  WeakRefCountedPtr& operator=(const WeakRefCountedPtr<Y>& other) {
240
268
  static_assert(std::has_virtual_destructor<T>::value,
241
269
  "T does not have a virtual dtor");
@@ -250,6 +278,13 @@ class WeakRefCountedPtr {
250
278
  if (value_ != nullptr) value_->WeakUnref();
251
279
  }
252
280
 
281
+ // An explicit copy method that supports ref-count tracing.
282
+ WeakRefCountedPtr<T> WeakRef(const DebugLocation& location,
283
+ const char* reason) {
284
+ if (value_ != nullptr) value_->IncrementWeakRefCount(location, reason);
285
+ return WeakRefCountedPtr<T>(value_);
286
+ }
287
+
253
288
  void swap(WeakRefCountedPtr& other) { std::swap(value_, other.value_); }
254
289
 
255
290
  // If value is non-null, we take ownership of a ref to it.
@@ -262,13 +297,15 @@ class WeakRefCountedPtr {
262
297
  T* old_value = std::exchange(value_, value);
263
298
  if (old_value != nullptr) old_value->WeakUnref(location, reason);
264
299
  }
265
- template <typename Y>
300
+ template <typename Y,
301
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
266
302
  void reset(Y* value = nullptr) {
267
303
  static_assert(std::has_virtual_destructor<T>::value,
268
304
  "T does not have a virtual dtor");
269
305
  reset(static_cast<T*>(value));
270
306
  }
271
- template <typename Y>
307
+ template <typename Y,
308
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
272
309
  void reset(const DebugLocation& location, const char* reason,
273
310
  Y* value = nullptr) {
274
311
  static_assert(std::has_virtual_destructor<T>::value,
@@ -280,35 +317,41 @@ class WeakRefCountedPtr {
280
317
  // us to pass a ref to idiomatic C code that does not use WeakRefCountedPtr<>.
281
318
  // Once all of our code has been converted to idiomatic C++, this
282
319
  // method should go away.
283
- T* release() {
284
- T* value = value_;
285
- value_ = nullptr;
286
- return value;
287
- }
320
+ T* release() { return std::exchange(value_, nullptr); }
288
321
 
289
322
  T* get() const { return value_; }
290
323
 
291
324
  T& operator*() const { return *value_; }
292
325
  T* operator->() const { return value_; }
293
326
 
294
- template <typename Y>
327
+ template <typename Y,
328
+ std::enable_if_t<std::is_base_of<T, Y>::value, bool> = true>
329
+ WeakRefCountedPtr<Y> TakeAsSubclass() {
330
+ return WeakRefCountedPtr<Y>(static_cast<Y*>(release()));
331
+ }
332
+
333
+ template <typename Y,
334
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
295
335
  bool operator==(const WeakRefCountedPtr<Y>& other) const {
296
336
  return value_ == other.value_;
297
337
  }
298
338
 
299
- template <typename Y>
339
+ template <typename Y,
340
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
300
341
  bool operator==(const Y* other) const {
301
342
  return value_ == other;
302
343
  }
303
344
 
304
345
  bool operator==(std::nullptr_t) const { return value_ == nullptr; }
305
346
 
306
- template <typename Y>
347
+ template <typename Y,
348
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
307
349
  bool operator!=(const WeakRefCountedPtr<Y>& other) const {
308
350
  return value_ != other.value_;
309
351
  }
310
352
 
311
- template <typename Y>
353
+ template <typename Y,
354
+ std::enable_if_t<std::is_convertible<Y*, T*>::value, bool> = true>
312
355
  bool operator!=(const Y* other) const {
313
356
  return value_ != other;
314
357
  }
@@ -104,6 +104,19 @@ inline bool operator==(const RefCountedStringValue& lhs,
104
104
  return lhs.as_string_view() == rhs.as_string_view();
105
105
  }
106
106
 
107
+ inline bool operator!=(const RefCountedStringValue& lhs,
108
+ absl::string_view rhs) {
109
+ return lhs.as_string_view() != rhs;
110
+ }
111
+ inline bool operator!=(absl::string_view lhs,
112
+ const RefCountedStringValue& rhs) {
113
+ return lhs != rhs.as_string_view();
114
+ }
115
+ inline bool operator!=(const RefCountedStringValue& lhs,
116
+ const RefCountedStringValue& rhs) {
117
+ return lhs.as_string_view() != rhs.as_string_view();
118
+ }
119
+
107
120
  inline bool operator<(const RefCountedStringValue& lhs, absl::string_view rhs) {
108
121
  return lhs.as_string_view() < rhs;
109
122
  }
@@ -34,8 +34,7 @@
34
34
  #include "google/protobuf/any.upb.h"
35
35
  #include "google/rpc/status.upb.h"
36
36
  #include "upb/base/string_view.h"
37
- #include "upb/mem/arena.h"
38
- #include "upb/upb.hpp"
37
+ #include "upb/mem/arena.hpp"
39
38
 
40
39
  #include <grpc/support/log.h>
41
40
 
@@ -51,19 +51,11 @@ static void combiner_finally_exec(grpc_core::Combiner* lock,
51
51
  grpc_closure* closure,
52
52
  grpc_error_handle error);
53
53
 
54
- // TODO(ctiller): delete this when the combiner_offload_to_event_engine
55
- // experiment is removed.
56
- static void offload(void* arg, grpc_error_handle error);
57
-
58
54
  grpc_core::Combiner* grpc_combiner_create(
59
55
  std::shared_ptr<grpc_event_engine::experimental::EventEngine>
60
56
  event_engine) {
61
57
  grpc_core::Combiner* lock = new grpc_core::Combiner();
62
- if (grpc_core::IsCombinerOffloadToEventEngineEnabled()) {
63
- lock->event_engine = event_engine;
64
- } else {
65
- GRPC_CLOSURE_INIT(&lock->offload, offload, lock, nullptr);
66
- }
58
+ lock->event_engine = event_engine;
67
59
  gpr_ref_init(&lock->refs, 1);
68
60
  gpr_atm_no_barrier_store(&lock->state, STATE_UNORPHANED);
69
61
  grpc_closure_list_init(&lock->final_list);
@@ -173,27 +165,18 @@ static void move_next() {
173
165
  }
174
166
  }
175
167
 
176
- static void offload(void* arg, grpc_error_handle /*error*/) {
177
- grpc_core::Combiner* lock = static_cast<grpc_core::Combiner*>(arg);
178
- push_last_on_exec_ctx(lock);
179
- }
180
-
181
168
  static void queue_offload(grpc_core::Combiner* lock) {
182
169
  move_next();
183
170
  // Make the combiner look uncontended by storing a non-null value here, so
184
171
  // that we don't immediately offload again.
185
172
  gpr_atm_no_barrier_store(&lock->initiating_exec_ctx_or_null, 1);
186
173
  GRPC_COMBINER_TRACE(gpr_log(GPR_INFO, "C:%p queue_offload", lock));
187
- if (grpc_core::IsCombinerOffloadToEventEngineEnabled()) {
188
- lock->event_engine->Run([lock] {
189
- grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
190
- grpc_core::ExecCtx exec_ctx(0);
191
- push_last_on_exec_ctx(lock);
192
- exec_ctx.Flush();
193
- });
194
- } else {
195
- grpc_core::Executor::Run(&lock->offload, absl::OkStatus());
196
- }
174
+ lock->event_engine->Run([lock] {
175
+ grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
176
+ grpc_core::ExecCtx exec_ctx(0);
177
+ push_last_on_exec_ctx(lock);
178
+ exec_ctx.Flush();
179
+ });
197
180
  }
198
181
 
199
182
  bool grpc_combiner_continue_exec_ctx() {
@@ -215,33 +198,14 @@ bool grpc_combiner_continue_exec_ctx() {
215
198
  grpc_core::ExecCtx::Get()->IsReadyToFinish(),
216
199
  lock->time_to_execute_final_list));
217
200
 
218
- if (grpc_core::IsCombinerOffloadToEventEngineEnabled()) {
219
- // offload only if both (1) the combiner is contended and has more than one
220
- // closure to execute, and (2) the current execution context needs to finish
221
- // as soon as possible
222
- if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish()) {
223
- // this execution context wants to move on: schedule remaining work to be
224
- // picked up on the executor
225
- queue_offload(lock);
226
- return true;
227
- }
228
- } else {
229
- // TODO(ctiller): delete this when the combiner_offload_to_event_engine
230
- // experiment is removed.
231
-
232
- // offload only if all the following conditions are true:
233
- // 1. the combiner is contended and has more than one closure to execute
234
- // 2. the current execution context needs to finish as soon as possible
235
- // 3. the current thread is not a worker for any background poller
236
- // 4. the DEFAULT executor is threaded
237
- if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish() &&
238
- !grpc_iomgr_platform_is_any_background_poller_thread() &&
239
- grpc_core::Executor::IsThreadedDefault()) {
240
- // this execution context wants to move on: schedule remaining work to be
241
- // picked up on the executor
242
- queue_offload(lock);
243
- return true;
244
- }
201
+ // offload only if both (1) the combiner is contended and has more than one
202
+ // closure to execute, and (2) the current execution context needs to finish
203
+ // as soon as possible
204
+ if (contended && grpc_core::ExecCtx::Get()->IsReadyToFinish()) {
205
+ // this execution context wants to move on: schedule remaining work to be
206
+ // picked up on the executor
207
+ queue_offload(lock);
208
+ return true;
245
209
  }
246
210
 
247
211
  if (!lock->time_to_execute_final_list ||
@@ -17,6 +17,7 @@
17
17
 
18
18
  #include <atomic>
19
19
  #include <memory>
20
+ #include <utility>
20
21
 
21
22
  #include "absl/functional/any_invocable.h"
22
23
  #include "absl/status/status.h"
@@ -69,6 +70,12 @@ class EventEngineEndpointWrapper {
69
70
  explicit EventEngineEndpointWrapper(
70
71
  std::unique_ptr<EventEngine::Endpoint> endpoint);
71
72
 
73
+ EventEngine::Endpoint* endpoint() { return endpoint_.get(); }
74
+
75
+ std::unique_ptr<EventEngine::Endpoint> ReleaseEndpoint() {
76
+ return std::move(endpoint_);
77
+ }
78
+
72
79
  int Fd() {
73
80
  grpc_core::MutexLock lock(&mu_);
74
81
  return fd_;
@@ -428,6 +435,30 @@ bool grpc_is_event_engine_endpoint(grpc_endpoint* ep) {
428
435
  return ep->vtable == &grpc_event_engine_endpoint_vtable;
429
436
  }
430
437
 
438
+ EventEngine::Endpoint* grpc_get_wrapped_event_engine_endpoint(
439
+ grpc_endpoint* ep) {
440
+ if (!grpc_is_event_engine_endpoint(ep)) {
441
+ return nullptr;
442
+ }
443
+ auto* eeep =
444
+ reinterpret_cast<EventEngineEndpointWrapper::grpc_event_engine_endpoint*>(
445
+ ep);
446
+ return eeep->wrapper->endpoint();
447
+ }
448
+
449
+ std::unique_ptr<EventEngine::Endpoint> grpc_take_wrapped_event_engine_endpoint(
450
+ grpc_endpoint* ep) {
451
+ if (!grpc_is_event_engine_endpoint(ep)) {
452
+ return nullptr;
453
+ }
454
+ auto* eeep =
455
+ reinterpret_cast<EventEngineEndpointWrapper::grpc_event_engine_endpoint*>(
456
+ ep);
457
+ auto endpoint = eeep->wrapper->ReleaseEndpoint();
458
+ delete eeep->wrapper;
459
+ return endpoint;
460
+ }
461
+
431
462
  void grpc_event_engine_endpoint_destroy_and_release_fd(
432
463
  grpc_endpoint* ep, int* fd, grpc_closure* on_release_fd) {
433
464
  auto* eeep =
@@ -15,6 +15,8 @@
15
15
  #define GRPC_SRC_CORE_LIB_IOMGR_EVENT_ENGINE_SHIMS_ENDPOINT_H
16
16
  #include <grpc/support/port_platform.h>
17
17
 
18
+ #include <memory>
19
+
18
20
  #include <grpc/event_engine/event_engine.h>
19
21
 
20
22
  #include "src/core/lib/iomgr/endpoint.h"
@@ -31,6 +33,20 @@ grpc_endpoint* grpc_event_engine_endpoint_create(
31
33
  /// Returns true if the passed endpoint is an event engine shim endpoint.
32
34
  bool grpc_is_event_engine_endpoint(grpc_endpoint* ep);
33
35
 
36
+ /// Returns the wrapped event engine endpoint if the given grpc_endpoint is an
37
+ /// event engine shim endpoint. Otherwise it returns nullptr.
38
+ EventEngine::Endpoint* grpc_get_wrapped_event_engine_endpoint(
39
+ grpc_endpoint* ep);
40
+
41
+ /// Transfers ownership of the wrapped event engine endpoint if the given
42
+ /// grpc_endpoint is an event engine shim endpoint. Otherwise it returns
43
+ /// nullptr. If the passed ep wraps an event_engine endpoint, then after this
44
+ /// call, the memory location holding by the passed ep is free'ed.
45
+ /// Its safe to call this function only when there are no pending reads/writes
46
+ /// on the endpoint.
47
+ std::unique_ptr<EventEngine::Endpoint> grpc_take_wrapped_event_engine_endpoint(
48
+ grpc_endpoint* ep);
49
+
34
50
  /// Destroys the passed in event engine shim endpoint and schedules the
35
51
  /// asynchronous execution of the on_release_fd callback. The int pointer fd is
36
52
  /// set to the underlying endpoint's file descriptor.
@@ -336,6 +336,7 @@ int64_t grpc_tcp_client_create_from_prepared_fd(
336
336
  err = connect(fd, reinterpret_cast<const grpc_sockaddr*>(addr->addr),
337
337
  addr->len);
338
338
  } while (err < 0 && errno == EINTR);
339
+ int connect_errno = (err < 0) ? errno : 0;
339
340
 
340
341
  auto addr_uri = grpc_sockaddr_to_uri(addr);
341
342
  if (!addr_uri.ok()) {
@@ -347,7 +348,7 @@ int64_t grpc_tcp_client_create_from_prepared_fd(
347
348
  std::string name = absl::StrCat("tcp-client:", addr_uri.value());
348
349
  grpc_fd* fdobj = grpc_fd_create(fd, name.c_str(), true);
349
350
  int64_t connection_id = 0;
350
- if (errno == EWOULDBLOCK || errno == EINPROGRESS) {
351
+ if (connect_errno == EWOULDBLOCK || connect_errno == EINPROGRESS) {
351
352
  // Connection is still in progress.
352
353
  connection_id = g_connection_id.fetch_add(1, std::memory_order_acq_rel);
353
354
  }
@@ -359,10 +360,10 @@ int64_t grpc_tcp_client_create_from_prepared_fd(
359
360
  grpc_core::ExecCtx::Run(DEBUG_LOCATION, closure, absl::OkStatus());
360
361
  return 0;
361
362
  }
362
- if (errno != EWOULDBLOCK && errno != EINPROGRESS) {
363
+ if (connect_errno != EWOULDBLOCK && connect_errno != EINPROGRESS) {
363
364
  // Connection already failed. Return 0 to discourage any cancellation
364
365
  // attempts.
365
- grpc_error_handle error = GRPC_OS_ERROR(errno, "connect");
366
+ grpc_error_handle error = GRPC_OS_ERROR(connect_errno, "connect");
366
367
  error = grpc_error_set_str(
367
368
  error, grpc_core::StatusStrProperty::kTargetAddress, addr_uri.value());
368
369
  grpc_fd_orphan(fdobj, nullptr, nullptr, "tcp_client_connect_error");
@@ -346,7 +346,7 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
346
346
  struct UpdateArgs {
347
347
  /// A list of endpoints, each with one or more address, or an error
348
348
  /// indicating a failure to obtain the list of addresses.
349
- absl::StatusOr<EndpointAddressesList> addresses;
349
+ absl::StatusOr<std::shared_ptr<EndpointAddressesIterator>> addresses;
350
350
  /// The LB policy config.
351
351
  RefCountedPtr<Config> config;
352
352
  /// A human-readable note providing context about the name resolution that