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.
- checksums.yaml +4 -4
- data/Makefile +38 -17
- data/include/grpc/create_channel_from_endpoint.h +54 -0
- data/include/grpc/credentials.h +11 -5
- data/include/grpc/event_engine/event_engine.h +74 -17
- data/include/grpc/grpc_posix.h +20 -1
- data/include/grpc/impl/channel_arg_names.h +2 -4
- data/include/grpc/module.modulemap +1 -0
- data/include/grpc/support/json.h +24 -0
- data/src/core/call/interception_chain.h +7 -11
- data/src/core/channelz/channel_trace.cc +213 -115
- data/src/core/channelz/channel_trace.h +380 -86
- data/src/core/channelz/channelz.cc +270 -181
- data/src/core/channelz/channelz.h +168 -55
- data/src/core/channelz/channelz_registry.cc +2 -1
- data/src/core/channelz/channelz_registry.h +24 -0
- data/src/core/channelz/property_list.cc +357 -0
- data/src/core/channelz/property_list.h +202 -0
- data/src/core/channelz/ztrace_collector.h +3 -2
- data/src/core/client_channel/backup_poller.cc +17 -2
- data/src/core/client_channel/client_channel.cc +17 -28
- data/src/core/client_channel/client_channel_filter.cc +19 -29
- data/src/core/client_channel/config_selector.h +8 -2
- data/src/core/client_channel/dynamic_filters.cc +5 -6
- data/src/core/client_channel/dynamic_filters.h +1 -1
- data/src/core/client_channel/global_subchannel_pool.cc +4 -1
- data/src/core/client_channel/retry_filter.cc +21 -27
- data/src/core/client_channel/retry_filter.h +10 -7
- data/src/core/client_channel/retry_filter_legacy_call_data.cc +5 -5
- data/src/core/client_channel/retry_filter_legacy_call_data.h +1 -1
- data/src/core/client_channel/retry_interceptor.cc +30 -44
- data/src/core/client_channel/retry_interceptor.h +18 -17
- data/src/core/client_channel/retry_throttle.cc +46 -61
- data/src/core/client_channel/retry_throttle.h +17 -39
- data/src/core/client_channel/subchannel.cc +43 -19
- data/src/core/client_channel/subchannel.h +8 -0
- data/src/core/config/config_vars.cc +2 -0
- data/src/core/config/core_configuration.cc +1 -0
- data/src/core/config/core_configuration.h +11 -0
- data/src/core/credentials/call/call_creds_registry.h +125 -0
- data/src/core/credentials/call/call_creds_registry_init.cc +91 -0
- data/src/core/credentials/call/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +6 -48
- data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.cc +86 -0
- data/src/core/credentials/call/jwt_token_file/jwt_token_file_call_credentials.h +74 -0
- data/src/core/credentials/call/jwt_util.cc +70 -0
- data/src/core/credentials/call/jwt_util.h +32 -0
- data/src/core/credentials/transport/channel_creds_registry_init.cc +1 -1
- data/src/core/credentials/transport/google_default/google_default_credentials.cc +72 -4
- data/src/core/credentials/transport/ssl/ssl_credentials.cc +0 -1
- data/src/core/credentials/transport/tls/load_system_roots_supported.cc +1 -0
- data/src/core/credentials/transport/xds/xds_credentials.cc +0 -3
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +8 -8
- data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +16 -16
- data/src/core/ext/filters/http/client_authority_filter.cc +2 -4
- data/src/core/ext/filters/http/message_compress/compression_filter.h +25 -22
- data/src/core/ext/filters/http/server/http_server_filter.h +12 -11
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +120 -35
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +6 -5
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +162 -115
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +0 -3
- data/src/core/ext/transport/chttp2/transport/decode_huff.cc +1239 -3514
- data/src/core/ext/transport/chttp2/transport/decode_huff.h +1008 -1486
- data/src/core/ext/transport/chttp2/transport/flow_control.h +22 -17
- data/src/core/ext/transport/chttp2/transport/frame.cc +10 -0
- data/src/core/ext/transport/chttp2/transport/frame.h +2 -2
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +7 -8
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -5
- data/src/core/ext/transport/chttp2/transport/header_assembler.h +299 -0
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +11 -5
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +12 -1
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +1017 -0
- data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +593 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +19 -22
- data/{third_party/abseil-cpp/absl/strings/cord_buffer.cc → src/core/ext/transport/chttp2/transport/http2_stats_collector.cc} +14 -14
- data/src/core/ext/transport/chttp2/transport/http2_stats_collector.h +33 -0
- data/src/core/ext/transport/chttp2/transport/http2_status.h +6 -1
- data/src/core/ext/transport/chttp2/transport/http2_transport.cc +43 -0
- data/src/core/ext/transport/chttp2/transport/http2_transport.h +65 -0
- data/src/core/ext/transport/chttp2/transport/http2_ztrace_collector.h +0 -29
- data/src/core/ext/transport/chttp2/transport/internal.h +18 -8
- data/src/core/ext/transport/chttp2/transport/keepalive.cc +105 -0
- data/src/core/ext/transport/chttp2/transport/keepalive.h +138 -0
- data/src/core/ext/transport/chttp2/transport/message_assembler.h +185 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +2 -4
- data/src/core/ext/transport/chttp2/transport/ping_callbacks.h +19 -0
- data/src/core/ext/transport/chttp2/transport/ping_promise.cc +151 -0
- data/src/core/ext/transport/chttp2/transport/ping_promise.h +180 -0
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.cc +5 -9
- data/src/core/ext/transport/chttp2/transport/ping_rate_policy.h +11 -0
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +39 -1
- data/src/core/ext/transport/chttp2/transport/transport_common.cc +19 -0
- data/src/core/ext/transport/chttp2/transport/transport_common.h +27 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +37 -11
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb.h +571 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.c +120 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/channelz.upb_minitable.h +36 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb.h +1272 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.c +312 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/promise.upb_minitable.h +50 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb.h +984 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.c +226 -0
- data/src/core/ext/upb-gen/src/proto/grpc/channelz/v2/property_list.upb_minitable.h +44 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.c +175 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/promise.upbdefs.h +82 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.c +135 -0
- data/src/core/ext/upbdefs-gen/src/proto/grpc/channelz/v2/property_list.upbdefs.h +67 -0
- data/src/core/filter/auth/auth_filters.h +0 -25
- data/src/core/filter/auth/client_auth_filter.cc +0 -118
- data/src/core/filter/filter_args.h +9 -23
- data/src/core/handshaker/handshaker.cc +23 -14
- data/src/core/handshaker/handshaker.h +3 -0
- data/src/core/handshaker/http_connect/http_connect_handshaker.cc +3 -1
- data/src/core/handshaker/security/legacy_secure_endpoint.cc +6 -5
- data/src/core/handshaker/security/secure_endpoint.cc +70 -25
- data/src/core/handshaker/security/security_handshaker.cc +4 -1
- data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +7 -1
- data/src/core/lib/channel/channel_args.cc +15 -0
- data/src/core/lib/channel/channel_args.h +3 -0
- data/src/core/lib/channel/channel_stack.cc +22 -23
- data/src/core/lib/channel/channel_stack.h +9 -7
- data/src/core/lib/channel/channel_stack_builder_impl.cc +1 -1
- data/src/core/lib/channel/channel_stack_builder_impl.h +2 -7
- data/src/core/lib/channel/promise_based_filter.h +5 -5
- data/src/core/lib/debug/trace_impl.h +0 -1
- data/src/core/lib/event_engine/ares_resolver.cc +165 -46
- data/src/core/lib/event_engine/ares_resolver.h +48 -2
- data/src/core/lib/event_engine/cf_engine/cf_engine.cc +3 -1
- data/src/core/lib/event_engine/cf_engine/cf_engine.h +1 -4
- data/src/core/lib/event_engine/cf_engine/cfstream_endpoint.h +2 -6
- data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.cc +40 -0
- data/src/core/lib/event_engine/endpoint_channel_arg_wrapper.h +60 -0
- data/src/core/lib/event_engine/event_engine.cc +7 -0
- data/src/core/lib/event_engine/extensions/channelz.h +10 -6
- data/src/core/lib/event_engine/grpc_polled_fd.h +5 -0
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +130 -162
- data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.h +11 -15
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +75 -117
- data/src/core/lib/event_engine/posix_engine/ev_poll_posix.h +7 -9
- data/src/core/lib/event_engine/posix_engine/event_poller.h +18 -15
- data/src/core/lib/event_engine/posix_engine/event_poller_posix_default.cc +0 -18
- data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +124 -0
- data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.h +243 -0
- data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +29 -19
- data/src/core/lib/event_engine/posix_engine/internal_errqueue.cc +6 -2
- data/src/core/lib/event_engine/posix_engine/internal_errqueue.h +6 -1
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +145 -92
- data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +9 -19
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +333 -116
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +61 -18
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +45 -37
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +6 -4
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +32 -142
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.h +6 -5
- data/src/core/lib/event_engine/posix_engine/posix_interface.h +211 -0
- data/src/core/lib/event_engine/posix_engine/posix_interface_posix.cc +1083 -0
- data/src/core/lib/event_engine/posix_engine/posix_interface_windows.cc +281 -0
- data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.cc +154 -0
- data/src/core/lib/event_engine/posix_engine/posix_write_event_sink.h +174 -0
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +3 -719
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +10 -170
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +33 -22
- data/src/core/lib/event_engine/posix_engine/timer_manager.h +13 -11
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +117 -151
- data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +26 -94
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.cc +26 -25
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_eventfd.h +6 -2
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.cc +36 -62
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_pipe.h +6 -2
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix.h +7 -6
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.cc +12 -6
- data/src/core/lib/event_engine/posix_engine/wakeup_fd_posix_default.h +3 -1
- data/src/core/lib/event_engine/shim.cc +9 -0
- data/src/core/lib/event_engine/shim.h +3 -0
- data/src/core/lib/event_engine/thread_pool/thread_pool.h +7 -3
- data/src/core/lib/event_engine/thread_pool/thread_pool_factory.cc +0 -17
- data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +4 -2
- data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +3 -2
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +4 -0
- data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.h +4 -0
- data/src/core/lib/event_engine/windows/windows_endpoint.h +2 -6
- data/src/core/lib/event_engine/windows/windows_engine.cc +0 -1
- data/src/core/lib/event_engine/windows/windows_engine.h +1 -3
- data/src/core/lib/event_engine/windows/windows_listener.cc +14 -2
- data/src/core/lib/experiments/experiments.cc +45 -93
- data/src/core/lib/experiments/experiments.h +21 -51
- data/src/core/lib/iomgr/endpoint.cc +4 -3
- data/src/core/lib/iomgr/endpoint.h +7 -4
- data/src/core/lib/iomgr/endpoint_cfstream.cc +3 -2
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +7 -2
- data/src/core/lib/iomgr/ev_poll_posix.cc +7 -2
- data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +4 -6
- data/src/core/lib/iomgr/tcp_posix.cc +12 -6
- data/src/core/lib/iomgr/tcp_windows.cc +3 -2
- data/src/core/lib/promise/activity.h +1 -0
- data/src/core/lib/promise/arena_promise.h +23 -7
- data/src/core/lib/promise/detail/promise_factory.h +10 -0
- data/src/core/lib/promise/detail/promise_like.h +118 -11
- data/src/core/lib/promise/detail/promise_variant.h +50 -0
- data/src/core/lib/promise/detail/seq_state.h +687 -548
- data/src/core/lib/promise/if.h +20 -0
- data/src/core/lib/promise/inter_activity_latch.h +147 -0
- data/src/core/lib/promise/inter_activity_mutex.h +547 -0
- data/src/core/lib/promise/loop.h +65 -3
- data/src/core/lib/promise/map.h +24 -0
- data/src/core/lib/promise/match_promise.h +103 -0
- data/src/core/lib/promise/mpsc.cc +425 -0
- data/src/core/lib/promise/mpsc.h +490 -0
- data/src/core/lib/promise/party.cc +50 -1
- data/src/core/lib/promise/party.h +66 -1
- data/src/core/lib/promise/race.h +31 -0
- data/src/core/lib/promise/seq.h +4 -1
- data/src/core/lib/promise/status_flag.h +7 -0
- data/src/core/lib/promise/try_seq.h +4 -1
- data/src/core/lib/promise/wait_set.cc +28 -0
- data/src/core/lib/promise/wait_set.h +86 -0
- data/src/core/lib/resource_quota/arena.h +19 -0
- data/src/core/lib/slice/slice.h +5 -0
- data/src/core/lib/surface/channel_create.cc +88 -13
- data/src/core/lib/surface/channel_create.h +4 -0
- data/src/core/lib/surface/channel_init.cc +164 -47
- data/src/core/lib/surface/channel_init.h +64 -1
- data/src/core/lib/surface/filter_stack_call.cc +18 -9
- data/src/core/lib/surface/init.cc +6 -15
- data/src/core/lib/surface/legacy_channel.cc +3 -5
- data/src/core/lib/surface/legacy_channel.h +3 -1
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/promise_endpoint.cc +110 -0
- data/src/core/lib/transport/promise_endpoint.h +307 -0
- data/src/core/load_balancing/child_policy_handler.cc +2 -4
- data/src/core/load_balancing/delegating_helper.h +2 -3
- data/src/core/load_balancing/health_check_client.cc +1 -5
- data/src/core/load_balancing/lb_policy.h +1 -3
- data/src/core/load_balancing/oob_backend_metric.cc +1 -5
- data/src/core/load_balancing/pick_first/pick_first.cc +3 -0
- data/src/core/load_balancing/xds/cds.cc +10 -1
- data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +2 -0
- data/src/core/resolver/xds/xds_config.cc +6 -3
- data/src/core/resolver/xds/xds_config.h +9 -4
- data/src/core/resolver/xds/xds_dependency_manager.cc +21 -6
- data/src/core/resolver/xds/xds_dependency_manager.h +2 -1
- data/src/core/resolver/xds/xds_resolver.cc +31 -11
- data/src/core/server/server.cc +83 -12
- data/src/core/server/server.h +21 -2
- data/src/core/server/xds_server_config_fetcher.cc +63 -25
- data/src/core/service_config/service_config.h +1 -1
- data/src/core/service_config/service_config_impl.h +1 -1
- data/src/core/telemetry/context_list_entry.cc +38 -0
- data/src/core/telemetry/context_list_entry.h +42 -12
- data/src/core/telemetry/stats_data.cc +233 -207
- data/src/core/telemetry/stats_data.h +250 -153
- data/src/core/telemetry/tcp_tracer.h +1 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +11 -3
- data/src/core/tsi/fake_transport_security.cc +17 -0
- data/src/core/tsi/ssl_transport_security.cc +2 -0
- data/src/core/tsi/transport_security_grpc.cc +8 -0
- data/src/core/tsi/transport_security_grpc.h +15 -0
- data/src/core/util/backoff.cc +1 -5
- data/src/core/util/backoff.h +1 -0
- data/src/core/util/down_cast.h +1 -1
- data/src/core/util/function_signature.h +15 -1
- data/src/core/util/http_client/httpcli.cc +12 -5
- data/src/core/util/http_client/httpcli.h +4 -1
- data/src/core/util/latent_see.h +8 -5
- data/src/core/util/log.cc +4 -0
- data/src/core/util/memory_usage.h +268 -0
- data/src/core/util/per_cpu.cc +2 -0
- data/src/core/util/per_cpu.h +7 -0
- data/src/core/util/shared_bit_gen.h +20 -0
- data/src/core/util/single_set_ptr.h +2 -2
- data/src/core/util/upb_utils.h +42 -0
- data/src/core/util/uri.cc +3 -2
- data/src/core/util/useful.h +53 -2
- data/src/core/util/wait_for_single_owner.cc +31 -0
- data/src/core/util/wait_for_single_owner.h +24 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc.cc +2 -0
- data/src/core/xds/grpc/xds_bootstrap_grpc.h +5 -0
- data/src/core/xds/grpc/xds_client_grpc.cc +6 -2
- data/src/core/xds/grpc/xds_common_types_parser.cc +138 -50
- data/src/core/xds/grpc/xds_common_types_parser.h +12 -0
- data/src/core/xds/grpc/xds_http_filter.h +7 -0
- data/src/core/xds/grpc/xds_http_gcp_authn_filter.cc +22 -0
- data/src/core/xds/grpc/xds_http_gcp_authn_filter.h +3 -0
- data/src/core/xds/grpc/xds_route_config_parser.cc +15 -38
- data/src/core/xds/grpc/xds_server_grpc.cc +63 -13
- data/src/core/xds/grpc/xds_server_grpc.h +10 -2
- data/src/core/xds/grpc/xds_server_grpc_interface.h +4 -0
- data/src/core/xds/grpc/xds_transport_grpc.cc +18 -0
- data/src/core/xds/xds_client/xds_bootstrap.h +2 -0
- data/src/core/xds/xds_client/xds_client.cc +26 -5
- data/src/ruby/ext/grpc/extconf.rb +2 -0
- data/src/ruby/ext/grpc/rb_call.c +1 -8
- data/src/ruby/ext/grpc/rb_channel.c +72 -568
- data/src/ruby/ext/grpc/rb_channel.h +0 -3
- data/src/ruby/ext/grpc/rb_completion_queue.c +26 -14
- data/src/ruby/ext/grpc/rb_completion_queue.h +1 -7
- data/src/ruby/ext/grpc/rb_grpc.c +9 -5
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +1 -1
- data/src/ruby/ext/grpc/rb_loader.c +0 -4
- data/src/ruby/ext/grpc/rb_server.c +31 -50
- data/src/ruby/lib/grpc/generic/client_stub.rb +4 -4
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/core_spec.rb +22 -0
- data/src/ruby/spec/generic/active_call_spec.rb +1 -1
- data/third_party/abseil-cpp/absl/algorithm/container.h +2 -19
- data/third_party/abseil-cpp/absl/base/attributes.h +76 -7
- data/third_party/abseil-cpp/absl/base/call_once.h +11 -12
- data/third_party/abseil-cpp/absl/base/config.h +20 -129
- data/third_party/abseil-cpp/absl/base/{internal/fast_type_id.h → fast_type_id.h} +11 -16
- data/third_party/abseil-cpp/absl/base/internal/cycleclock.cc +0 -5
- data/third_party/abseil-cpp/absl/base/internal/cycleclock_config.h +7 -7
- data/third_party/abseil-cpp/absl/base/internal/endian.h +34 -38
- data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +71 -0
- data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +6 -5
- data/third_party/abseil-cpp/absl/base/internal/{nullability_impl.h → nullability_deprecated.h} +45 -8
- data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +0 -9
- data/third_party/abseil-cpp/absl/base/internal/spinlock.h +3 -13
- data/third_party/abseil-cpp/absl/base/internal/unaligned_access.h +6 -6
- data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +8 -3
- data/third_party/abseil-cpp/absl/base/no_destructor.h +11 -32
- data/third_party/abseil-cpp/absl/base/nullability.h +84 -72
- data/third_party/abseil-cpp/absl/base/options.h +3 -80
- data/third_party/abseil-cpp/absl/base/policy_checks.h +7 -7
- data/third_party/abseil-cpp/absl/cleanup/cleanup.h +1 -3
- data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -4
- data/third_party/abseil-cpp/absl/container/btree_map.h +4 -2
- data/third_party/abseil-cpp/absl/container/btree_set.h +4 -2
- data/third_party/abseil-cpp/absl/container/fixed_array.h +7 -14
- data/third_party/abseil-cpp/absl/container/flat_hash_map.h +5 -0
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +6 -1
- data/third_party/abseil-cpp/absl/container/inlined_vector.h +8 -5
- data/third_party/abseil-cpp/absl/container/internal/btree.h +132 -29
- data/third_party/abseil-cpp/absl/container/internal/btree_container.h +175 -71
- data/third_party/abseil-cpp/absl/container/internal/common.h +43 -0
- data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -2
- data/third_party/abseil-cpp/absl/container/internal/container_memory.h +9 -10
- data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +1 -8
- data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +0 -4
- data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +527 -0
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +20 -4
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +31 -12
- data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +2 -7
- data/third_party/abseil-cpp/absl/container/internal/layout.h +26 -42
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +199 -68
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +1354 -183
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +881 -1424
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +80 -0
- data/third_party/abseil-cpp/absl/crc/crc32c.cc +0 -4
- data/third_party/abseil-cpp/absl/crc/crc32c.h +7 -5
- data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +0 -22
- data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +45 -74
- data/third_party/abseil-cpp/absl/debugging/internal/addresses.h +57 -0
- data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.cc +1 -1
- data/third_party/abseil-cpp/absl/debugging/internal/decode_rust_punycode.h +5 -5
- data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +8 -35
- data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc +16 -16
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +40 -37
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +16 -7
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +14 -5
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +10 -4
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +27 -16
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +13 -4
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +4 -3
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +15 -28
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +19 -9
- data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +144 -27
- data/third_party/abseil-cpp/absl/debugging/stacktrace.h +73 -5
- data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +19 -9
- data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +3 -2
- data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +25 -6
- data/third_party/abseil-cpp/absl/flags/commandlineflag.h +2 -2
- data/third_party/abseil-cpp/absl/flags/flag.h +4 -3
- data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +2 -2
- data/third_party/abseil-cpp/absl/flags/internal/flag.cc +2 -1
- data/third_party/abseil-cpp/absl/flags/internal/flag.h +7 -6
- data/third_party/abseil-cpp/absl/flags/internal/registry.h +4 -3
- data/third_party/abseil-cpp/absl/flags/reflection.cc +2 -3
- data/third_party/abseil-cpp/absl/functional/any_invocable.h +8 -10
- data/third_party/abseil-cpp/absl/functional/function_ref.h +2 -9
- data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +110 -226
- data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +10 -12
- data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +2 -5
- data/third_party/abseil-cpp/absl/hash/hash.h +18 -0
- data/third_party/abseil-cpp/absl/hash/internal/hash.cc +1 -5
- data/third_party/abseil-cpp/absl/hash/internal/hash.h +86 -61
- data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +25 -68
- data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +2 -6
- data/third_party/abseil-cpp/absl/hash/internal/weakly_mixed_integer.h +38 -0
- data/third_party/abseil-cpp/absl/log/check.h +2 -1
- data/third_party/abseil-cpp/absl/log/globals.h +4 -5
- data/third_party/abseil-cpp/absl/log/internal/append_truncated.h +28 -0
- data/third_party/abseil-cpp/absl/log/internal/check_op.cc +22 -22
- data/third_party/abseil-cpp/absl/log/internal/check_op.h +65 -62
- data/third_party/abseil-cpp/absl/log/internal/conditions.cc +5 -3
- data/third_party/abseil-cpp/absl/log/internal/conditions.h +7 -2
- data/third_party/abseil-cpp/absl/log/internal/log_message.cc +85 -43
- data/third_party/abseil-cpp/absl/log/internal/log_message.h +84 -59
- data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -0
- data/third_party/abseil-cpp/absl/log/internal/proto.cc +3 -2
- data/third_party/abseil-cpp/absl/log/internal/proto.h +3 -3
- data/third_party/abseil-cpp/absl/log/internal/strip.h +4 -12
- data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +8 -6
- data/third_party/abseil-cpp/absl/log/internal/voidify.h +10 -4
- data/third_party/abseil-cpp/absl/log/log.h +48 -35
- data/third_party/abseil-cpp/absl/log/log_sink_registry.h +2 -2
- data/third_party/abseil-cpp/absl/meta/type_traits.h +46 -175
- data/third_party/abseil-cpp/absl/numeric/bits.h +68 -2
- data/third_party/abseil-cpp/absl/numeric/int128.cc +0 -52
- data/third_party/abseil-cpp/absl/numeric/internal/bits.h +7 -3
- data/third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc +1 -1
- data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +10 -11
- data/third_party/abseil-cpp/absl/random/distributions.h +6 -8
- data/third_party/abseil-cpp/absl/random/gaussian_distribution.h +1 -1
- data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +5 -6
- data/third_party/abseil-cpp/absl/random/internal/{pool_urbg.cc → entropy_pool.cc} +22 -90
- data/third_party/abseil-cpp/absl/random/internal/entropy_pool.h +35 -0
- data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +5 -6
- data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +1 -1
- data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +20 -12
- data/third_party/abseil-cpp/absl/random/internal/seed_material.h +5 -5
- data/third_party/abseil-cpp/absl/random/random.h +88 -53
- data/third_party/abseil-cpp/absl/random/seed_sequences.cc +6 -2
- data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +3 -4
- data/third_party/abseil-cpp/absl/status/internal/status_internal.h +3 -4
- data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +4 -3
- data/third_party/abseil-cpp/absl/status/status.cc +4 -8
- data/third_party/abseil-cpp/absl/status/status.h +8 -8
- data/third_party/abseil-cpp/absl/status/status_payload_printer.h +2 -2
- data/third_party/abseil-cpp/absl/status/statusor.cc +2 -2
- data/third_party/abseil-cpp/absl/status/statusor.h +6 -6
- data/third_party/abseil-cpp/absl/strings/ascii.cc +9 -9
- data/third_party/abseil-cpp/absl/strings/ascii.h +18 -18
- data/third_party/abseil-cpp/absl/strings/charconv.cc +21 -22
- data/third_party/abseil-cpp/absl/strings/charconv.h +5 -5
- data/third_party/abseil-cpp/absl/strings/cord.cc +54 -58
- data/third_party/abseil-cpp/absl/strings/cord.h +94 -83
- data/third_party/abseil-cpp/absl/strings/cord_analysis.cc +11 -11
- data/third_party/abseil-cpp/absl/strings/cord_analysis.h +3 -3
- data/third_party/abseil-cpp/absl/strings/escaping.cc +130 -149
- data/third_party/abseil-cpp/absl/strings/escaping.h +9 -10
- data/third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc +1 -1
- data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +6 -8
- data/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +0 -4
- data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +0 -4
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc +7 -63
- data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +1 -11
- data/third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc +0 -22
- data/third_party/abseil-cpp/absl/strings/internal/str_format/output.cc +5 -3
- data/third_party/abseil-cpp/absl/strings/internal/str_format/parser.h +4 -2
- data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +3 -3
- data/third_party/abseil-cpp/absl/strings/internal/string_constant.h +0 -5
- data/third_party/abseil-cpp/absl/strings/internal/utf8.cc +96 -1
- data/third_party/abseil-cpp/absl/strings/internal/utf8.h +15 -1
- data/third_party/abseil-cpp/absl/strings/numbers.cc +53 -32
- data/third_party/abseil-cpp/absl/strings/numbers.h +87 -58
- data/third_party/abseil-cpp/absl/strings/str_cat.cc +6 -7
- data/third_party/abseil-cpp/absl/strings/str_cat.h +32 -32
- data/third_party/abseil-cpp/absl/strings/str_format.h +18 -18
- data/third_party/abseil-cpp/absl/strings/str_replace.cc +3 -3
- data/third_party/abseil-cpp/absl/strings/str_replace.h +6 -6
- data/third_party/abseil-cpp/absl/strings/string_view.cc +4 -9
- data/third_party/abseil-cpp/absl/strings/string_view.h +27 -32
- data/third_party/abseil-cpp/absl/strings/strip.h +4 -4
- data/third_party/abseil-cpp/absl/strings/substitute.cc +5 -4
- data/third_party/abseil-cpp/absl/strings/substitute.h +66 -64
- data/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc +0 -5
- data/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/internal/win32_waiter.cc +0 -4
- data/third_party/abseil-cpp/absl/synchronization/mutex.cc +1 -1
- data/third_party/abseil-cpp/absl/synchronization/mutex.h +97 -69
- data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
- data/third_party/abseil-cpp/absl/time/civil_time.cc +1 -0
- data/third_party/abseil-cpp/absl/time/duration.cc +12 -7
- data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h +1 -1
- data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +90 -111
- data/third_party/abseil-cpp/absl/time/time.h +20 -15
- data/third_party/abseil-cpp/absl/types/optional.h +7 -747
- data/third_party/abseil-cpp/absl/types/span.h +13 -11
- data/third_party/abseil-cpp/absl/types/variant.h +5 -784
- data/third_party/abseil-cpp/absl/utility/utility.h +10 -185
- metadata +72 -20
- data/src/core/lib/event_engine/forkable.cc +0 -105
- data/src/core/lib/event_engine/forkable.h +0 -67
- data/src/core/lib/iomgr/python_util.h +0 -46
- data/third_party/abseil-cpp/absl/base/internal/inline_variable.h +0 -108
- data/third_party/abseil-cpp/absl/base/internal/invoke.h +0 -241
- data/third_party/abseil-cpp/absl/log/log_entry.cc +0 -41
- data/third_party/abseil-cpp/absl/random/internal/pool_urbg.h +0 -131
- data/third_party/abseil-cpp/absl/types/bad_optional_access.cc +0 -66
- data/third_party/abseil-cpp/absl/types/bad_optional_access.h +0 -78
- data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +0 -82
- data/third_party/abseil-cpp/absl/types/bad_variant_access.h +0 -82
- data/third_party/abseil-cpp/absl/types/internal/optional.h +0 -352
- data/third_party/abseil-cpp/absl/types/internal/variant.h +0 -1622
@@ -0,0 +1,1083 @@
|
|
1
|
+
// Copyright 2025 The 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
|
+
#include <grpc/event_engine/event_engine.h>
|
16
|
+
#include <grpc/support/port_platform.h>
|
17
|
+
|
18
|
+
#include "src/core/lib/event_engine/posix_engine/posix_interface.h"
|
19
|
+
#include "src/core/lib/iomgr/port.h"
|
20
|
+
|
21
|
+
#if defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_LINUX_EVENTFD)
|
22
|
+
#include <fcntl.h>
|
23
|
+
|
24
|
+
#include "src/core/util/strerror.h"
|
25
|
+
#endif // defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_LINUX_EVENTFD)
|
26
|
+
|
27
|
+
#ifdef GRPC_POSIX_SOCKET
|
28
|
+
|
29
|
+
#include <sys/types.h>
|
30
|
+
|
31
|
+
#include <cerrno>
|
32
|
+
#include <cstdint>
|
33
|
+
#include <utility>
|
34
|
+
|
35
|
+
#include "absl/cleanup/cleanup.h"
|
36
|
+
#include "absl/log/log.h"
|
37
|
+
#include "absl/status/status.h"
|
38
|
+
#include "absl/strings/str_cat.h"
|
39
|
+
#include "absl/strings/str_replace.h"
|
40
|
+
#include "absl/strings/string_view.h"
|
41
|
+
#include "src/core/lib/event_engine/posix_engine/file_descriptor_collection.h"
|
42
|
+
#include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h"
|
43
|
+
#include "src/core/lib/event_engine/tcp_socket_utils.h"
|
44
|
+
#include "src/core/util/crash.h" // IWYU pragma: keep
|
45
|
+
#include "src/core/util/status_helper.h"
|
46
|
+
|
47
|
+
#ifdef GRPC_POSIX_SOCKET_UTILS_COMMON
|
48
|
+
#include <arpa/inet.h> // IWYU pragma: keep
|
49
|
+
#ifdef GRPC_LINUX_TCP_H
|
50
|
+
#include <linux/tcp.h>
|
51
|
+
#else
|
52
|
+
#include <netinet/in.h> // IWYU pragma: keep
|
53
|
+
#include <netinet/tcp.h>
|
54
|
+
#endif // GRPC_LINUX_TCP_H
|
55
|
+
#include <sys/ioctl.h>
|
56
|
+
#include <sys/socket.h>
|
57
|
+
#include <unistd.h>
|
58
|
+
#endif // GRPC_POSIX_SOCKET_UTILS_COMMON
|
59
|
+
|
60
|
+
#ifdef GRPC_LINUX_EVENTFD
|
61
|
+
#include <sys/eventfd.h>
|
62
|
+
#endif
|
63
|
+
|
64
|
+
// File needs to be compilable on all platforms. These macros will produce stubs
|
65
|
+
// if specific feature is not available in specific environment
|
66
|
+
#ifdef GRPC_LINUX_EPOLL
|
67
|
+
#include <sys/epoll.h>
|
68
|
+
#endif // GRPC_LINUX_EPOLL
|
69
|
+
|
70
|
+
#if GPR_LINUX == 1
|
71
|
+
// For Linux, it will be detected to support TCP_USER_TIMEOUT
|
72
|
+
#ifndef TCP_USER_TIMEOUT
|
73
|
+
#define TCP_USER_TIMEOUT 18
|
74
|
+
#endif
|
75
|
+
#define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT 0
|
76
|
+
#else
|
77
|
+
// For non-Linux, TCP_USER_TIMEOUT will be used if TCP_USER_TIMEOUT is defined.
|
78
|
+
#ifdef TCP_USER_TIMEOUT
|
79
|
+
#define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT 0
|
80
|
+
#else
|
81
|
+
#define TCP_USER_TIMEOUT 0
|
82
|
+
#define SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT -1
|
83
|
+
#endif // TCP_USER_TIMEOUT
|
84
|
+
#endif // GPR_LINUX == 1
|
85
|
+
|
86
|
+
#define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
|
87
|
+
|
88
|
+
#endif // GRPC_POSIX_SOCKET
|
89
|
+
|
90
|
+
namespace grpc_event_engine::experimental {
|
91
|
+
|
92
|
+
#if defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_POSIX_SOCKET)
|
93
|
+
namespace {
|
94
|
+
|
95
|
+
// Templated Fn to make it easier to compile on all platforms.
|
96
|
+
template <typename Fn, typename... Args>
|
97
|
+
PosixErrorOr<int64_t> Int64Wrap(bool correct_gen, int fd, const Fn& fn,
|
98
|
+
Args&&... args) {
|
99
|
+
if (!correct_gen) return PosixError::WrongGeneration();
|
100
|
+
auto result = std::invoke(fn, fd, std::forward<Args>(args)...);
|
101
|
+
if (result < 0) return PosixError::Error(errno);
|
102
|
+
return result;
|
103
|
+
}
|
104
|
+
|
105
|
+
// Set a socket to non blocking mode
|
106
|
+
absl::Status SetSocketNonBlocking(int fd, int non_blocking) {
|
107
|
+
int oldflags = fcntl(fd, F_GETFL, 0);
|
108
|
+
if (oldflags < 0) {
|
109
|
+
return absl::Status(absl::StatusCode::kInternal,
|
110
|
+
absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
|
111
|
+
}
|
112
|
+
|
113
|
+
if (non_blocking) {
|
114
|
+
oldflags |= O_NONBLOCK;
|
115
|
+
} else {
|
116
|
+
oldflags &= ~O_NONBLOCK;
|
117
|
+
}
|
118
|
+
|
119
|
+
if (fcntl(fd, F_SETFL, oldflags) != 0) {
|
120
|
+
return absl::Status(absl::StatusCode::kInternal,
|
121
|
+
absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
|
122
|
+
}
|
123
|
+
return absl::OkStatus();
|
124
|
+
}
|
125
|
+
|
126
|
+
} // namespace
|
127
|
+
#endif // defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_POSIX_SOCKET)
|
128
|
+
|
129
|
+
#ifdef GRPC_POSIX_SOCKET
|
130
|
+
|
131
|
+
namespace {
|
132
|
+
|
133
|
+
// This way if constexpr can be used and also macro nesting is not needed
|
134
|
+
#ifdef GRPC_LINUX_ERRQUEUE
|
135
|
+
constexpr bool kLinuxErrqueue = true;
|
136
|
+
#else // GRPC_LINUX_ERRQUEUE
|
137
|
+
constexpr bool kLinuxErrqueue = false;
|
138
|
+
#endif // GRPC_LINUX_ERRQUEUE
|
139
|
+
|
140
|
+
// The default values for TCP_USER_TIMEOUT are currently configured to be in
|
141
|
+
// line with the default values of KEEPALIVE_TIMEOUT as proposed in
|
142
|
+
// https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md
|
143
|
+
int kDefaultClientUserTimeoutMs = 20000;
|
144
|
+
int kDefaultServerUserTimeoutMs = 20000;
|
145
|
+
bool kDefaultClientUserTimeoutEnabled = false;
|
146
|
+
bool kDefaultServerUserTimeoutEnabled = true;
|
147
|
+
|
148
|
+
// Whether the socket supports TCP_USER_TIMEOUT option.
|
149
|
+
// (0: don't know, 1: support, -1: not support)
|
150
|
+
std::atomic<int> g_socket_supports_tcp_user_timeout(
|
151
|
+
SOCKET_SUPPORTS_TCP_USER_TIMEOUT_DEFAULT);
|
152
|
+
|
153
|
+
absl::Status ErrorForFd(
|
154
|
+
int fd, const experimental::EventEngine::ResolvedAddress& addr) {
|
155
|
+
if (fd >= 0) return absl::OkStatus();
|
156
|
+
const char* addr_str = reinterpret_cast<const char*>(addr.address());
|
157
|
+
return absl::Status(absl::StatusCode::kInternal,
|
158
|
+
absl::StrCat("socket: ", grpc_core::StrError(errno),
|
159
|
+
std::string(addr_str, addr.size())));
|
160
|
+
}
|
161
|
+
|
162
|
+
int CreateSocket(std::function<int(int, int, int)> socket_factory, int family,
|
163
|
+
int type, int protocol) {
|
164
|
+
int res = socket_factory != nullptr ? socket_factory(family, type, protocol)
|
165
|
+
: socket(family, type, protocol);
|
166
|
+
if (res < 0 && errno == EMFILE) {
|
167
|
+
int saved_errno = errno;
|
168
|
+
LOG_EVERY_N_SEC(ERROR, 10)
|
169
|
+
<< "socket(" << family << ", " << type << ", " << protocol
|
170
|
+
<< ") returned " << res << " with error: |"
|
171
|
+
<< grpc_core::StrError(errno)
|
172
|
+
<< "|. This process might not have a sufficient file descriptor limit "
|
173
|
+
"for the number of connections grpc wants to open (which is "
|
174
|
+
"generally a function of the number of grpc channels, the lb policy "
|
175
|
+
"of each channel, and the number of backends each channel is load "
|
176
|
+
"balancing across).";
|
177
|
+
errno = saved_errno;
|
178
|
+
}
|
179
|
+
return res;
|
180
|
+
}
|
181
|
+
|
182
|
+
// Tries to set the socket's receive buffer to given size.
|
183
|
+
absl::Status SetSocketRcvBuf(int fd, int buffer_size_bytes) {
|
184
|
+
return 0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffer_size_bytes,
|
185
|
+
sizeof(buffer_size_bytes))
|
186
|
+
? absl::OkStatus()
|
187
|
+
: absl::Status(absl::StatusCode::kInternal,
|
188
|
+
absl::StrCat("setsockopt(SO_RCVBUF): ",
|
189
|
+
grpc_core::StrError(errno)));
|
190
|
+
}
|
191
|
+
|
192
|
+
// get max listen queue size on linux
|
193
|
+
int InitMaxAcceptQueueSize() {
|
194
|
+
int n = SOMAXCONN;
|
195
|
+
char buf[64];
|
196
|
+
FILE* fp = fopen("/proc/sys/net/core/somaxconn", "r");
|
197
|
+
int max_accept_queue_size;
|
198
|
+
if (fp == nullptr) {
|
199
|
+
// 2.4 kernel.
|
200
|
+
return SOMAXCONN;
|
201
|
+
}
|
202
|
+
if (fgets(buf, sizeof buf, fp)) {
|
203
|
+
char* end;
|
204
|
+
long i = strtol(buf, &end, 10);
|
205
|
+
if (i > 0 && i <= INT_MAX && end && *end == '\n') {
|
206
|
+
n = static_cast<int>(i);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
fclose(fp);
|
210
|
+
max_accept_queue_size = n;
|
211
|
+
|
212
|
+
if (max_accept_queue_size < MIN_SAFE_ACCEPT_QUEUE_SIZE) {
|
213
|
+
LOG(INFO) << "Suspiciously small accept queue (" << max_accept_queue_size
|
214
|
+
<< ") will probably lead to connection drops";
|
215
|
+
}
|
216
|
+
return max_accept_queue_size;
|
217
|
+
}
|
218
|
+
|
219
|
+
int GetMaxAcceptQueueSize() {
|
220
|
+
static const int kMaxAcceptQueueSize = InitMaxAcceptQueueSize();
|
221
|
+
return kMaxAcceptQueueSize;
|
222
|
+
}
|
223
|
+
|
224
|
+
// Set a socket to close on exec
|
225
|
+
absl::Status SetSocketCloexec(int fd, int close_on_exec) {
|
226
|
+
int oldflags = fcntl(fd, F_GETFD, 0);
|
227
|
+
if (oldflags < 0) {
|
228
|
+
return absl::Status(absl::StatusCode::kInternal,
|
229
|
+
absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
|
230
|
+
}
|
231
|
+
|
232
|
+
if (close_on_exec) {
|
233
|
+
oldflags |= FD_CLOEXEC;
|
234
|
+
} else {
|
235
|
+
oldflags &= ~FD_CLOEXEC;
|
236
|
+
}
|
237
|
+
|
238
|
+
if (fcntl(fd, F_SETFD, oldflags) != 0) {
|
239
|
+
return absl::Status(absl::StatusCode::kInternal,
|
240
|
+
absl::StrCat("fcntl: ", grpc_core::StrError(errno)));
|
241
|
+
}
|
242
|
+
|
243
|
+
return absl::OkStatus();
|
244
|
+
}
|
245
|
+
|
246
|
+
// set a socket to reuse old addresses
|
247
|
+
absl::Status SetSocketOption(int fd, int level, int option, int value,
|
248
|
+
absl::string_view debug_label) {
|
249
|
+
int val = (value != 0);
|
250
|
+
int newval;
|
251
|
+
socklen_t intlen = sizeof(newval);
|
252
|
+
if (0 != setsockopt(fd, level, option, &val, sizeof(val))) {
|
253
|
+
return absl::Status(absl::StatusCode::kInternal,
|
254
|
+
absl::StrCat("setsockopt(", debug_label,
|
255
|
+
"): ", grpc_core::StrError(errno)));
|
256
|
+
}
|
257
|
+
if (0 != getsockopt(fd, level, option, &newval, &intlen)) {
|
258
|
+
return absl::Status(absl::StatusCode::kInternal,
|
259
|
+
absl::StrCat("setsockopt(", debug_label,
|
260
|
+
"): ", grpc_core::StrError(errno)));
|
261
|
+
}
|
262
|
+
if ((newval != 0) != val) {
|
263
|
+
return absl::Status(absl::StatusCode::kInternal,
|
264
|
+
absl::StrCat("Failed to set ", debug_label));
|
265
|
+
}
|
266
|
+
|
267
|
+
return absl::OkStatus();
|
268
|
+
}
|
269
|
+
|
270
|
+
// set a socket to reuse old ports
|
271
|
+
absl::Status SetSocketReusePort(int fd, GRPC_UNUSED int reuse) {
|
272
|
+
#ifndef SO_REUSEPORT
|
273
|
+
return absl::Status(absl::StatusCode::kInternal,
|
274
|
+
"SO_REUSEPORT unavailable on compiling system");
|
275
|
+
#else
|
276
|
+
return SetSocketOption(fd, SOL_SOCKET, SO_REUSEPORT, 1, "SO_REUSEPORT");
|
277
|
+
#endif
|
278
|
+
}
|
279
|
+
|
280
|
+
// Set Differentiated Services Code Point (DSCP)
|
281
|
+
absl::Status SetSocketDscp(int fdesc, int dscp) {
|
282
|
+
if (dscp == PosixTcpOptions::kDscpNotSet) {
|
283
|
+
return absl::OkStatus();
|
284
|
+
}
|
285
|
+
// The TOS/TrafficClass byte consists of following bits:
|
286
|
+
// | 7 6 5 4 3 2 | 1 0 |
|
287
|
+
// | DSCP | ECN |
|
288
|
+
int newval = dscp << 2;
|
289
|
+
int val;
|
290
|
+
socklen_t intlen = sizeof(val);
|
291
|
+
// Get ECN bits from current IP_TOS value unless IPv6 only
|
292
|
+
if (0 == getsockopt(fdesc, IPPROTO_IP, IP_TOS, &val, &intlen)) {
|
293
|
+
newval |= (val & 0x3);
|
294
|
+
if (0 != setsockopt(fdesc, IPPROTO_IP, IP_TOS, &newval, sizeof(newval))) {
|
295
|
+
return absl::Status(
|
296
|
+
absl::StatusCode::kInternal,
|
297
|
+
absl::StrCat("setsockopt(IP_TOS): ", grpc_core::StrError(errno)));
|
298
|
+
}
|
299
|
+
}
|
300
|
+
// Get ECN from current Traffic Class value if IPv6 is available
|
301
|
+
if (0 == getsockopt(fdesc, IPPROTO_IPV6, IPV6_TCLASS, &val, &intlen)) {
|
302
|
+
newval |= (val & 0x3);
|
303
|
+
if (0 !=
|
304
|
+
setsockopt(fdesc, IPPROTO_IPV6, IPV6_TCLASS, &newval, sizeof(newval))) {
|
305
|
+
return absl::Status(absl::StatusCode::kInternal,
|
306
|
+
absl::StrCat("setsockopt(IPV6_TCLASS): ",
|
307
|
+
grpc_core::StrError(errno)));
|
308
|
+
}
|
309
|
+
}
|
310
|
+
return absl::OkStatus();
|
311
|
+
}
|
312
|
+
|
313
|
+
// Set a socket to use zerocopy
|
314
|
+
absl::Status SetSocketZeroCopy(int fd) {
|
315
|
+
#ifdef GRPC_LINUX_ERRQUEUE
|
316
|
+
return SetSocketOption(fd, SOL_SOCKET, SO_ZEROCOPY, 1, "SO_ZEROCOPY");
|
317
|
+
#else // GRPC_LINUX_ERRQUEUE
|
318
|
+
return absl::Status(absl::StatusCode::kInternal,
|
319
|
+
absl::StrCat("setsockopt(SO_ZEROCOPY): ",
|
320
|
+
grpc_core::StrError(ENOSYS).c_str()));
|
321
|
+
#endif // GRPC_LINUX_ERRQUEUE
|
322
|
+
}
|
323
|
+
|
324
|
+
// Set TCP_USER_TIMEOUT
|
325
|
+
void TrySetSocketTcpUserTimeout(int fd, const PosixTcpOptions& options,
|
326
|
+
bool is_client) {
|
327
|
+
if (g_socket_supports_tcp_user_timeout.load() < 0) {
|
328
|
+
return;
|
329
|
+
}
|
330
|
+
bool enable = is_client ? kDefaultClientUserTimeoutEnabled
|
331
|
+
: kDefaultServerUserTimeoutEnabled;
|
332
|
+
int timeout =
|
333
|
+
is_client ? kDefaultClientUserTimeoutMs : kDefaultServerUserTimeoutMs;
|
334
|
+
if (options.keep_alive_time_ms > 0) {
|
335
|
+
enable = options.keep_alive_time_ms != INT_MAX;
|
336
|
+
}
|
337
|
+
if (options.keep_alive_timeout_ms > 0) {
|
338
|
+
timeout = options.keep_alive_timeout_ms;
|
339
|
+
}
|
340
|
+
if (enable) {
|
341
|
+
int newval;
|
342
|
+
socklen_t len = sizeof(newval);
|
343
|
+
// If this is the first time to use TCP_USER_TIMEOUT, try to check
|
344
|
+
// if it is available.
|
345
|
+
if (g_socket_supports_tcp_user_timeout.load() == 0) {
|
346
|
+
if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
|
347
|
+
// This log is intentionally not protected behind a flag, so that
|
348
|
+
// users know that TCP_USER_TIMEOUT is not being used.
|
349
|
+
GRPC_TRACE_LOG(tcp, INFO)
|
350
|
+
<< "TCP_USER_TIMEOUT is not available. TCP_USER_TIMEOUT "
|
351
|
+
"won't be used thereafter";
|
352
|
+
g_socket_supports_tcp_user_timeout.store(-1);
|
353
|
+
} else {
|
354
|
+
GRPC_TRACE_LOG(tcp, INFO)
|
355
|
+
<< "TCP_USER_TIMEOUT is available. TCP_USER_TIMEOUT will be "
|
356
|
+
"used thereafter";
|
357
|
+
g_socket_supports_tcp_user_timeout.store(1);
|
358
|
+
}
|
359
|
+
}
|
360
|
+
if (g_socket_supports_tcp_user_timeout.load() > 0) {
|
361
|
+
if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout,
|
362
|
+
sizeof(timeout))) {
|
363
|
+
LOG(ERROR) << "setsockopt(TCP_USER_TIMEOUT) "
|
364
|
+
<< grpc_core::StrError(errno);
|
365
|
+
return;
|
366
|
+
}
|
367
|
+
if (0 != getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &newval, &len)) {
|
368
|
+
LOG(ERROR) << "getsockopt(TCP_USER_TIMEOUT) "
|
369
|
+
<< grpc_core::StrError(errno);
|
370
|
+
return;
|
371
|
+
}
|
372
|
+
if (newval != timeout) {
|
373
|
+
// Do not fail on failing to set TCP_USER_TIMEOUT
|
374
|
+
LOG(ERROR) << "Failed to set TCP_USER_TIMEOUT";
|
375
|
+
return;
|
376
|
+
}
|
377
|
+
}
|
378
|
+
}
|
379
|
+
}
|
380
|
+
|
381
|
+
absl::StatusOr<int> InternalCreateDualStackSocket(
|
382
|
+
std::function<int(int, int, int)> socket_factory,
|
383
|
+
const experimental::EventEngine::ResolvedAddress& addr, int type,
|
384
|
+
int protocol, EventEnginePosixInterface::DSMode& dsmode) {
|
385
|
+
const sockaddr* sock_addr = addr.address();
|
386
|
+
int family = sock_addr->sa_family;
|
387
|
+
int newfd;
|
388
|
+
if (family == AF_INET6) {
|
389
|
+
if (IsIpv6LoopbackAvailable()) {
|
390
|
+
newfd = CreateSocket(socket_factory, family, type, protocol);
|
391
|
+
} else {
|
392
|
+
newfd = -1;
|
393
|
+
errno = EAFNOSUPPORT;
|
394
|
+
}
|
395
|
+
// Check if we've got a valid dualstack socket.
|
396
|
+
if (newfd > 0 && SetSocketDualStack(newfd)) {
|
397
|
+
dsmode = EventEnginePosixInterface::DSMode::DSMODE_DUALSTACK;
|
398
|
+
return newfd;
|
399
|
+
}
|
400
|
+
// If this isn't an IPv4 address, then return whatever we've
|
401
|
+
// got.
|
402
|
+
if (!ResolvedAddressIsV4Mapped(addr, nullptr)) {
|
403
|
+
if (newfd < 0) {
|
404
|
+
return ErrorForFd(newfd, addr);
|
405
|
+
}
|
406
|
+
dsmode = EventEnginePosixInterface::DSMode::DSMODE_IPV6;
|
407
|
+
return newfd;
|
408
|
+
}
|
409
|
+
// Fall back to AF_INET.
|
410
|
+
if (newfd >= 0) {
|
411
|
+
close(newfd);
|
412
|
+
}
|
413
|
+
family = AF_INET;
|
414
|
+
}
|
415
|
+
dsmode = family == AF_INET ? EventEnginePosixInterface::DSMode::DSMODE_IPV4
|
416
|
+
: EventEnginePosixInterface::DSMode::DSMODE_NONE;
|
417
|
+
newfd = CreateSocket(socket_factory, family, type, protocol);
|
418
|
+
if (newfd < 0) {
|
419
|
+
return ErrorForFd(newfd, addr);
|
420
|
+
}
|
421
|
+
return newfd;
|
422
|
+
}
|
423
|
+
|
424
|
+
absl::Status InternalSetSocketNoSigpipeIfPossible(GRPC_UNUSED int fd) {
|
425
|
+
#ifdef GRPC_HAVE_SO_NOSIGPIPE
|
426
|
+
return SetSocketOption(fd, SOL_SOCKET, SO_NOSIGPIPE, 1, "SO_NOSIGPIPE");
|
427
|
+
#else // GRPC_HAVE_SO_NOSIGPIPE
|
428
|
+
return absl::OkStatus();
|
429
|
+
#endif // GRPC_HAVE_SO_NOSIGPIPE
|
430
|
+
}
|
431
|
+
|
432
|
+
absl::Status InternalApplySocketMutatorInOptions(
|
433
|
+
int fd, grpc_fd_usage usage, const PosixTcpOptions& options) {
|
434
|
+
if (options.socket_mutator == nullptr) {
|
435
|
+
return absl::OkStatus();
|
436
|
+
}
|
437
|
+
if (!grpc_socket_mutator_mutate_fd(options.socket_mutator, fd, usage)) {
|
438
|
+
return absl::Status(absl::StatusCode::kInternal,
|
439
|
+
"grpc_socket_mutator failed.");
|
440
|
+
}
|
441
|
+
return absl::OkStatus();
|
442
|
+
}
|
443
|
+
|
444
|
+
} // namespace
|
445
|
+
|
446
|
+
bool IsSocketReusePortSupported() {
|
447
|
+
static bool kSupportSoReusePort = []() -> bool {
|
448
|
+
EventEnginePosixInterface posix_interface;
|
449
|
+
auto s = posix_interface.Socket(AF_INET, SOCK_STREAM, 0);
|
450
|
+
if (!s.ok()) {
|
451
|
+
// This might be an ipv6-only environment in which case
|
452
|
+
// 'socket(AF_INET,..)' call would fail. Try creating IPv6 socket in
|
453
|
+
// that case
|
454
|
+
s = posix_interface.Socket(AF_INET6, SOCK_STREAM, 0);
|
455
|
+
}
|
456
|
+
if (s.ok()) {
|
457
|
+
bool result =
|
458
|
+
SetSocketReusePort(posix_interface.GetFd(s.value()).value(), 1).ok();
|
459
|
+
posix_interface.Close(s.value());
|
460
|
+
return result;
|
461
|
+
} else {
|
462
|
+
return false;
|
463
|
+
}
|
464
|
+
}();
|
465
|
+
return kSupportSoReusePort;
|
466
|
+
}
|
467
|
+
|
468
|
+
#ifdef GRPC_ENABLE_FORK_SUPPORT
|
469
|
+
|
470
|
+
void EventEnginePosixInterface::AdvanceGeneration() {
|
471
|
+
if (!IsEventEngineForkEnabled()) {
|
472
|
+
grpc_core::Crash(
|
473
|
+
"Fork support is disabled but AdvanceGeneration was called");
|
474
|
+
}
|
475
|
+
for (int fd : descriptors_.ClearAndReturnRawDescriptors()) {
|
476
|
+
if (fd > 0) {
|
477
|
+
close(fd);
|
478
|
+
}
|
479
|
+
}
|
480
|
+
descriptors_ = FileDescriptorCollection(descriptors_.generation() + 1);
|
481
|
+
}
|
482
|
+
|
483
|
+
#endif // GRPC_ENABLE_FORK_SUPPORT
|
484
|
+
|
485
|
+
FileDescriptor EventEnginePosixInterface::Adopt(int fd) {
|
486
|
+
return descriptors_.Add(fd);
|
487
|
+
}
|
488
|
+
|
489
|
+
PosixErrorOr<int> EventEnginePosixInterface::GetFd(const FileDescriptor& fd) {
|
490
|
+
if (!IsCorrectGeneration(fd)) {
|
491
|
+
return PosixError::WrongGeneration();
|
492
|
+
}
|
493
|
+
return fd.fd();
|
494
|
+
}
|
495
|
+
|
496
|
+
//
|
497
|
+
// ---- Socket/FD Creation Factories ----
|
498
|
+
//
|
499
|
+
|
500
|
+
absl::StatusOr<EventEnginePosixInterface::PosixSocketCreateResult>
|
501
|
+
EventEnginePosixInterface::CreateAndPrepareTcpClientSocket(
|
502
|
+
const PosixTcpOptions& options,
|
503
|
+
const EventEngine::ResolvedAddress& target_addr) {
|
504
|
+
EventEnginePosixInterface::DSMode dsmode;
|
505
|
+
EventEngine::ResolvedAddress mapped_target_addr;
|
506
|
+
|
507
|
+
// Use dualstack sockets where available. Set mapped to v6 or v4 mapped to
|
508
|
+
// v6.
|
509
|
+
if (!ResolvedAddressToV4Mapped(target_addr, &mapped_target_addr)) {
|
510
|
+
// addr is v4 mapped to v6 or just v6.
|
511
|
+
mapped_target_addr = target_addr;
|
512
|
+
}
|
513
|
+
absl::StatusOr<FileDescriptor> socket_fd = CreateDualStackSocket(
|
514
|
+
nullptr, mapped_target_addr, SOCK_STREAM, 0, dsmode);
|
515
|
+
if (!socket_fd.ok()) {
|
516
|
+
return socket_fd.status();
|
517
|
+
}
|
518
|
+
|
519
|
+
if (dsmode == DSMode::DSMODE_IPV4) {
|
520
|
+
// Original addr is either v4 or v4 mapped to v6. Set mapped_addr to v4.
|
521
|
+
if (!ResolvedAddressIsV4Mapped(target_addr, &mapped_target_addr)) {
|
522
|
+
mapped_target_addr = target_addr;
|
523
|
+
}
|
524
|
+
}
|
525
|
+
auto error =
|
526
|
+
PrepareTcpClientSocket(socket_fd->fd(), mapped_target_addr, options);
|
527
|
+
if (!error.ok()) {
|
528
|
+
return error;
|
529
|
+
}
|
530
|
+
return PosixSocketCreateResult{*socket_fd, mapped_target_addr};
|
531
|
+
}
|
532
|
+
|
533
|
+
absl::StatusOr<FileDescriptor> EventEnginePosixInterface::CreateDualStackSocket(
|
534
|
+
std::function<int(int, int, int)> socket_factory,
|
535
|
+
const experimental::EventEngine::ResolvedAddress& addr, int type,
|
536
|
+
int protocol, DSMode& dsmode) {
|
537
|
+
auto fd = InternalCreateDualStackSocket(std::move(socket_factory), addr, type,
|
538
|
+
protocol, dsmode);
|
539
|
+
if (!fd.ok()) {
|
540
|
+
return std::move(fd).status();
|
541
|
+
}
|
542
|
+
return descriptors_.Add(*fd);
|
543
|
+
}
|
544
|
+
|
545
|
+
#ifdef GRPC_LINUX_EPOLL
|
546
|
+
#ifdef GRPC_LINUX_EPOLL_CREATE1
|
547
|
+
|
548
|
+
PosixErrorOr<FileDescriptor>
|
549
|
+
EventEnginePosixInterface::EpollCreateAndCloexec() {
|
550
|
+
auto fd = RegisterPosixResult(epoll_create1(EPOLL_CLOEXEC));
|
551
|
+
if (!fd.ok()) {
|
552
|
+
LOG(ERROR) << "epoll_create1 unavailable";
|
553
|
+
}
|
554
|
+
return fd;
|
555
|
+
}
|
556
|
+
|
557
|
+
#else // GRPC_LINUX_EPOLL_CREATE1
|
558
|
+
|
559
|
+
PosixErrorOr<FileDescriptor>
|
560
|
+
EventEnginePosixInterface::EpollCreateAndCloexec() {
|
561
|
+
auto fd = RegisterPosixResult(epoll_create(MAX_EPOLL_EVENTS));
|
562
|
+
if (!fd.ok()) {
|
563
|
+
LOG(ERROR) << "epoll_create unavailable";
|
564
|
+
return fd;
|
565
|
+
} else if (fcntl(fd->value(), F_SETFD, FD_CLOEXEC) != 0) {
|
566
|
+
LOG(ERROR) << "fcntl following epoll_create failed";
|
567
|
+
return PosixError::Error(errno);
|
568
|
+
}
|
569
|
+
return fd;
|
570
|
+
}
|
571
|
+
|
572
|
+
#endif // GRPC_LINUX_EPOLL_CREATE1
|
573
|
+
#else // GRPC_LINUX_EPOLL
|
574
|
+
|
575
|
+
PosixErrorOr<FileDescriptor>
|
576
|
+
EventEnginePosixInterface::EpollCreateAndCloexec() {
|
577
|
+
grpc_core::Crash("Not supported");
|
578
|
+
}
|
579
|
+
|
580
|
+
#endif // GRPC_LINUX_EPOLL
|
581
|
+
|
582
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Socket(int domain,
|
583
|
+
int type,
|
584
|
+
int protocol) {
|
585
|
+
return RegisterPosixResult(socket(domain, type, protocol));
|
586
|
+
}
|
587
|
+
|
588
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Accept(
|
589
|
+
const FileDescriptor& sockfd, struct sockaddr* addr, socklen_t* addrlen) {
|
590
|
+
if (!IsCorrectGeneration(sockfd)) {
|
591
|
+
return PosixError::WrongGeneration();
|
592
|
+
}
|
593
|
+
return RegisterPosixResult(accept(sockfd.fd(), addr, addrlen));
|
594
|
+
}
|
595
|
+
|
596
|
+
#ifdef GRPC_POSIX_SOCKETUTILS
|
597
|
+
|
598
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Accept4(
|
599
|
+
const FileDescriptor& sockfd,
|
600
|
+
grpc_event_engine::experimental::EventEngine::ResolvedAddress& addr,
|
601
|
+
int nonblock, int cloexec) {
|
602
|
+
int flags;
|
603
|
+
EventEngine::ResolvedAddress peer_addr;
|
604
|
+
socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
|
605
|
+
auto fd = Accept(sockfd, const_cast<sockaddr*>(peer_addr.address()), &len);
|
606
|
+
if (!fd.ok()) {
|
607
|
+
return fd;
|
608
|
+
}
|
609
|
+
int raw_fd = fd->fd();
|
610
|
+
if (nonblock) {
|
611
|
+
flags = fcntl(raw_fd, F_GETFL, 0);
|
612
|
+
if (flags < 0) goto close_and_error;
|
613
|
+
if (fcntl(raw_fd, F_SETFL, flags | O_NONBLOCK) != 0) goto close_and_error;
|
614
|
+
}
|
615
|
+
if (cloexec) {
|
616
|
+
flags = fcntl(raw_fd, F_GETFD, 0);
|
617
|
+
if (flags < 0) goto close_and_error;
|
618
|
+
if (fcntl(raw_fd, F_SETFD, flags | FD_CLOEXEC) != 0) goto close_and_error;
|
619
|
+
}
|
620
|
+
addr = EventEngine::ResolvedAddress(peer_addr.address(), len);
|
621
|
+
return fd;
|
622
|
+
|
623
|
+
close_and_error:
|
624
|
+
Close(*fd);
|
625
|
+
return PosixError::Error(errno);
|
626
|
+
}
|
627
|
+
|
628
|
+
#else // GRPC_POSIX_SOCKETUTILS
|
629
|
+
|
630
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::Accept4(
|
631
|
+
const FileDescriptor& sockfd,
|
632
|
+
grpc_event_engine::experimental::EventEngine::ResolvedAddress& addr,
|
633
|
+
int nonblock, int cloexec) {
|
634
|
+
if (!IsCorrectGeneration(sockfd)) {
|
635
|
+
return PosixError::WrongGeneration();
|
636
|
+
}
|
637
|
+
int flags = 0;
|
638
|
+
flags |= nonblock ? SOCK_NONBLOCK : 0;
|
639
|
+
flags |= cloexec ? SOCK_CLOEXEC : 0;
|
640
|
+
EventEngine::ResolvedAddress peer_addr;
|
641
|
+
socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
|
642
|
+
PosixErrorOr<FileDescriptor> ret = RegisterPosixResult(accept4(
|
643
|
+
sockfd.fd(), const_cast<sockaddr*>(peer_addr.address()), &len, flags));
|
644
|
+
if (ret.ok()) {
|
645
|
+
addr = EventEngine::ResolvedAddress(peer_addr.address(), len);
|
646
|
+
}
|
647
|
+
return ret;
|
648
|
+
}
|
649
|
+
|
650
|
+
#endif // GRPC_POSIX_SOCKETUTILS
|
651
|
+
|
652
|
+
PosixError EventEnginePosixInterface::Connect(const FileDescriptor& sockfd,
|
653
|
+
const struct sockaddr* addr,
|
654
|
+
socklen_t addrlen) {
|
655
|
+
return PosixResultWrap(
|
656
|
+
sockfd, [&](int sockfd) { return connect(sockfd, addr, addrlen); });
|
657
|
+
}
|
658
|
+
|
659
|
+
PosixErrorOr<int64_t> EventEnginePosixInterface::RecvMsg(
|
660
|
+
const FileDescriptor& fd, struct msghdr* message, int flags) {
|
661
|
+
return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), recvmsg, message, flags);
|
662
|
+
}
|
663
|
+
|
664
|
+
PosixErrorOr<int64_t> EventEnginePosixInterface::SendMsg(
|
665
|
+
const FileDescriptor& fd, const struct msghdr* message, int flags) {
|
666
|
+
return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), sendmsg, message, flags);
|
667
|
+
}
|
668
|
+
|
669
|
+
PosixError EventEnginePosixInterface::Shutdown(const FileDescriptor& fd,
|
670
|
+
int how) {
|
671
|
+
return PosixResultWrap(fd, [&](int fd) { return shutdown(fd, how); });
|
672
|
+
}
|
673
|
+
|
674
|
+
absl::Status EventEnginePosixInterface::ApplySocketMutatorInOptions(
|
675
|
+
const FileDescriptor& fd, grpc_fd_usage usage,
|
676
|
+
const PosixTcpOptions& options) {
|
677
|
+
if (!IsCorrectGeneration(fd)) {
|
678
|
+
return absl::InternalError("ApplySocketMutatorInOptions: wrong generation");
|
679
|
+
}
|
680
|
+
return InternalApplySocketMutatorInOptions(fd.fd(), usage, options);
|
681
|
+
}
|
682
|
+
|
683
|
+
void EventEnginePosixInterface::ConfigureDefaultTcpUserTimeout(bool enable,
|
684
|
+
int timeout,
|
685
|
+
bool is_client) {
|
686
|
+
if (is_client) {
|
687
|
+
kDefaultClientUserTimeoutEnabled = enable;
|
688
|
+
if (timeout > 0) {
|
689
|
+
kDefaultClientUserTimeoutMs = timeout;
|
690
|
+
}
|
691
|
+
} else {
|
692
|
+
kDefaultServerUserTimeoutEnabled = enable;
|
693
|
+
if (timeout > 0) {
|
694
|
+
kDefaultServerUserTimeoutMs = timeout;
|
695
|
+
}
|
696
|
+
}
|
697
|
+
}
|
698
|
+
|
699
|
+
int EventEnginePosixInterface::ConfigureSocket(const FileDescriptor& fd,
|
700
|
+
int type) {
|
701
|
+
if (!IsCorrectGeneration(fd)) {
|
702
|
+
return -1;
|
703
|
+
}
|
704
|
+
#define RETURN_IF_ERROR(expr) \
|
705
|
+
if (!(expr).ok()) { \
|
706
|
+
return -1; \
|
707
|
+
}
|
708
|
+
RETURN_IF_ERROR(SetSocketNonBlocking(fd.fd(), 1));
|
709
|
+
RETURN_IF_ERROR(SetSocketCloexec(fd.fd(), 1));
|
710
|
+
if (type == SOCK_STREAM) {
|
711
|
+
RETURN_IF_ERROR(
|
712
|
+
SetSocketOption(fd.fd(), IPPROTO_TCP, TCP_NODELAY, 1, "TCP_NODELAY"));
|
713
|
+
}
|
714
|
+
return 0;
|
715
|
+
}
|
716
|
+
|
717
|
+
PosixError EventEnginePosixInterface::GetSockOpt(const FileDescriptor& fd,
|
718
|
+
int level, int optname,
|
719
|
+
void* optval, void* optlen) {
|
720
|
+
return PosixResultWrap(fd, [&](int fd) {
|
721
|
+
return getsockopt(fd, level, optname, optval,
|
722
|
+
static_cast<socklen_t*>(optlen));
|
723
|
+
});
|
724
|
+
}
|
725
|
+
|
726
|
+
// Bind to "::" to get a port number not used by any address.
|
727
|
+
absl::StatusOr<int> EventEnginePosixInterface::GetUnusedPort() {
|
728
|
+
EventEngine::ResolvedAddress wild = ResolvedAddressMakeWild6(0);
|
729
|
+
DSMode dsmode;
|
730
|
+
auto fd =
|
731
|
+
InternalCreateDualStackSocket(nullptr, wild, SOCK_STREAM, 0, dsmode);
|
732
|
+
GRPC_RETURN_IF_ERROR(fd.status());
|
733
|
+
if (dsmode == DSMode::DSMODE_IPV4) {
|
734
|
+
wild = ResolvedAddressMakeWild4(0);
|
735
|
+
}
|
736
|
+
if (bind(*fd, wild.address(), wild.size()) != 0) {
|
737
|
+
close(*fd);
|
738
|
+
return absl::FailedPreconditionError(
|
739
|
+
absl::StrCat("bind(GetUnusedPort): ", std::strerror(errno)));
|
740
|
+
}
|
741
|
+
socklen_t len = wild.size();
|
742
|
+
if (getsockname(*fd, const_cast<sockaddr*>(wild.address()), &len) != 0) {
|
743
|
+
close(*fd);
|
744
|
+
return absl::FailedPreconditionError(
|
745
|
+
absl::StrCat("getsockname(GetUnusedPort): ", std::strerror(errno)));
|
746
|
+
}
|
747
|
+
close(*fd);
|
748
|
+
int port = ResolvedAddressGetPort(wild);
|
749
|
+
if (port <= 0) {
|
750
|
+
return absl::FailedPreconditionError("Bad port");
|
751
|
+
}
|
752
|
+
return port;
|
753
|
+
}
|
754
|
+
|
755
|
+
PosixError EventEnginePosixInterface::Ioctl(const FileDescriptor& fd, int op,
|
756
|
+
void* arg) {
|
757
|
+
return PosixResultWrap(fd, [&](int fd) { return ioctl(fd, op, arg); });
|
758
|
+
}
|
759
|
+
|
760
|
+
absl::StatusOr<EventEngine::ResolvedAddress>
|
761
|
+
EventEnginePosixInterface::LocalAddress(const FileDescriptor& fd) {
|
762
|
+
if (!IsCorrectGeneration(fd)) {
|
763
|
+
return absl::InternalError(
|
764
|
+
"getsockname: file descriptor from wrong generation");
|
765
|
+
}
|
766
|
+
EventEngine::ResolvedAddress addr;
|
767
|
+
socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
|
768
|
+
if (getsockname(fd.fd(), const_cast<sockaddr*>(addr.address()), &len) < 0) {
|
769
|
+
return absl::InternalError(
|
770
|
+
absl::StrCat("getsockname:", grpc_core::StrError(errno)));
|
771
|
+
}
|
772
|
+
return EventEngine::ResolvedAddress(addr.address(), len);
|
773
|
+
}
|
774
|
+
|
775
|
+
absl::StatusOr<std::string> EventEnginePosixInterface::LocalAddressString(
|
776
|
+
const FileDescriptor& fd) {
|
777
|
+
auto status = LocalAddress(fd);
|
778
|
+
if (!status.ok()) {
|
779
|
+
return status.status();
|
780
|
+
}
|
781
|
+
return ResolvedAddressToNormalizedString((*status));
|
782
|
+
}
|
783
|
+
|
784
|
+
absl::StatusOr<EventEngine::ResolvedAddress>
|
785
|
+
EventEnginePosixInterface::PeerAddress(const FileDescriptor& fd) {
|
786
|
+
if (!IsCorrectGeneration(fd)) {
|
787
|
+
return absl::InternalError("getpeername: wrong file descriptor generation");
|
788
|
+
}
|
789
|
+
EventEngine::ResolvedAddress addr;
|
790
|
+
socklen_t len = EventEngine::ResolvedAddress::MAX_SIZE_BYTES;
|
791
|
+
if (getpeername(fd.fd(), const_cast<sockaddr*>(addr.address()), &len) < 0) {
|
792
|
+
return absl::InternalError(
|
793
|
+
absl::StrCat("getpeername:", grpc_core::StrError(errno)));
|
794
|
+
}
|
795
|
+
return EventEngine::ResolvedAddress(addr.address(), len);
|
796
|
+
}
|
797
|
+
|
798
|
+
absl::StatusOr<std::string> EventEnginePosixInterface::PeerAddressString(
|
799
|
+
const FileDescriptor& fd) {
|
800
|
+
auto status = PeerAddress(fd);
|
801
|
+
if (!status.ok()) {
|
802
|
+
return status.status();
|
803
|
+
}
|
804
|
+
return ResolvedAddressToNormalizedString((*status));
|
805
|
+
}
|
806
|
+
|
807
|
+
absl::StatusOr<EventEngine::ResolvedAddress>
|
808
|
+
EventEnginePosixInterface::PrepareListenerSocket(
|
809
|
+
const FileDescriptor& fd, const PosixTcpOptions& options,
|
810
|
+
const EventEngine::ResolvedAddress& address) {
|
811
|
+
if (!IsCorrectGeneration(fd)) {
|
812
|
+
return absl::InternalError("PrepareListenerSocket: wrong generation");
|
813
|
+
}
|
814
|
+
int f = fd.fd();
|
815
|
+
if (IsSocketReusePortSupported() && options.allow_reuse_port &&
|
816
|
+
address.address()->sa_family != AF_UNIX &&
|
817
|
+
!ResolvedAddressIsVSock(address)) {
|
818
|
+
GRPC_RETURN_IF_ERROR(SetSocketReusePort(f, 1));
|
819
|
+
}
|
820
|
+
|
821
|
+
GRPC_RETURN_IF_ERROR(SetSocketNonBlocking(f, 1));
|
822
|
+
GRPC_RETURN_IF_ERROR(SetSocketCloexec(f, 1));
|
823
|
+
|
824
|
+
if (address.address()->sa_family != AF_UNIX &&
|
825
|
+
!ResolvedAddressIsVSock(address)) {
|
826
|
+
GRPC_RETURN_IF_ERROR(
|
827
|
+
SetSocketOption(f, IPPROTO_TCP, TCP_NODELAY, 1, "TCP_NODELAY"));
|
828
|
+
GRPC_RETURN_IF_ERROR(
|
829
|
+
SetSocketOption(f, SOL_SOCKET, SO_REUSEADDR, 1, "SO_REUSEADDR"));
|
830
|
+
GRPC_RETURN_IF_ERROR(SetSocketDscp(f, options.dscp));
|
831
|
+
TrySetSocketTcpUserTimeout(f, options, false);
|
832
|
+
}
|
833
|
+
GRPC_RETURN_IF_ERROR(InternalSetSocketNoSigpipeIfPossible(f));
|
834
|
+
GRPC_RETURN_IF_ERROR(InternalApplySocketMutatorInOptions(
|
835
|
+
f, GRPC_FD_SERVER_LISTENER_USAGE, options));
|
836
|
+
if (kLinuxErrqueue && !SetSocketZeroCopy(f).ok()) {
|
837
|
+
// it's not fatal, so just log it.
|
838
|
+
VLOG(2) << "Node does not support SO_ZEROCOPY, continuing.";
|
839
|
+
}
|
840
|
+
if (bind(f, address.address(), address.size()) < 0) {
|
841
|
+
auto sockaddr_str = ResolvedAddressToString(address);
|
842
|
+
if (!sockaddr_str.ok()) {
|
843
|
+
LOG(ERROR) << "Could not convert sockaddr to string: "
|
844
|
+
<< sockaddr_str.status();
|
845
|
+
sockaddr_str = "<unparsable>";
|
846
|
+
}
|
847
|
+
sockaddr_str = absl::StrReplaceAll(*sockaddr_str, {{"\0", "@"}});
|
848
|
+
return absl::FailedPreconditionError(
|
849
|
+
absl::StrCat("Error in bind for address '", *sockaddr_str,
|
850
|
+
"': ", std::strerror(errno)));
|
851
|
+
}
|
852
|
+
if (listen(f, GetMaxAcceptQueueSize()) < 0) {
|
853
|
+
return absl::FailedPreconditionError(
|
854
|
+
absl::StrCat("Error in listen: ", std::strerror(errno)));
|
855
|
+
}
|
856
|
+
socklen_t len = static_cast<socklen_t>(sizeof(struct sockaddr_storage));
|
857
|
+
EventEngine::ResolvedAddress sockname_temp;
|
858
|
+
if (getsockname(f, const_cast<sockaddr*>(sockname_temp.address()), &len) <
|
859
|
+
0) {
|
860
|
+
return absl::FailedPreconditionError(
|
861
|
+
absl::StrCat("Error in getsockname: ", std::strerror(errno)));
|
862
|
+
}
|
863
|
+
return sockname_temp;
|
864
|
+
}
|
865
|
+
|
866
|
+
// Set a socket using a grpc_socket_mutator
|
867
|
+
absl::Status EventEnginePosixInterface::SetSocketMutator(
|
868
|
+
const FileDescriptor& fd, grpc_fd_usage usage,
|
869
|
+
grpc_socket_mutator* mutator) {
|
870
|
+
CHECK(mutator);
|
871
|
+
if (!IsCorrectGeneration(fd)) {
|
872
|
+
return absl::InternalError("SetSocketMutator: FD has a wrong generation");
|
873
|
+
}
|
874
|
+
if (!grpc_socket_mutator_mutate_fd(mutator, fd.fd(), usage)) {
|
875
|
+
return absl::Status(absl::StatusCode::kInternal,
|
876
|
+
"grpc_socket_mutator failed.");
|
877
|
+
}
|
878
|
+
return absl::OkStatus();
|
879
|
+
}
|
880
|
+
|
881
|
+
absl::Status EventEnginePosixInterface::SetSocketNoSigpipeIfPossible(
|
882
|
+
const FileDescriptor& fd) {
|
883
|
+
if (!IsCorrectGeneration(fd)) {
|
884
|
+
return absl::OkStatus();
|
885
|
+
}
|
886
|
+
return InternalSetSocketNoSigpipeIfPossible(fd.fd());
|
887
|
+
}
|
888
|
+
|
889
|
+
PosixErrorOr<int64_t> EventEnginePosixInterface::SetSockOpt(
|
890
|
+
const FileDescriptor& fd, int level, int optname, uint32_t optval) {
|
891
|
+
if (!IsCorrectGeneration(fd)) {
|
892
|
+
return PosixError::WrongGeneration();
|
893
|
+
}
|
894
|
+
if (setsockopt(fd.fd(), level, optname, &optval, sizeof(optval)) < 0) {
|
895
|
+
return PosixError::Error(errno);
|
896
|
+
}
|
897
|
+
return optval;
|
898
|
+
}
|
899
|
+
|
900
|
+
#ifdef GRPC_LINUX_EVENTFD
|
901
|
+
|
902
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::EventFd(int initval,
|
903
|
+
int flags) {
|
904
|
+
return RegisterPosixResult(eventfd(initval, flags));
|
905
|
+
}
|
906
|
+
|
907
|
+
PosixError EventEnginePosixInterface::EventFdRead(const FileDescriptor& fd) {
|
908
|
+
return PosixResultWrap(fd, [](int fd) {
|
909
|
+
eventfd_t value;
|
910
|
+
return eventfd_read(fd, &value);
|
911
|
+
});
|
912
|
+
}
|
913
|
+
|
914
|
+
PosixError EventEnginePosixInterface::EventFdWrite(const FileDescriptor& fd) {
|
915
|
+
return PosixResultWrap(fd, [](int fd) { return eventfd_write(fd, 1); });
|
916
|
+
}
|
917
|
+
|
918
|
+
#else // GRPC_LINUX_EVENTFD
|
919
|
+
|
920
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::EventFd(int initval,
|
921
|
+
int flags) {
|
922
|
+
grpc_core::Crash("EventFD not supported");
|
923
|
+
}
|
924
|
+
|
925
|
+
PosixError EventEnginePosixInterface::EventFdRead(const FileDescriptor& fd) {
|
926
|
+
grpc_core::Crash("Not implemented");
|
927
|
+
}
|
928
|
+
|
929
|
+
PosixError EventEnginePosixInterface::EventFdWrite(const FileDescriptor& fd) {
|
930
|
+
grpc_core::Crash("Not implemented");
|
931
|
+
}
|
932
|
+
|
933
|
+
#endif // GRPC_LINUX_EVENTFD
|
934
|
+
|
935
|
+
//
|
936
|
+
// Epoll
|
937
|
+
//
|
938
|
+
#ifdef GRPC_LINUX_EPOLL
|
939
|
+
|
940
|
+
PosixError EventEnginePosixInterface::EpollCtlDel(const FileDescriptor& epfd,
|
941
|
+
const FileDescriptor& fd) {
|
942
|
+
if (!IsCorrectGeneration(epfd) || !IsCorrectGeneration(fd)) {
|
943
|
+
return PosixError::WrongGeneration();
|
944
|
+
}
|
945
|
+
epoll_event phony_event;
|
946
|
+
int result = epoll_ctl(epfd.fd(), EPOLL_CTL_DEL, fd.fd(), &phony_event);
|
947
|
+
if (result < 0) {
|
948
|
+
return PosixError::Error(errno);
|
949
|
+
}
|
950
|
+
return PosixError::Ok();
|
951
|
+
}
|
952
|
+
|
953
|
+
PosixError EventEnginePosixInterface::EpollCtlAdd(const FileDescriptor& epfd,
|
954
|
+
bool writable,
|
955
|
+
const FileDescriptor& fd,
|
956
|
+
void* data) {
|
957
|
+
epoll_event event;
|
958
|
+
event.events = static_cast<uint32_t>(EPOLLIN | EPOLLET);
|
959
|
+
if (writable) {
|
960
|
+
event.events |= EPOLLOUT;
|
961
|
+
}
|
962
|
+
event.data.ptr = data;
|
963
|
+
if (!IsCorrectGeneration(epfd) || !IsCorrectGeneration(fd)) {
|
964
|
+
return PosixError::WrongGeneration();
|
965
|
+
}
|
966
|
+
int result = epoll_ctl(epfd.fd(), EPOLL_CTL_ADD, fd.fd(), &event);
|
967
|
+
if (result < 0) {
|
968
|
+
return PosixError::Error(errno);
|
969
|
+
}
|
970
|
+
return PosixError::Ok();
|
971
|
+
}
|
972
|
+
|
973
|
+
#endif // GRPC_LINUX_EPOLL
|
974
|
+
|
975
|
+
absl::Status EventEnginePosixInterface::PrepareTcpClientSocket(
|
976
|
+
int fd, const EventEngine::ResolvedAddress& addr,
|
977
|
+
const PosixTcpOptions& options) {
|
978
|
+
bool close_fd = true;
|
979
|
+
auto sock_cleanup = absl::MakeCleanup([&close_fd, &fd]() -> void {
|
980
|
+
if (close_fd && fd > 0) {
|
981
|
+
close(fd);
|
982
|
+
}
|
983
|
+
});
|
984
|
+
GRPC_RETURN_IF_ERROR(SetSocketNonBlocking(fd, 1));
|
985
|
+
GRPC_RETURN_IF_ERROR(SetSocketCloexec(fd, 1));
|
986
|
+
if (options.tcp_receive_buffer_size != options.kReadBufferSizeUnset) {
|
987
|
+
GRPC_RETURN_IF_ERROR(SetSocketRcvBuf(fd, options.tcp_receive_buffer_size));
|
988
|
+
}
|
989
|
+
if (addr.address()->sa_family != AF_UNIX && !ResolvedAddressIsVSock(addr)) {
|
990
|
+
// If its not a unix socket or vsock address.
|
991
|
+
GRPC_RETURN_IF_ERROR(
|
992
|
+
SetSocketOption(fd, IPPROTO_TCP, TCP_NODELAY, 1, "TCP_NODELAY"));
|
993
|
+
GRPC_RETURN_IF_ERROR(
|
994
|
+
SetSocketOption(fd, SOL_SOCKET, SO_REUSEADDR, 1, "SO_REUSEADDR"));
|
995
|
+
GRPC_RETURN_IF_ERROR(SetSocketDscp(fd, options.dscp));
|
996
|
+
TrySetSocketTcpUserTimeout(fd, options, true);
|
997
|
+
}
|
998
|
+
GRPC_RETURN_IF_ERROR(InternalSetSocketNoSigpipeIfPossible(fd));
|
999
|
+
GRPC_RETURN_IF_ERROR(InternalApplySocketMutatorInOptions(
|
1000
|
+
fd, GRPC_FD_CLIENT_CONNECTION_USAGE, options));
|
1001
|
+
// No errors. Set close_fd to false to ensure the socket is
|
1002
|
+
// not closed.
|
1003
|
+
close_fd = false;
|
1004
|
+
return absl::OkStatus();
|
1005
|
+
}
|
1006
|
+
|
1007
|
+
PosixError EventEnginePosixInterface::PosixResultWrap(
|
1008
|
+
const FileDescriptor& wrapped,
|
1009
|
+
const absl::AnyInvocable<int(int) const>& fn) const {
|
1010
|
+
if (!IsCorrectGeneration(wrapped)) {
|
1011
|
+
return PosixError::WrongGeneration();
|
1012
|
+
}
|
1013
|
+
int result = fn(wrapped.fd());
|
1014
|
+
if (result < 0) {
|
1015
|
+
return PosixError::Error(errno);
|
1016
|
+
}
|
1017
|
+
return PosixError::Ok();
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
PosixErrorOr<FileDescriptor> EventEnginePosixInterface::RegisterPosixResult(
|
1021
|
+
int result) {
|
1022
|
+
if (result < 0) {
|
1023
|
+
return PosixError::Error(errno);
|
1024
|
+
}
|
1025
|
+
return descriptors_.Add(result);
|
1026
|
+
}
|
1027
|
+
|
1028
|
+
#endif // GRPC_POSIX_SOCKET
|
1029
|
+
|
1030
|
+
#if defined(GRPC_POSIX_WAKEUP_FD) || defined(GRPC_LINUX_EVENTFD)
|
1031
|
+
|
1032
|
+
void EventEnginePosixInterface::Close(const FileDescriptor& fd) {
|
1033
|
+
if (descriptors_.Remove(fd)) {
|
1034
|
+
close(fd.fd());
|
1035
|
+
}
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
bool EventEnginePosixInterface::IsCorrectGeneration(
|
1039
|
+
const FileDescriptor& fd) const {
|
1040
|
+
(void)fd; // Always used now
|
1041
|
+
#ifdef GRPC_ENABLE_FORK_SUPPORT
|
1042
|
+
if (IsEventEngineForkEnabled()) {
|
1043
|
+
return descriptors_.generation() == fd.generation();
|
1044
|
+
}
|
1045
|
+
#endif // GRPC_ENABLE_FORK_SUPPORT
|
1046
|
+
return true;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
absl::StatusOr<std::pair<FileDescriptor, FileDescriptor> >
|
1050
|
+
EventEnginePosixInterface::Pipe() {
|
1051
|
+
int pipefd[2];
|
1052
|
+
int r = pipe(pipefd);
|
1053
|
+
if (0 != r) {
|
1054
|
+
return absl::Status(absl::StatusCode::kInternal,
|
1055
|
+
absl::StrCat("pipe: ", grpc_core::StrError(errno)));
|
1056
|
+
}
|
1057
|
+
auto status = SetSocketNonBlocking(pipefd[0], 1);
|
1058
|
+
if (status.ok()) {
|
1059
|
+
status = SetSocketNonBlocking(pipefd[1], 1);
|
1060
|
+
}
|
1061
|
+
if (status.ok()) {
|
1062
|
+
return std::pair(descriptors_.Add(pipefd[0]), descriptors_.Add(pipefd[1]));
|
1063
|
+
}
|
1064
|
+
close(pipefd[0]);
|
1065
|
+
close(pipefd[1]);
|
1066
|
+
return status;
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
PosixErrorOr<int64_t> EventEnginePosixInterface::Read(const FileDescriptor& fd,
|
1070
|
+
absl::Span<char> buf) {
|
1071
|
+
return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), read, buf.data(),
|
1072
|
+
buf.size());
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
PosixErrorOr<int64_t> EventEnginePosixInterface::Write(const FileDescriptor& fd,
|
1076
|
+
absl::Span<char> buf) {
|
1077
|
+
return Int64Wrap(IsCorrectGeneration(fd), fd.fd(), write, buf.data(),
|
1078
|
+
buf.size());
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
#endif // defined (GRPC_POSIX_WAKEUP_FD) || defined (GRPC_LINUX_EVENTFD)
|
1082
|
+
|
1083
|
+
} // namespace grpc_event_engine::experimental
|