grpc 1.2.5 → 1.3.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +1434 -399
- data/etc/roots.pem +34 -150
- data/include/grpc/grpc.h +71 -0
- data/include/grpc/impl/codegen/atm.h +5 -0
- data/include/grpc/impl/codegen/atm_gcc_atomic.h +6 -0
- data/include/grpc/impl/codegen/atm_gcc_sync.h +2 -0
- data/include/grpc/impl/codegen/atm_windows.h +11 -0
- data/include/grpc/impl/codegen/grpc_types.h +54 -13
- data/include/grpc/impl/codegen/port_platform.h +15 -1
- data/include/grpc/support/alloc.h +2 -1
- data/include/grpc/support/sync.h +4 -0
- data/include/grpc/support/tls.h +1 -1
- data/src/core/ext/census/gen/trace_context.pb.h +1 -1
- data/src/core/ext/census/grpc_filter.c +14 -10
- data/src/core/ext/census/grpc_plugin.c +3 -1
- data/src/core/ext/census/trace_label.h +1 -1
- data/src/core/ext/census/trace_propagation.h +1 -1
- data/src/core/ext/census/trace_status.h +1 -1
- data/src/core/ext/census/trace_string.h +1 -1
- data/src/core/ext/census/tracing.h +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/channel_connectivity.c +56 -27
- data/src/core/ext/{client_channel → filters/client_channel}/client_channel.c +407 -202
- data/src/core/ext/{client_channel → filters/client_channel}/client_channel.h +10 -6
- data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/client_channel_factory.h +4 -4
- data/src/core/ext/{client_channel → filters/client_channel}/client_channel_plugin.c +12 -7
- data/src/core/ext/{client_channel → filters/client_channel}/connector.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/connector.h +3 -5
- data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.c +6 -6
- data/src/core/ext/{client_channel → filters/client_channel}/http_connect_handshaker.h +3 -3
- data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.c +4 -4
- data/src/core/ext/{client_channel → filters/client_channel}/http_proxy.h +3 -3
- data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/lb_policy.h +4 -4
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.c +22 -20
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb.h +4 -4
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel.h +5 -4
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/grpclb_channel_secure.c +2 -2
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.c +1 -1
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/load_balancer_api.h +6 -5
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.c +1 -1
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/grpclb/proto/grpc/lb/v1/load_balancer.pb.h +0 -0
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/pick_first/pick_first.c +20 -15
- data/src/core/ext/{lb_policy → filters/client_channel/lb_policy}/round_robin/round_robin.c +21 -16
- data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_factory.h +5 -5
- data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/lb_policy_registry.h +4 -4
- data/src/core/ext/{client_channel → filters/client_channel}/parse_address.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/parse_address.h +4 -4
- data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper.h +3 -3
- data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.c +10 -4
- data/src/core/ext/{client_channel → filters/client_channel}/proxy_mapper_registry.h +4 -4
- data/src/core/ext/{client_channel → filters/client_channel}/resolver.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/resolver.h +4 -4
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +350 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +66 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +319 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +289 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +64 -0
- data/src/core/ext/{resolver → filters/client_channel/resolver}/dns/native/dns_resolver.c +21 -5
- data/src/core/ext/{resolver → filters/client_channel/resolver}/sockaddr/sockaddr_resolver.c +3 -3
- data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/resolver_factory.h +6 -6
- data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.c +1 -2
- data/src/core/ext/{client_channel → filters/client_channel}/resolver_registry.h +4 -4
- data/src/core/ext/filters/client_channel/retry_throttle.c +210 -0
- data/src/core/ext/filters/client_channel/retry_throttle.h +65 -0
- data/src/core/ext/{client_channel → filters/client_channel}/subchannel.c +49 -43
- data/src/core/ext/{client_channel → filters/client_channel}/subchannel.h +21 -7
- data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/subchannel_index.h +5 -5
- data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.c +1 -1
- data/src/core/ext/{client_channel → filters/client_channel}/uri_parser.h +3 -3
- data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.c +4 -2
- data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting.h +3 -3
- data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.c +17 -14
- data/src/core/ext/{load_reporting → filters/load_reporting}/load_reporting_filter.h +4 -4
- data/src/core/ext/filters/max_age/max_age_filter.c +439 -0
- data/src/core/ext/filters/max_age/max_age_filter.h +39 -0
- data/src/core/ext/transport/chttp2/client/chttp2_connector.c +6 -41
- data/src/core/ext/transport/chttp2/client/chttp2_connector.h +1 -1
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +2 -2
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +3 -3
- data/src/core/ext/transport/chttp2/server/chttp2_server.c +2 -2
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +2 -5
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +2 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +449 -204
- data/src/core/ext/transport/chttp2/transport/frame_data.c +10 -7
- data/src/core/ext/transport/chttp2/transport/frame_goaway.c +3 -2
- data/src/core/ext/transport/chttp2/transport/frame_ping.c +37 -7
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +4 -3
- data/src/core/ext/transport/chttp2/transport/frame_settings.c +18 -38
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +1 -29
- data/src/core/ext/transport/chttp2/transport/frame_window_update.c +2 -2
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +64 -37
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +11 -4
- data/src/core/ext/transport/chttp2/transport/hpack_parser.c +60 -39
- data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
- data/src/core/ext/transport/chttp2/transport/http2_settings.c +75 -0
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +74 -0
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +22 -43
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +8 -10
- data/src/core/ext/transport/chttp2/transport/internal.h +24 -2
- data/src/core/ext/transport/chttp2/transport/parsing.c +33 -15
- data/src/core/ext/transport/chttp2/transport/writing.c +56 -10
- data/src/core/lib/channel/channel_args.c +7 -0
- data/src/core/lib/channel/channel_args.h +2 -0
- data/src/core/lib/channel/channel_stack.c +20 -27
- data/src/core/lib/channel/channel_stack.h +18 -16
- data/src/core/lib/channel/compress_filter.c +20 -18
- data/src/core/lib/channel/connected_channel.c +9 -8
- data/src/core/lib/channel/deadline_filter.c +28 -24
- data/src/core/lib/channel/deadline_filter.h +3 -3
- data/src/core/lib/channel/handshaker.c +3 -2
- data/src/core/lib/channel/http_client_filter.c +119 -61
- data/src/core/lib/channel/http_server_filter.c +124 -69
- data/src/core/lib/channel/message_size_filter.c +23 -19
- data/src/core/lib/http/httpcli.c +8 -6
- data/src/core/lib/http/httpcli_security_connector.c +5 -5
- data/src/core/lib/http/parser.c +57 -31
- data/src/core/lib/iomgr/closure.c +15 -0
- data/src/core/lib/iomgr/closure.h +4 -0
- data/src/core/lib/iomgr/combiner.c +8 -0
- data/src/core/lib/iomgr/endpoint_pair.h +2 -3
- data/src/core/lib/iomgr/endpoint_pair_posix.c +10 -7
- data/src/core/lib/iomgr/endpoint_pair_uv.c +2 -3
- data/src/core/lib/iomgr/endpoint_pair_windows.c +9 -6
- data/src/core/lib/iomgr/error.c +360 -177
- data/src/core/lib/iomgr/error.h +31 -33
- data/src/core/lib/iomgr/error_internal.h +30 -9
- data/src/core/lib/iomgr/ev_epoll_linux.c +25 -239
- data/src/core/lib/iomgr/ev_poll_posix.c +11 -7
- data/src/core/lib/iomgr/ev_posix.c +6 -0
- data/src/core/lib/iomgr/ev_posix.h +3 -0
- data/src/core/lib/iomgr/exec_ctx.c +6 -0
- data/src/core/lib/iomgr/executor.c +8 -2
- data/src/core/lib/iomgr/load_file.c +6 -3
- data/src/core/lib/iomgr/lockfree_event.c +238 -0
- data/src/core/{ext/client_channel/initial_connect_string.h → lib/iomgr/lockfree_event.h} +17 -13
- data/src/core/lib/iomgr/pollset.h +4 -0
- data/src/core/lib/iomgr/pollset_windows.c +2 -2
- data/src/core/lib/iomgr/port.h +9 -0
- data/src/core/lib/iomgr/resolve_address_posix.c +15 -9
- data/src/core/lib/iomgr/resolve_address_uv.c +8 -6
- data/src/core/lib/iomgr/resolve_address_windows.c +2 -2
- data/src/core/lib/iomgr/resource_quota.c +19 -4
- data/src/core/lib/iomgr/resource_quota.h +2 -0
- data/src/core/lib/iomgr/sockaddr_utils.c +3 -1
- data/src/core/lib/iomgr/socket_factory_posix.c +110 -0
- data/src/core/lib/iomgr/socket_factory_posix.h +90 -0
- data/src/core/lib/iomgr/socket_utils_common_posix.c +25 -9
- data/src/core/lib/iomgr/socket_utils_posix.h +7 -0
- data/src/core/lib/iomgr/tcp_client.h +0 -4
- data/src/core/lib/iomgr/tcp_client_posix.c +15 -31
- data/src/core/lib/iomgr/tcp_client_uv.c +10 -6
- data/src/core/lib/iomgr/tcp_client_windows.c +9 -19
- data/src/core/lib/iomgr/tcp_posix.c +111 -22
- data/src/core/lib/iomgr/tcp_posix.h +3 -4
- data/src/core/lib/iomgr/tcp_server_posix.c +39 -417
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +135 -0
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +221 -0
- data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.c +196 -0
- data/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.c +49 -0
- data/src/core/lib/iomgr/tcp_server_uv.c +43 -16
- data/src/core/lib/iomgr/tcp_server_windows.c +10 -22
- data/src/core/lib/iomgr/tcp_uv.c +16 -13
- data/src/core/lib/iomgr/tcp_windows.c +24 -12
- data/src/core/lib/iomgr/tcp_windows.h +2 -2
- data/src/core/lib/iomgr/timer.h +3 -0
- data/src/core/lib/iomgr/timer_generic.c +257 -72
- data/src/core/lib/iomgr/timer_generic.h +1 -1
- data/src/core/lib/iomgr/timer_heap.c +8 -8
- data/src/core/lib/iomgr/udp_server.c +54 -24
- data/src/core/lib/iomgr/udp_server.h +7 -7
- data/src/core/lib/iomgr/unix_sockets_posix.c +1 -1
- data/src/core/lib/iomgr/unix_sockets_posix_noop.c +2 -1
- data/src/core/lib/iomgr/wakeup_fd_posix.h +1 -1
- data/src/core/lib/profiling/basic_timers.c +1 -1
- data/src/core/lib/security/credentials/credentials.h +1 -1
- data/src/core/lib/security/credentials/google_default/google_default_credentials.c +10 -9
- data/src/core/lib/security/credentials/jwt/json_token.c +1 -1
- data/src/core/lib/security/credentials/jwt/jwt_verifier.c +2 -2
- data/src/core/lib/security/transport/client_auth_filter.c +33 -26
- data/src/core/lib/security/transport/secure_endpoint.c +8 -5
- data/src/core/lib/security/transport/security_connector.c +37 -37
- data/src/core/lib/security/transport/security_connector.h +1 -1
- data/src/core/lib/security/transport/security_handshaker.c +15 -12
- data/src/core/lib/security/transport/server_auth_filter.c +20 -18
- data/src/core/lib/security/transport/tsi_error.c +5 -3
- data/src/core/lib/security/transport/tsi_error.h +1 -1
- data/src/core/lib/{security/util → slice}/b64.c +21 -6
- data/src/core/lib/{security/util → slice}/b64.h +16 -4
- data/src/core/lib/slice/slice.c +4 -2
- data/src/core/lib/slice/slice_buffer.c +16 -14
- data/src/core/lib/support/arena.c +98 -0
- data/src/core/{ext/client_channel/initial_connect_string.c → lib/support/arena.h} +17 -15
- data/src/core/{ext/client_channel/default_initial_connect_string.c → lib/support/atm.c} +14 -5
- data/src/core/lib/support/cpu_linux.c +5 -0
- data/src/core/lib/support/sync.c +4 -0
- data/src/core/lib/support/time.c +4 -10
- data/src/core/lib/support/wrap_memcpy.c +3 -1
- data/src/core/lib/surface/call.c +252 -221
- data/src/core/lib/surface/channel.c +72 -21
- data/src/core/lib/surface/channel.h +8 -0
- data/src/core/lib/surface/completion_queue.c +2 -3
- data/src/core/lib/surface/completion_queue_factory.c +77 -0
- data/src/core/lib/surface/completion_queue_factory.h +51 -0
- data/src/core/lib/surface/init_secure.c +3 -1
- data/src/core/lib/surface/lame_client.c +18 -14
- data/src/core/lib/surface/server.c +43 -41
- data/src/core/lib/surface/validate_metadata.c +8 -4
- data/src/core/lib/surface/version.c +2 -2
- data/src/core/lib/transport/bdp_estimator.h +1 -1
- data/src/core/lib/transport/connectivity_state.c +2 -1
- data/src/core/lib/transport/error_utils.c +17 -17
- data/src/core/lib/transport/error_utils.h +1 -1
- data/src/core/lib/transport/metadata_batch.c +6 -7
- data/src/core/lib/transport/pid_controller.c +1 -0
- data/src/core/lib/transport/service_config.c +12 -0
- data/src/core/lib/transport/service_config.h +6 -0
- data/src/core/lib/transport/transport.c +29 -17
- data/src/core/lib/transport/transport.h +85 -42
- data/src/core/lib/transport/transport_impl.h +5 -3
- data/src/core/lib/transport/transport_op_string.c +20 -14
- data/src/core/plugin_registry/grpc_plugin_registry.c +8 -0
- data/src/core/{lib/tsi → tsi}/fake_transport_security.c +2 -2
- data/src/core/{lib/tsi → tsi}/fake_transport_security.h +4 -4
- data/src/core/{lib/tsi → tsi}/ssl_transport_security.c +40 -79
- data/src/core/{lib/tsi → tsi}/ssl_transport_security.h +44 -21
- data/src/core/{lib/tsi → tsi}/ssl_types.h +3 -3
- data/src/core/{lib/tsi → tsi}/transport_security.c +2 -2
- data/src/core/{lib/tsi → tsi}/transport_security.h +4 -4
- data/src/core/{lib/tsi → tsi}/transport_security_interface.h +3 -3
- data/src/ruby/ext/grpc/extconf.rb +1 -0
- data/src/ruby/ext/grpc/rb_call_credentials.c +2 -2
- data/src/ruby/ext/grpc/rb_channel.c +520 -93
- data/src/ruby/ext/grpc/rb_channel.h +2 -0
- data/src/ruby/ext/grpc/rb_channel_credentials.c +3 -0
- data/src/ruby/ext/grpc/rb_compression_options.c +5 -2
- data/src/ruby/ext/grpc/rb_event_thread.c +6 -6
- data/src/ruby/ext/grpc/rb_grpc.c +29 -7
- data/src/ruby/ext/grpc/rb_grpc.h +2 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +10 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +15 -0
- data/src/ruby/ext/grpc/rb_server.c +5 -3
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/channel_connection_spec.rb +173 -0
- data/src/ruby/spec/channel_spec.rb +29 -0
- data/src/ruby/spec/generic/rpc_server_pool_spec.rb +27 -17
- data/third_party/cares/ares_build.h +264 -0
- data/third_party/cares/cares/ares.h +636 -0
- data/third_party/cares/cares/ares__close_sockets.c +61 -0
- data/third_party/cares/cares/ares__get_hostent.c +261 -0
- data/third_party/cares/cares/ares__read_line.c +73 -0
- data/third_party/cares/cares/ares__timeval.c +111 -0
- data/third_party/cares/cares/ares_cancel.c +63 -0
- data/third_party/cares/cares/ares_create_query.c +202 -0
- data/third_party/cares/cares/ares_data.c +221 -0
- data/third_party/cares/cares/ares_data.h +72 -0
- data/third_party/cares/cares/ares_destroy.c +108 -0
- data/third_party/cares/cares/ares_dns.h +103 -0
- data/third_party/cares/cares/ares_expand_name.c +205 -0
- data/third_party/cares/cares/ares_expand_string.c +70 -0
- data/third_party/cares/cares/ares_fds.c +59 -0
- data/third_party/cares/cares/ares_free_hostent.c +41 -0
- data/third_party/cares/cares/ares_free_string.c +25 -0
- data/third_party/cares/cares/ares_getenv.c +30 -0
- data/third_party/cares/cares/ares_getenv.h +26 -0
- data/third_party/cares/cares/ares_gethostbyaddr.c +294 -0
- data/third_party/cares/cares/ares_gethostbyname.c +518 -0
- data/third_party/cares/cares/ares_getnameinfo.c +422 -0
- data/third_party/cares/cares/ares_getopt.c +122 -0
- data/third_party/cares/cares/ares_getopt.h +53 -0
- data/third_party/cares/cares/ares_getsock.c +66 -0
- data/third_party/cares/cares/ares_inet_net_pton.h +25 -0
- data/third_party/cares/cares/ares_init.c +2146 -0
- data/third_party/cares/cares/ares_iphlpapi.h +221 -0
- data/third_party/cares/cares/ares_ipv6.h +78 -0
- data/third_party/cares/cares/ares_library_init.c +167 -0
- data/third_party/cares/cares/ares_library_init.h +42 -0
- data/third_party/cares/cares/ares_llist.c +63 -0
- data/third_party/cares/cares/ares_llist.h +39 -0
- data/third_party/cares/cares/ares_mkquery.c +24 -0
- data/third_party/cares/cares/ares_nowarn.c +260 -0
- data/third_party/cares/cares/ares_nowarn.h +61 -0
- data/third_party/cares/cares/ares_options.c +402 -0
- data/third_party/cares/cares/ares_parse_a_reply.c +264 -0
- data/third_party/cares/cares/ares_parse_aaaa_reply.c +264 -0
- data/third_party/cares/cares/ares_parse_mx_reply.c +170 -0
- data/third_party/cares/cares/ares_parse_naptr_reply.c +188 -0
- data/third_party/cares/cares/ares_parse_ns_reply.c +183 -0
- data/third_party/cares/cares/ares_parse_ptr_reply.c +219 -0
- data/third_party/cares/cares/ares_parse_soa_reply.c +133 -0
- data/third_party/cares/cares/ares_parse_srv_reply.c +179 -0
- data/third_party/cares/cares/ares_parse_txt_reply.c +220 -0
- data/third_party/cares/cares/ares_platform.c +11035 -0
- data/third_party/cares/cares/ares_platform.h +43 -0
- data/third_party/cares/cares/ares_private.h +363 -0
- data/third_party/cares/cares/ares_process.c +1359 -0
- data/third_party/cares/cares/ares_query.c +186 -0
- data/third_party/cares/cares/ares_rules.h +125 -0
- data/third_party/cares/cares/ares_search.c +316 -0
- data/third_party/cares/cares/ares_send.c +131 -0
- data/third_party/cares/cares/ares_setup.h +217 -0
- data/third_party/cares/cares/ares_strcasecmp.c +66 -0
- data/third_party/cares/cares/ares_strcasecmp.h +30 -0
- data/third_party/cares/cares/ares_strdup.c +49 -0
- data/third_party/cares/cares/ares_strdup.h +24 -0
- data/third_party/cares/cares/ares_strerror.c +56 -0
- data/third_party/cares/cares/ares_timeout.c +88 -0
- data/third_party/cares/cares/ares_version.c +11 -0
- data/third_party/cares/cares/ares_version.h +24 -0
- data/third_party/cares/cares/ares_writev.c +79 -0
- data/third_party/cares/cares/bitncmp.c +59 -0
- data/third_party/cares/cares/bitncmp.h +26 -0
- data/third_party/cares/cares/config-win32.h +377 -0
- data/third_party/cares/cares/inet_net_pton.c +450 -0
- data/third_party/cares/cares/inet_ntop.c +208 -0
- data/third_party/cares/cares/setup_once.h +554 -0
- data/third_party/cares/cares/windows_port.c +22 -0
- data/third_party/cares/config_darwin/ares_config.h +523 -0
- data/third_party/cares/config_linux/ares_config.h +524 -0
- metadata +164 -68
@@ -157,7 +157,6 @@
|
|
157
157
|
#define GPR_GETPID_IN_UNISTD_H 1
|
158
158
|
#define GPR_SUPPORT_CHANNELS_FROM_FD 1
|
159
159
|
#elif defined(__linux__)
|
160
|
-
#define GPR_POSIX_CRASH_HANDLER 1
|
161
160
|
#define GPR_PLATFORM_STRING "linux"
|
162
161
|
#ifndef _BSD_SOURCE
|
163
162
|
#define _BSD_SOURCE
|
@@ -187,6 +186,11 @@
|
|
187
186
|
#else /* _LP64 */
|
188
187
|
#define GPR_ARCH_32 1
|
189
188
|
#endif /* _LP64 */
|
189
|
+
#ifdef __GLIBC__
|
190
|
+
#define GPR_POSIX_CRASH_HANDLER 1
|
191
|
+
#else /* musl libc */
|
192
|
+
#define GPR_MUSL_LIBC_COMPAT 1
|
193
|
+
#endif
|
190
194
|
#elif defined(__APPLE__)
|
191
195
|
#include <Availability.h>
|
192
196
|
#include <TargetConditionals.h>
|
@@ -364,11 +368,21 @@ typedef unsigned __int64 uint64_t;
|
|
364
368
|
power of two */
|
365
369
|
#define GPR_MAX_ALIGNMENT 16
|
366
370
|
|
371
|
+
#ifndef GRPC_ARES
|
372
|
+
#ifdef GPR_WINDOWS
|
373
|
+
#define GRPC_ARES 0
|
374
|
+
#else
|
375
|
+
#define GRPC_ARES 1
|
376
|
+
#endif
|
377
|
+
#endif
|
378
|
+
|
367
379
|
#ifndef GRPC_MUST_USE_RESULT
|
368
380
|
#if defined(__GNUC__) && !defined(__MINGW32__)
|
369
381
|
#define GRPC_MUST_USE_RESULT __attribute__((warn_unused_result))
|
382
|
+
#define GPR_ALIGN_STRUCT(n) __attribute__((aligned(n)))
|
370
383
|
#else
|
371
384
|
#define GRPC_MUST_USE_RESULT
|
385
|
+
#define GPR_ALIGN_STRUCT(n)
|
372
386
|
#endif
|
373
387
|
#endif
|
374
388
|
|
@@ -68,7 +68,8 @@ GPRAPI void gpr_free_aligned(void *ptr);
|
|
68
68
|
|
69
69
|
/** Request the family of allocation functions in \a functions be used. NOTE
|
70
70
|
* that this request will be honored in a *best effort* basis and that no
|
71
|
-
* guarantees are made about the default functions (eg, malloc) being called.
|
71
|
+
* guarantees are made about the default functions (eg, malloc) being called.
|
72
|
+
* The functions.free_fn implementation must be a no-op for NULL input. */
|
72
73
|
GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
|
73
74
|
|
74
75
|
/** Return the family of allocation functions currently in effect. */
|
data/include/grpc/support/sync.h
CHANGED
@@ -164,6 +164,10 @@ GPRAPI void gpr_refn(gpr_refcount *r, int n);
|
|
164
164
|
zero. . Requires *r initialized. */
|
165
165
|
GPRAPI int gpr_unref(gpr_refcount *r);
|
166
166
|
|
167
|
+
/* Return non-zero iff the reference count of *r is one, and thus is owned
|
168
|
+
by exactly one object. */
|
169
|
+
GPRAPI int gpr_ref_is_unique(gpr_refcount *r);
|
170
|
+
|
167
171
|
/* --- Stats counters ---
|
168
172
|
|
169
173
|
These calls act on the integral type gpr_stats_counter. It requires no
|
data/include/grpc/support/tls.h
CHANGED
@@ -74,17 +74,18 @@ static void extract_and_annotate_method_tag(grpc_metadata_batch *md,
|
|
74
74
|
}
|
75
75
|
|
76
76
|
static void client_mutate_op(grpc_call_element *elem,
|
77
|
-
|
77
|
+
grpc_transport_stream_op_batch *op) {
|
78
78
|
call_data *calld = elem->call_data;
|
79
79
|
channel_data *chand = elem->channel_data;
|
80
80
|
if (op->send_initial_metadata) {
|
81
|
-
extract_and_annotate_method_tag(
|
81
|
+
extract_and_annotate_method_tag(
|
82
|
+
op->payload->send_initial_metadata.send_initial_metadata, calld, chand);
|
82
83
|
}
|
83
84
|
}
|
84
85
|
|
85
86
|
static void client_start_transport_op(grpc_exec_ctx *exec_ctx,
|
86
87
|
grpc_call_element *elem,
|
87
|
-
|
88
|
+
grpc_transport_stream_op_batch *op) {
|
88
89
|
client_mutate_op(elem, op);
|
89
90
|
grpc_call_next_op(exec_ctx, elem, op);
|
90
91
|
}
|
@@ -103,19 +104,22 @@ static void server_on_done_recv(grpc_exec_ctx *exec_ctx, void *ptr,
|
|
103
104
|
}
|
104
105
|
|
105
106
|
static void server_mutate_op(grpc_call_element *elem,
|
106
|
-
|
107
|
+
grpc_transport_stream_op_batch *op) {
|
107
108
|
call_data *calld = elem->call_data;
|
108
109
|
if (op->recv_initial_metadata) {
|
109
110
|
/* substitute our callback for the op callback */
|
110
|
-
calld->recv_initial_metadata =
|
111
|
-
|
112
|
-
|
111
|
+
calld->recv_initial_metadata =
|
112
|
+
op->payload->recv_initial_metadata.recv_initial_metadata;
|
113
|
+
calld->on_done_recv =
|
114
|
+
op->payload->recv_initial_metadata.recv_initial_metadata_ready;
|
115
|
+
op->payload->recv_initial_metadata.recv_initial_metadata_ready =
|
116
|
+
&calld->finish_recv;
|
113
117
|
}
|
114
118
|
}
|
115
119
|
|
116
120
|
static void server_start_transport_op(grpc_exec_ctx *exec_ctx,
|
117
121
|
grpc_call_element *elem,
|
118
|
-
|
122
|
+
grpc_transport_stream_op_batch *op) {
|
119
123
|
/* TODO(ctiller): this code fails. I don't know why. I expect it's
|
120
124
|
incomplete, and someone should look at it soon.
|
121
125
|
|
@@ -138,7 +142,7 @@ static grpc_error *client_init_call_elem(grpc_exec_ctx *exec_ctx,
|
|
138
142
|
static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
139
143
|
grpc_call_element *elem,
|
140
144
|
const grpc_call_final_info *final_info,
|
141
|
-
|
145
|
+
grpc_closure *ignored) {
|
142
146
|
call_data *d = elem->call_data;
|
143
147
|
GPR_ASSERT(d != NULL);
|
144
148
|
/* TODO(hongyu): record rpc client stats and census_rpc_end_op here */
|
@@ -160,7 +164,7 @@ static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx,
|
|
160
164
|
static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
161
165
|
grpc_call_element *elem,
|
162
166
|
const grpc_call_final_info *final_info,
|
163
|
-
|
167
|
+
grpc_closure *ignored) {
|
164
168
|
call_data *d = elem->call_data;
|
165
169
|
GPR_ASSERT(d != NULL);
|
166
170
|
/* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
|
@@ -31,6 +31,8 @@
|
|
31
31
|
*
|
32
32
|
*/
|
33
33
|
|
34
|
+
#include <grpc/support/port_platform.h>
|
35
|
+
|
34
36
|
#include <limits.h>
|
35
37
|
#include <string.h>
|
36
38
|
|
@@ -48,7 +50,7 @@ static bool is_census_enabled(const grpc_channel_args *a) {
|
|
48
50
|
return a->args[i].value.integer != 0 && census_enabled();
|
49
51
|
}
|
50
52
|
}
|
51
|
-
return census_enabled();
|
53
|
+
return census_enabled() && !grpc_channel_args_want_minimal_stack(a);
|
52
54
|
}
|
53
55
|
|
54
56
|
static bool maybe_add_census_filter(grpc_exec_ctx *exec_ctx,
|
@@ -36,7 +36,7 @@
|
|
36
36
|
#include <grpc/support/alloc.h>
|
37
37
|
#include <grpc/support/log.h>
|
38
38
|
|
39
|
-
#include "src/core/ext/client_channel/client_channel.h"
|
39
|
+
#include "src/core/ext/filters/client_channel/client_channel.h"
|
40
40
|
#include "src/core/lib/iomgr/timer.h"
|
41
41
|
#include "src/core/lib/surface/api_trace.h"
|
42
42
|
#include "src/core/lib/surface/completion_queue.h"
|
@@ -67,9 +67,8 @@ grpc_connectivity_state grpc_channel_check_connectivity_state(
|
|
67
67
|
|
68
68
|
typedef enum {
|
69
69
|
WAITING,
|
70
|
-
|
70
|
+
READY_TO_CALL_BACK,
|
71
71
|
CALLING_BACK_AND_FINISHED,
|
72
|
-
CALLED_BACK
|
73
72
|
} callback_phase;
|
74
73
|
|
75
74
|
typedef struct {
|
@@ -77,11 +76,13 @@ typedef struct {
|
|
77
76
|
callback_phase phase;
|
78
77
|
grpc_closure on_complete;
|
79
78
|
grpc_closure on_timeout;
|
79
|
+
grpc_closure watcher_timer_init;
|
80
80
|
grpc_timer alarm;
|
81
81
|
grpc_connectivity_state state;
|
82
82
|
grpc_completion_queue *cq;
|
83
83
|
grpc_cq_completion completion_storage;
|
84
84
|
grpc_channel *channel;
|
85
|
+
grpc_error *error;
|
85
86
|
void *tag;
|
86
87
|
} state_watcher;
|
87
88
|
|
@@ -105,11 +106,8 @@ static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw,
|
|
105
106
|
gpr_mu_lock(&w->mu);
|
106
107
|
switch (w->phase) {
|
107
108
|
case WAITING:
|
108
|
-
case
|
109
|
+
case READY_TO_CALL_BACK:
|
109
110
|
GPR_UNREACHABLE_CODE(return );
|
110
|
-
case CALLING_BACK:
|
111
|
-
w->phase = CALLED_BACK;
|
112
|
-
break;
|
113
111
|
case CALLING_BACK_AND_FINISHED:
|
114
112
|
delete = 1;
|
115
113
|
break;
|
@@ -123,10 +121,14 @@ static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw,
|
|
123
121
|
|
124
122
|
static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
|
125
123
|
bool due_to_completion, grpc_error *error) {
|
126
|
-
int delete = 0;
|
127
|
-
|
128
124
|
if (due_to_completion) {
|
129
125
|
grpc_timer_cancel(exec_ctx, &w->alarm);
|
126
|
+
} else {
|
127
|
+
grpc_channel_element *client_channel_elem = grpc_channel_stack_last_element(
|
128
|
+
grpc_channel_get_channel_stack(w->channel));
|
129
|
+
grpc_client_channel_watch_connectivity_state(exec_ctx, client_channel_elem,
|
130
|
+
grpc_cq_pollset(w->cq), NULL,
|
131
|
+
&w->on_complete, NULL);
|
130
132
|
}
|
131
133
|
|
132
134
|
gpr_mu_lock(&w->mu);
|
@@ -139,33 +141,35 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
|
|
139
141
|
error = GRPC_ERROR_NONE;
|
140
142
|
} else {
|
141
143
|
if (error == GRPC_ERROR_NONE) {
|
142
|
-
error =
|
143
|
-
|
144
|
+
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
145
|
+
"Timed out waiting for connection state change");
|
144
146
|
} else if (error == GRPC_ERROR_CANCELLED) {
|
145
147
|
error = GRPC_ERROR_NONE;
|
146
148
|
}
|
147
149
|
}
|
148
150
|
switch (w->phase) {
|
149
151
|
case WAITING:
|
150
|
-
|
151
|
-
|
152
|
-
|
152
|
+
GRPC_ERROR_REF(error);
|
153
|
+
w->error = error;
|
154
|
+
w->phase = READY_TO_CALL_BACK;
|
153
155
|
break;
|
154
|
-
case
|
156
|
+
case READY_TO_CALL_BACK:
|
157
|
+
if (error != GRPC_ERROR_NONE) {
|
158
|
+
GPR_ASSERT(!due_to_completion);
|
159
|
+
GRPC_ERROR_UNREF(w->error);
|
160
|
+
GRPC_ERROR_REF(error);
|
161
|
+
w->error = error;
|
162
|
+
}
|
155
163
|
w->phase = CALLING_BACK_AND_FINISHED;
|
164
|
+
grpc_cq_end_op(exec_ctx, w->cq, w->tag, w->error, finished_completion, w,
|
165
|
+
&w->completion_storage);
|
156
166
|
break;
|
157
167
|
case CALLING_BACK_AND_FINISHED:
|
158
168
|
GPR_UNREACHABLE_CODE(return );
|
159
|
-
case CALLED_BACK:
|
160
|
-
delete = 1;
|
161
169
|
break;
|
162
170
|
}
|
163
171
|
gpr_mu_unlock(&w->mu);
|
164
172
|
|
165
|
-
if (delete) {
|
166
|
-
delete_state_watcher(exec_ctx, w);
|
167
|
-
}
|
168
|
-
|
169
173
|
GRPC_ERROR_UNREF(error);
|
170
174
|
}
|
171
175
|
|
@@ -179,6 +183,28 @@ static void timeout_complete(grpc_exec_ctx *exec_ctx, void *pw,
|
|
179
183
|
partly_done(exec_ctx, pw, false, GRPC_ERROR_REF(error));
|
180
184
|
}
|
181
185
|
|
186
|
+
int grpc_channel_num_external_connectivity_watchers(grpc_channel *channel) {
|
187
|
+
grpc_channel_element *client_channel_elem =
|
188
|
+
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
|
189
|
+
return grpc_client_channel_num_external_connectivity_watchers(
|
190
|
+
client_channel_elem);
|
191
|
+
}
|
192
|
+
|
193
|
+
typedef struct watcher_timer_init_arg {
|
194
|
+
state_watcher *w;
|
195
|
+
gpr_timespec deadline;
|
196
|
+
} watcher_timer_init_arg;
|
197
|
+
|
198
|
+
static void watcher_timer_init(grpc_exec_ctx *exec_ctx, void *arg,
|
199
|
+
grpc_error *error_ignored) {
|
200
|
+
watcher_timer_init_arg *wa = (watcher_timer_init_arg *)arg;
|
201
|
+
|
202
|
+
grpc_timer_init(exec_ctx, &wa->w->alarm,
|
203
|
+
gpr_convert_clock_type(wa->deadline, GPR_CLOCK_MONOTONIC),
|
204
|
+
&wa->w->on_timeout, gpr_now(GPR_CLOCK_MONOTONIC));
|
205
|
+
gpr_free(wa);
|
206
|
+
}
|
207
|
+
|
182
208
|
void grpc_channel_watch_connectivity_state(
|
183
209
|
grpc_channel *channel, grpc_connectivity_state last_observed_state,
|
184
210
|
gpr_timespec deadline, grpc_completion_queue *cq, void *tag) {
|
@@ -208,16 +234,19 @@ void grpc_channel_watch_connectivity_state(
|
|
208
234
|
w->cq = cq;
|
209
235
|
w->tag = tag;
|
210
236
|
w->channel = channel;
|
237
|
+
w->error = NULL;
|
211
238
|
|
212
|
-
|
213
|
-
|
214
|
-
|
239
|
+
watcher_timer_init_arg *wa = gpr_malloc(sizeof(watcher_timer_init_arg));
|
240
|
+
wa->w = w;
|
241
|
+
wa->deadline = deadline;
|
242
|
+
grpc_closure_init(&w->watcher_timer_init, watcher_timer_init, wa,
|
243
|
+
grpc_schedule_on_exec_ctx);
|
215
244
|
|
216
245
|
if (client_channel_elem->filter == &grpc_client_channel_filter) {
|
217
246
|
GRPC_CHANNEL_INTERNAL_REF(channel, "watch_channel_connectivity");
|
218
|
-
grpc_client_channel_watch_connectivity_state(
|
219
|
-
|
220
|
-
|
247
|
+
grpc_client_channel_watch_connectivity_state(
|
248
|
+
&exec_ctx, client_channel_elem, grpc_cq_pollset(cq), &w->state,
|
249
|
+
&w->on_complete, &w->watcher_timer_init);
|
221
250
|
} else {
|
222
251
|
abort();
|
223
252
|
}
|
@@ -31,7 +31,7 @@
|
|
31
31
|
*
|
32
32
|
*/
|
33
33
|
|
34
|
-
#include "src/core/ext/client_channel/client_channel.h"
|
34
|
+
#include "src/core/ext/filters/client_channel/client_channel.h"
|
35
35
|
|
36
36
|
#include <stdbool.h>
|
37
37
|
#include <stdio.h>
|
@@ -43,11 +43,12 @@
|
|
43
43
|
#include <grpc/support/sync.h>
|
44
44
|
#include <grpc/support/useful.h>
|
45
45
|
|
46
|
-
#include "src/core/ext/client_channel/http_connect_handshaker.h"
|
47
|
-
#include "src/core/ext/client_channel/lb_policy_registry.h"
|
48
|
-
#include "src/core/ext/client_channel/proxy_mapper_registry.h"
|
49
|
-
#include "src/core/ext/client_channel/resolver_registry.h"
|
50
|
-
#include "src/core/ext/client_channel/
|
46
|
+
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
|
47
|
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
|
48
|
+
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
|
49
|
+
#include "src/core/ext/filters/client_channel/resolver_registry.h"
|
50
|
+
#include "src/core/ext/filters/client_channel/retry_throttle.h"
|
51
|
+
#include "src/core/ext/filters/client_channel/subchannel.h"
|
51
52
|
#include "src/core/lib/channel/channel_args.h"
|
52
53
|
#include "src/core/lib/channel/connected_channel.h"
|
53
54
|
#include "src/core/lib/channel/deadline_filter.h"
|
@@ -71,7 +72,8 @@
|
|
71
72
|
*/
|
72
73
|
|
73
74
|
typedef enum {
|
74
|
-
|
75
|
+
/* zero so it can be default initialized */
|
76
|
+
WAIT_FOR_READY_UNSET = 0,
|
75
77
|
WAIT_FOR_READY_FALSE,
|
76
78
|
WAIT_FOR_READY_TRUE
|
77
79
|
} wait_for_ready_value;
|
@@ -172,6 +174,8 @@ static void *method_parameters_create_from_json(const grpc_json *json) {
|
|
172
174
|
return value;
|
173
175
|
}
|
174
176
|
|
177
|
+
struct external_connectivity_watcher;
|
178
|
+
|
175
179
|
/*************************************************************************
|
176
180
|
* CHANNEL-WIDE FUNCTIONS
|
177
181
|
*/
|
@@ -188,6 +192,8 @@ typedef struct client_channel_channel_data {
|
|
188
192
|
grpc_combiner *combiner;
|
189
193
|
/** currently active load balancer */
|
190
194
|
grpc_lb_policy *lb_policy;
|
195
|
+
/** retry throttle data */
|
196
|
+
grpc_server_retry_throttle_data *retry_throttle_data;
|
191
197
|
/** maps method names to method_parameters structs */
|
192
198
|
grpc_slice_hash_table *method_params_table;
|
193
199
|
/** incoming resolver result - set by resolver.next() */
|
@@ -205,6 +211,11 @@ typedef struct client_channel_channel_data {
|
|
205
211
|
/** interested parties (owned) */
|
206
212
|
grpc_pollset_set *interested_parties;
|
207
213
|
|
214
|
+
/* external_connectivity_watcher_list head is guarded by its own mutex, since
|
215
|
+
* counts need to be grabbed immediately without polling on a cq */
|
216
|
+
gpr_mu external_connectivity_watcher_list_mu;
|
217
|
+
struct external_connectivity_watcher *external_connectivity_watcher_list_head;
|
218
|
+
|
208
219
|
/* the following properties are guarded by a mutex since API's require them
|
209
220
|
to be instantaneously available */
|
210
221
|
gpr_mu info_mu;
|
@@ -283,6 +294,65 @@ static void watch_lb_policy_locked(grpc_exec_ctx *exec_ctx, channel_data *chand,
|
|
283
294
|
&w->on_changed);
|
284
295
|
}
|
285
296
|
|
297
|
+
typedef struct {
|
298
|
+
char *server_name;
|
299
|
+
grpc_server_retry_throttle_data *retry_throttle_data;
|
300
|
+
} service_config_parsing_state;
|
301
|
+
|
302
|
+
static void parse_retry_throttle_params(const grpc_json *field, void *arg) {
|
303
|
+
service_config_parsing_state *parsing_state = arg;
|
304
|
+
if (strcmp(field->key, "retryThrottling") == 0) {
|
305
|
+
if (parsing_state->retry_throttle_data != NULL) return; // Duplicate.
|
306
|
+
if (field->type != GRPC_JSON_OBJECT) return;
|
307
|
+
int max_milli_tokens = 0;
|
308
|
+
int milli_token_ratio = 0;
|
309
|
+
for (grpc_json *sub_field = field->child; sub_field != NULL;
|
310
|
+
sub_field = sub_field->next) {
|
311
|
+
if (sub_field->key == NULL) return;
|
312
|
+
if (strcmp(sub_field->key, "maxTokens") == 0) {
|
313
|
+
if (max_milli_tokens != 0) return; // Duplicate.
|
314
|
+
if (sub_field->type != GRPC_JSON_NUMBER) return;
|
315
|
+
max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
|
316
|
+
if (max_milli_tokens == -1) return;
|
317
|
+
max_milli_tokens *= 1000;
|
318
|
+
} else if (strcmp(sub_field->key, "tokenRatio") == 0) {
|
319
|
+
if (milli_token_ratio != 0) return; // Duplicate.
|
320
|
+
if (sub_field->type != GRPC_JSON_NUMBER) return;
|
321
|
+
// We support up to 3 decimal digits.
|
322
|
+
size_t whole_len = strlen(sub_field->value);
|
323
|
+
uint32_t multiplier = 1;
|
324
|
+
uint32_t decimal_value = 0;
|
325
|
+
const char *decimal_point = strchr(sub_field->value, '.');
|
326
|
+
if (decimal_point != NULL) {
|
327
|
+
whole_len = (size_t)(decimal_point - sub_field->value);
|
328
|
+
multiplier = 1000;
|
329
|
+
size_t decimal_len = strlen(decimal_point + 1);
|
330
|
+
if (decimal_len > 3) decimal_len = 3;
|
331
|
+
if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
|
332
|
+
&decimal_value)) {
|
333
|
+
return;
|
334
|
+
}
|
335
|
+
uint32_t decimal_multiplier = 1;
|
336
|
+
for (size_t i = 0; i < (3 - decimal_len); ++i) {
|
337
|
+
decimal_multiplier *= 10;
|
338
|
+
}
|
339
|
+
decimal_value *= decimal_multiplier;
|
340
|
+
}
|
341
|
+
uint32_t whole_value;
|
342
|
+
if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
|
343
|
+
&whole_value)) {
|
344
|
+
return;
|
345
|
+
}
|
346
|
+
milli_token_ratio = (int)((whole_value * multiplier) + decimal_value);
|
347
|
+
if (milli_token_ratio <= 0) return;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
parsing_state->retry_throttle_data =
|
351
|
+
grpc_retry_throttle_map_get_data_for_server(
|
352
|
+
parsing_state->server_name, max_milli_tokens, milli_token_ratio);
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
286
356
|
static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
287
357
|
void *arg, grpc_error *error) {
|
288
358
|
channel_data *chand = arg;
|
@@ -292,8 +362,11 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
292
362
|
grpc_slice_hash_table *method_params_table = NULL;
|
293
363
|
grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
|
294
364
|
bool exit_idle = false;
|
295
|
-
grpc_error *state_error =
|
365
|
+
grpc_error *state_error =
|
366
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
|
296
367
|
char *service_config_json = NULL;
|
368
|
+
service_config_parsing_state parsing_state;
|
369
|
+
memset(&parsing_state, 0, sizeof(parsing_state));
|
297
370
|
|
298
371
|
if (chand->resolver_result != NULL) {
|
299
372
|
// Find LB policy name.
|
@@ -308,8 +381,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
308
381
|
// resolver actually specified.
|
309
382
|
channel_arg =
|
310
383
|
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
|
311
|
-
if (channel_arg != NULL) {
|
312
|
-
GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
|
384
|
+
if (channel_arg != NULL && channel_arg->type == GRPC_ARG_POINTER) {
|
313
385
|
grpc_lb_addresses *addresses = channel_arg->value.pointer.p;
|
314
386
|
bool found_backend_address = false;
|
315
387
|
for (size_t i = 0; i < addresses->num_addresses; ++i) {
|
@@ -354,6 +426,19 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
354
426
|
grpc_service_config *service_config =
|
355
427
|
grpc_service_config_create(service_config_json);
|
356
428
|
if (service_config != NULL) {
|
429
|
+
channel_arg =
|
430
|
+
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVER_URI);
|
431
|
+
GPR_ASSERT(channel_arg != NULL);
|
432
|
+
GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
|
433
|
+
grpc_uri *uri =
|
434
|
+
grpc_uri_parse(exec_ctx, channel_arg->value.string, true);
|
435
|
+
GPR_ASSERT(uri->path[0] != '\0');
|
436
|
+
parsing_state.server_name =
|
437
|
+
uri->path[0] == '/' ? uri->path + 1 : uri->path;
|
438
|
+
grpc_service_config_parse_global_params(
|
439
|
+
service_config, parse_retry_throttle_params, &parsing_state);
|
440
|
+
parsing_state.server_name = NULL;
|
441
|
+
grpc_uri_destroy(uri);
|
357
442
|
method_params_table = grpc_service_config_create_method_config_table(
|
358
443
|
exec_ctx, service_config, method_parameters_create_from_json,
|
359
444
|
&method_parameters_vtable);
|
@@ -385,6 +470,11 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
385
470
|
chand->info_service_config_json = service_config_json;
|
386
471
|
}
|
387
472
|
gpr_mu_unlock(&chand->info_mu);
|
473
|
+
|
474
|
+
if (chand->retry_throttle_data != NULL) {
|
475
|
+
grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
|
476
|
+
}
|
477
|
+
chand->retry_throttle_data = parsing_state.retry_throttle_data;
|
388
478
|
if (chand->method_params_table != NULL) {
|
389
479
|
grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
|
390
480
|
}
|
@@ -392,9 +482,9 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
392
482
|
if (lb_policy != NULL) {
|
393
483
|
grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
|
394
484
|
} else if (chand->resolver == NULL /* disconnected */) {
|
395
|
-
grpc_closure_list_fail_all(
|
396
|
-
|
397
|
-
|
485
|
+
grpc_closure_list_fail_all(&chand->waiting_for_config_closures,
|
486
|
+
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
487
|
+
"Channel disconnected", &error, 1));
|
398
488
|
grpc_closure_list_sched(exec_ctx, &chand->waiting_for_config_closures);
|
399
489
|
}
|
400
490
|
if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) {
|
@@ -422,8 +512,8 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
422
512
|
grpc_error *refs[] = {error, state_error};
|
423
513
|
set_channel_connectivity_state_locked(
|
424
514
|
exec_ctx, chand, GRPC_CHANNEL_SHUTDOWN,
|
425
|
-
|
426
|
-
|
515
|
+
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
516
|
+
"Got config after disconnection", refs, GPR_ARRAY_SIZE(refs)),
|
427
517
|
"resolver_gone");
|
428
518
|
}
|
429
519
|
|
@@ -449,7 +539,7 @@ static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
|
|
449
539
|
static void start_transport_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
450
540
|
grpc_error *error_ignored) {
|
451
541
|
grpc_transport_op *op = arg;
|
452
|
-
grpc_channel_element *elem = op->
|
542
|
+
grpc_channel_element *elem = op->handler_private.extra_arg;
|
453
543
|
channel_data *chand = elem->channel_data;
|
454
544
|
|
455
545
|
if (op->on_connectivity_state_change != NULL) {
|
@@ -462,8 +552,9 @@ static void start_transport_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
462
552
|
|
463
553
|
if (op->send_ping != NULL) {
|
464
554
|
if (chand->lb_policy == NULL) {
|
465
|
-
grpc_closure_sched(
|
466
|
-
|
555
|
+
grpc_closure_sched(
|
556
|
+
exec_ctx, op->send_ping,
|
557
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
|
467
558
|
} else {
|
468
559
|
grpc_lb_policy_ping_one_locked(exec_ctx, chand->lb_policy, op->send_ping);
|
469
560
|
op->bind_pollset = NULL;
|
@@ -510,12 +601,12 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
|
|
510
601
|
op->bind_pollset);
|
511
602
|
}
|
512
603
|
|
513
|
-
op->
|
604
|
+
op->handler_private.extra_arg = elem;
|
514
605
|
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "start_transport_op");
|
515
606
|
grpc_closure_sched(
|
516
|
-
exec_ctx,
|
517
|
-
|
518
|
-
|
607
|
+
exec_ctx,
|
608
|
+
grpc_closure_init(&op->handler_private.closure, start_transport_op_locked,
|
609
|
+
op, grpc_combiner_scheduler(chand->combiner, false)),
|
519
610
|
GRPC_ERROR_NONE);
|
520
611
|
}
|
521
612
|
|
@@ -548,6 +639,12 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
548
639
|
// Initialize data members.
|
549
640
|
chand->combiner = grpc_combiner_create(NULL);
|
550
641
|
gpr_mu_init(&chand->info_mu);
|
642
|
+
gpr_mu_init(&chand->external_connectivity_watcher_list_mu);
|
643
|
+
|
644
|
+
gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
|
645
|
+
chand->external_connectivity_watcher_list_head = NULL;
|
646
|
+
gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
|
647
|
+
|
551
648
|
chand->owning_stack = args->channel_stack;
|
552
649
|
grpc_closure_init(&chand->on_resolver_result_changed,
|
553
650
|
on_resolver_result_changed_locked, chand,
|
@@ -558,14 +655,26 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
558
655
|
// Record client channel factory.
|
559
656
|
const grpc_arg *arg = grpc_channel_args_find(args->channel_args,
|
560
657
|
GRPC_ARG_CLIENT_CHANNEL_FACTORY);
|
561
|
-
|
562
|
-
|
658
|
+
if (arg == NULL) {
|
659
|
+
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
660
|
+
"Missing client channel factory in args for client channel filter");
|
661
|
+
}
|
662
|
+
if (arg->type != GRPC_ARG_POINTER) {
|
663
|
+
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
664
|
+
"client channel factory arg must be a pointer");
|
665
|
+
}
|
563
666
|
grpc_client_channel_factory_ref(arg->value.pointer.p);
|
564
667
|
chand->client_channel_factory = arg->value.pointer.p;
|
565
668
|
// Get server name to resolve, using proxy mapper if needed.
|
566
669
|
arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
|
567
|
-
|
568
|
-
|
670
|
+
if (arg == NULL) {
|
671
|
+
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
672
|
+
"Missing server uri in args for client channel filter");
|
673
|
+
}
|
674
|
+
if (arg->type != GRPC_ARG_STRING) {
|
675
|
+
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
676
|
+
"server uri arg must be a string");
|
677
|
+
}
|
569
678
|
char *proxy_name = NULL;
|
570
679
|
grpc_channel_args *new_args = NULL;
|
571
680
|
grpc_proxy_mappers_map_name(exec_ctx, arg->value.string, args->channel_args,
|
@@ -578,7 +687,7 @@ static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
578
687
|
if (proxy_name != NULL) gpr_free(proxy_name);
|
579
688
|
if (new_args != NULL) grpc_channel_args_destroy(exec_ctx, new_args);
|
580
689
|
if (chand->resolver == NULL) {
|
581
|
-
return
|
690
|
+
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("resolver creation failed");
|
582
691
|
}
|
583
692
|
return GRPC_ERROR_NONE;
|
584
693
|
}
|
@@ -612,6 +721,9 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
612
721
|
}
|
613
722
|
gpr_free(chand->info_lb_policy_name);
|
614
723
|
gpr_free(chand->info_service_config_json);
|
724
|
+
if (chand->retry_throttle_data != NULL) {
|
725
|
+
grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
|
726
|
+
}
|
615
727
|
if (chand->method_params_table != NULL) {
|
616
728
|
grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
|
617
729
|
}
|
@@ -619,6 +731,7 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
619
731
|
grpc_pollset_set_destroy(exec_ctx, chand->interested_parties);
|
620
732
|
GRPC_COMBINER_UNREF(exec_ctx, chand->combiner, "client_channel");
|
621
733
|
gpr_mu_destroy(&chand->info_mu);
|
734
|
+
gpr_mu_destroy(&chand->external_connectivity_watcher_list_mu);
|
622
735
|
}
|
623
736
|
|
624
737
|
/*************************************************************************
|
@@ -631,7 +744,8 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx,
|
|
631
744
|
#define CANCELLED_CALL ((grpc_subchannel_call *)1)
|
632
745
|
|
633
746
|
typedef enum {
|
634
|
-
|
747
|
+
/* zero so that it can be default-initialized */
|
748
|
+
GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING = 0,
|
635
749
|
GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL
|
636
750
|
} subchannel_creation_phase;
|
637
751
|
|
@@ -652,20 +766,21 @@ typedef struct client_channel_call_data {
|
|
652
766
|
grpc_slice path; // Request path.
|
653
767
|
gpr_timespec call_start_time;
|
654
768
|
gpr_timespec deadline;
|
769
|
+
grpc_server_retry_throttle_data *retry_throttle_data;
|
655
770
|
method_parameters *method_params;
|
656
|
-
grpc_closure read_service_config;
|
657
771
|
|
658
772
|
grpc_error *cancel_error;
|
659
773
|
|
660
774
|
/** either 0 for no call, 1 for cancelled, or a pointer to a
|
661
775
|
grpc_subchannel_call */
|
662
776
|
gpr_atm subchannel_call;
|
777
|
+
gpr_arena *arena;
|
663
778
|
|
664
779
|
subchannel_creation_phase creation_phase;
|
665
780
|
grpc_connected_subchannel *connected_subchannel;
|
666
781
|
grpc_polling_entity *pollent;
|
667
782
|
|
668
|
-
|
783
|
+
grpc_transport_stream_op_batch **waiting_ops;
|
669
784
|
size_t waiting_ops_count;
|
670
785
|
size_t waiting_ops_capacity;
|
671
786
|
|
@@ -674,6 +789,9 @@ typedef struct client_channel_call_data {
|
|
674
789
|
grpc_call_stack *owning_call;
|
675
790
|
|
676
791
|
grpc_linked_mdelem lb_token_mdelem;
|
792
|
+
|
793
|
+
grpc_closure on_complete;
|
794
|
+
grpc_closure *original_on_complete;
|
677
795
|
} call_data;
|
678
796
|
|
679
797
|
grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
|
@@ -682,7 +800,8 @@ grpc_subchannel_call *grpc_client_channel_get_subchannel_call(
|
|
682
800
|
return scc == CANCELLED_CALL ? NULL : scc;
|
683
801
|
}
|
684
802
|
|
685
|
-
static void add_waiting_locked(call_data *calld,
|
803
|
+
static void add_waiting_locked(call_data *calld,
|
804
|
+
grpc_transport_stream_op_batch *op) {
|
686
805
|
GPR_TIMER_BEGIN("add_waiting_locked", 0);
|
687
806
|
if (calld->waiting_ops_count == calld->waiting_ops_capacity) {
|
688
807
|
calld->waiting_ops_capacity = GPR_MAX(3, 2 * calld->waiting_ops_capacity);
|
@@ -698,7 +817,7 @@ static void fail_locked(grpc_exec_ctx *exec_ctx, call_data *calld,
|
|
698
817
|
grpc_error *error) {
|
699
818
|
size_t i;
|
700
819
|
for (i = 0; i < calld->waiting_ops_count; i++) {
|
701
|
-
|
820
|
+
grpc_transport_stream_op_batch_finish_with_failure(
|
702
821
|
exec_ctx, calld->waiting_ops[i], GRPC_ERROR_REF(error));
|
703
822
|
}
|
704
823
|
calld->waiting_ops_count = 0;
|
@@ -711,7 +830,7 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
|
|
711
830
|
}
|
712
831
|
|
713
832
|
grpc_subchannel_call *call = GET_CALL(calld);
|
714
|
-
|
833
|
+
grpc_transport_stream_op_batch **ops = calld->waiting_ops;
|
715
834
|
size_t nops = calld->waiting_ops_count;
|
716
835
|
if (call == CANCELLED_CALL) {
|
717
836
|
fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED);
|
@@ -726,6 +845,51 @@ static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
|
|
726
845
|
gpr_free(ops);
|
727
846
|
}
|
728
847
|
|
848
|
+
// Sets calld->method_params and calld->retry_throttle_data.
|
849
|
+
// If the method params specify a timeout, populates
|
850
|
+
// *per_method_deadline and returns true.
|
851
|
+
static bool set_call_method_params_from_service_config_locked(
|
852
|
+
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
|
853
|
+
gpr_timespec *per_method_deadline) {
|
854
|
+
channel_data *chand = elem->channel_data;
|
855
|
+
call_data *calld = elem->call_data;
|
856
|
+
if (chand->retry_throttle_data != NULL) {
|
857
|
+
calld->retry_throttle_data =
|
858
|
+
grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
|
859
|
+
}
|
860
|
+
if (chand->method_params_table != NULL) {
|
861
|
+
calld->method_params = grpc_method_config_table_get(
|
862
|
+
exec_ctx, chand->method_params_table, calld->path);
|
863
|
+
if (calld->method_params != NULL) {
|
864
|
+
method_parameters_ref(calld->method_params);
|
865
|
+
if (gpr_time_cmp(calld->method_params->timeout,
|
866
|
+
gpr_time_0(GPR_TIMESPAN)) != 0) {
|
867
|
+
*per_method_deadline =
|
868
|
+
gpr_time_add(calld->call_start_time, calld->method_params->timeout);
|
869
|
+
return true;
|
870
|
+
}
|
871
|
+
}
|
872
|
+
}
|
873
|
+
return false;
|
874
|
+
}
|
875
|
+
|
876
|
+
static void apply_final_configuration_locked(grpc_exec_ctx *exec_ctx,
|
877
|
+
grpc_call_element *elem) {
|
878
|
+
/* apply service-config level configuration to the call (now that we're
|
879
|
+
* certain it exists) */
|
880
|
+
call_data *calld = elem->call_data;
|
881
|
+
gpr_timespec per_method_deadline;
|
882
|
+
if (set_call_method_params_from_service_config_locked(exec_ctx, elem,
|
883
|
+
&per_method_deadline)) {
|
884
|
+
// If the deadline from the service config is shorter than the one
|
885
|
+
// from the client API, reset the deadline timer.
|
886
|
+
if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
|
887
|
+
calld->deadline = per_method_deadline;
|
888
|
+
grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
|
889
|
+
}
|
890
|
+
}
|
891
|
+
}
|
892
|
+
|
729
893
|
static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
730
894
|
grpc_error *error) {
|
731
895
|
grpc_call_element *elem = arg;
|
@@ -738,12 +902,14 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
738
902
|
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
|
739
903
|
if (calld->connected_subchannel == NULL) {
|
740
904
|
gpr_atm_no_barrier_store(&calld->subchannel_call, 1);
|
741
|
-
fail_locked(exec_ctx, calld,
|
742
|
-
|
905
|
+
fail_locked(exec_ctx, calld,
|
906
|
+
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
907
|
+
"Failed to create subchannel", &error, 1));
|
743
908
|
} else if (GET_CALL(calld) == CANCELLED_CALL) {
|
744
909
|
/* already cancelled before subchannel became ready */
|
745
|
-
grpc_error *cancellation_error =
|
746
|
-
|
910
|
+
grpc_error *cancellation_error =
|
911
|
+
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
912
|
+
"Cancelled before creating subchannel", &error, 1);
|
747
913
|
/* if due to deadline, attach the deadline exceeded status to the error */
|
748
914
|
if (gpr_time_cmp(calld->deadline, gpr_now(GPR_CLOCK_MONOTONIC)) < 0) {
|
749
915
|
cancellation_error =
|
@@ -754,17 +920,22 @@ static void subchannel_ready_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
754
920
|
} else {
|
755
921
|
/* Create call on subchannel. */
|
756
922
|
grpc_subchannel_call *subchannel_call = NULL;
|
923
|
+
const grpc_connected_subchannel_call_args call_args = {
|
924
|
+
.pollent = calld->pollent,
|
925
|
+
.path = calld->path,
|
926
|
+
.start_time = calld->call_start_time,
|
927
|
+
.deadline = calld->deadline,
|
928
|
+
.arena = calld->arena};
|
757
929
|
grpc_error *new_error = grpc_connected_subchannel_create_call(
|
758
|
-
exec_ctx, calld->connected_subchannel,
|
759
|
-
|
930
|
+
exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
|
931
|
+
gpr_atm_rel_store(&calld->subchannel_call,
|
932
|
+
(gpr_atm)(uintptr_t)subchannel_call);
|
760
933
|
if (new_error != GRPC_ERROR_NONE) {
|
761
934
|
new_error = grpc_error_add_child(new_error, error);
|
762
|
-
subchannel_call = CANCELLED_CALL;
|
763
935
|
fail_locked(exec_ctx, calld, new_error);
|
936
|
+
} else {
|
937
|
+
retry_waiting_locked(exec_ctx, calld);
|
764
938
|
}
|
765
|
-
gpr_atm_rel_store(&calld->subchannel_call,
|
766
|
-
(gpr_atm)(uintptr_t)subchannel_call);
|
767
|
-
retry_waiting_locked(exec_ctx, calld);
|
768
939
|
}
|
769
940
|
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
|
770
941
|
}
|
@@ -840,9 +1011,9 @@ static bool pick_subchannel_locked(
|
|
840
1011
|
cpa = closure->cb_arg;
|
841
1012
|
if (cpa->connected_subchannel == connected_subchannel) {
|
842
1013
|
cpa->connected_subchannel = NULL;
|
843
|
-
grpc_closure_sched(
|
844
|
-
|
845
|
-
|
1014
|
+
grpc_closure_sched(exec_ctx, cpa->on_ready,
|
1015
|
+
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
1016
|
+
"Pick cancelled", &error, 1));
|
846
1017
|
}
|
847
1018
|
}
|
848
1019
|
GPR_TIMER_END("pick_subchannel", 0);
|
@@ -851,6 +1022,7 @@ static bool pick_subchannel_locked(
|
|
851
1022
|
}
|
852
1023
|
GPR_ASSERT(error == GRPC_ERROR_NONE);
|
853
1024
|
if (chand->lb_policy != NULL) {
|
1025
|
+
apply_final_configuration_locked(exec_ctx, elem);
|
854
1026
|
grpc_lb_policy *lb_policy = chand->lb_policy;
|
855
1027
|
GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
|
856
1028
|
// If the application explicitly set wait_for_ready, use that.
|
@@ -898,16 +1070,17 @@ static bool pick_subchannel_locked(
|
|
898
1070
|
grpc_closure_list_append(&chand->waiting_for_config_closures, &cpa->closure,
|
899
1071
|
GRPC_ERROR_NONE);
|
900
1072
|
} else {
|
901
|
-
grpc_closure_sched(exec_ctx, on_ready,
|
1073
|
+
grpc_closure_sched(exec_ctx, on_ready,
|
1074
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Disconnected"));
|
902
1075
|
}
|
903
1076
|
|
904
1077
|
GPR_TIMER_END("pick_subchannel", 0);
|
905
1078
|
return false;
|
906
1079
|
}
|
907
1080
|
|
908
|
-
static void
|
909
|
-
|
910
|
-
|
1081
|
+
static void start_transport_stream_op_batch_locked_inner(
|
1082
|
+
grpc_exec_ctx *exec_ctx, grpc_transport_stream_op_batch *op,
|
1083
|
+
grpc_call_element *elem) {
|
911
1084
|
channel_data *chand = elem->channel_data;
|
912
1085
|
call_data *calld = elem->call_data;
|
913
1086
|
grpc_subchannel_call *call;
|
@@ -915,7 +1088,7 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
|
|
915
1088
|
/* need to recheck that another thread hasn't set the call */
|
916
1089
|
call = GET_CALL(calld);
|
917
1090
|
if (call == CANCELLED_CALL) {
|
918
|
-
|
1091
|
+
grpc_transport_stream_op_batch_finish_with_failure(
|
919
1092
|
exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
|
920
1093
|
/* early out */
|
921
1094
|
return;
|
@@ -926,11 +1099,11 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
|
|
926
1099
|
return;
|
927
1100
|
}
|
928
1101
|
/* if this is a cancellation, then we can raise our cancelled flag */
|
929
|
-
if (op->
|
1102
|
+
if (op->cancel_stream) {
|
930
1103
|
if (!gpr_atm_rel_cas(&calld->subchannel_call, 0,
|
931
1104
|
(gpr_atm)(uintptr_t)CANCELLED_CALL)) {
|
932
1105
|
/* recurse to retry */
|
933
|
-
|
1106
|
+
start_transport_stream_op_batch_locked_inner(exec_ctx, op, elem);
|
934
1107
|
/* early out */
|
935
1108
|
return;
|
936
1109
|
} else {
|
@@ -939,27 +1112,29 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
|
|
939
1112
|
cancelled before any ops are passed down (e.g., if the deadline
|
940
1113
|
is in the past when the call starts), we can return the right
|
941
1114
|
error to the caller when the first op does get passed down. */
|
942
|
-
calld->cancel_error =
|
1115
|
+
calld->cancel_error =
|
1116
|
+
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error);
|
943
1117
|
switch (calld->creation_phase) {
|
944
1118
|
case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING:
|
945
|
-
fail_locked(exec_ctx, calld,
|
1119
|
+
fail_locked(exec_ctx, calld,
|
1120
|
+
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
|
946
1121
|
break;
|
947
1122
|
case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL:
|
948
|
-
pick_subchannel_locked(
|
949
|
-
|
950
|
-
|
1123
|
+
pick_subchannel_locked(
|
1124
|
+
exec_ctx, elem, NULL, 0, &calld->connected_subchannel, NULL,
|
1125
|
+
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
|
951
1126
|
break;
|
952
1127
|
}
|
953
|
-
|
954
|
-
exec_ctx, op,
|
1128
|
+
grpc_transport_stream_op_batch_finish_with_failure(
|
1129
|
+
exec_ctx, op,
|
1130
|
+
GRPC_ERROR_REF(op->payload->cancel_stream.cancel_error));
|
955
1131
|
/* early out */
|
956
1132
|
return;
|
957
1133
|
}
|
958
1134
|
}
|
959
1135
|
/* if we don't have a subchannel, try to get one */
|
960
1136
|
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
|
961
|
-
calld->connected_subchannel == NULL &&
|
962
|
-
op->send_initial_metadata != NULL) {
|
1137
|
+
calld->connected_subchannel == NULL && op->send_initial_metadata) {
|
963
1138
|
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
|
964
1139
|
grpc_closure_init(&calld->next_step, subchannel_ready_locked, elem,
|
965
1140
|
grpc_combiner_scheduler(chand->combiner, true));
|
@@ -967,10 +1142,11 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
|
|
967
1142
|
/* If a subchannel is not available immediately, the polling entity from
|
968
1143
|
call_data should be provided to channel_data's interested_parties, so
|
969
1144
|
that IO of the lb_policy and resolver could be done under it. */
|
970
|
-
if (pick_subchannel_locked(
|
971
|
-
|
972
|
-
|
973
|
-
|
1145
|
+
if (pick_subchannel_locked(
|
1146
|
+
exec_ctx, elem,
|
1147
|
+
op->payload->send_initial_metadata.send_initial_metadata,
|
1148
|
+
op->payload->send_initial_metadata.send_initial_metadata_flags,
|
1149
|
+
&calld->connected_subchannel, &calld->next_step, GRPC_ERROR_NONE)) {
|
974
1150
|
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
|
975
1151
|
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
|
976
1152
|
} else {
|
@@ -982,19 +1158,24 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
|
|
982
1158
|
if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING &&
|
983
1159
|
calld->connected_subchannel != NULL) {
|
984
1160
|
grpc_subchannel_call *subchannel_call = NULL;
|
1161
|
+
const grpc_connected_subchannel_call_args call_args = {
|
1162
|
+
.pollent = calld->pollent,
|
1163
|
+
.path = calld->path,
|
1164
|
+
.start_time = calld->call_start_time,
|
1165
|
+
.deadline = calld->deadline,
|
1166
|
+
.arena = calld->arena};
|
985
1167
|
grpc_error *error = grpc_connected_subchannel_create_call(
|
986
|
-
exec_ctx, calld->connected_subchannel,
|
987
|
-
|
1168
|
+
exec_ctx, calld->connected_subchannel, &call_args, &subchannel_call);
|
1169
|
+
gpr_atm_rel_store(&calld->subchannel_call,
|
1170
|
+
(gpr_atm)(uintptr_t)subchannel_call);
|
988
1171
|
if (error != GRPC_ERROR_NONE) {
|
989
|
-
subchannel_call = CANCELLED_CALL;
|
990
1172
|
fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error));
|
991
|
-
|
1173
|
+
grpc_transport_stream_op_batch_finish_with_failure(exec_ctx, op, error);
|
1174
|
+
} else {
|
1175
|
+
retry_waiting_locked(exec_ctx, calld);
|
1176
|
+
/* recurse to retry */
|
1177
|
+
start_transport_stream_op_batch_locked_inner(exec_ctx, op, elem);
|
992
1178
|
}
|
993
|
-
gpr_atm_rel_store(&calld->subchannel_call,
|
994
|
-
(gpr_atm)(uintptr_t)subchannel_call);
|
995
|
-
retry_waiting_locked(exec_ctx, calld);
|
996
|
-
/* recurse to retry */
|
997
|
-
start_transport_stream_op_locked_inner(exec_ctx, op, elem);
|
998
1179
|
/* early out */
|
999
1180
|
return;
|
1000
1181
|
}
|
@@ -1002,19 +1183,48 @@ static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
|
|
1002
1183
|
add_waiting_locked(calld, op);
|
1003
1184
|
}
|
1004
1185
|
|
1005
|
-
static void
|
1006
|
-
|
1007
|
-
|
1186
|
+
static void on_complete(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
|
1187
|
+
grpc_call_element *elem = arg;
|
1188
|
+
call_data *calld = elem->call_data;
|
1189
|
+
if (calld->retry_throttle_data != NULL) {
|
1190
|
+
if (error == GRPC_ERROR_NONE) {
|
1191
|
+
grpc_server_retry_throttle_data_record_success(
|
1192
|
+
calld->retry_throttle_data);
|
1193
|
+
} else {
|
1194
|
+
// TODO(roth): In a subsequent PR, check the return value here and
|
1195
|
+
// decide whether or not to retry. Note that we should only
|
1196
|
+
// record failures whose statuses match the configured retryable
|
1197
|
+
// or non-fatal status codes.
|
1198
|
+
grpc_server_retry_throttle_data_record_failure(
|
1199
|
+
calld->retry_throttle_data);
|
1200
|
+
}
|
1201
|
+
}
|
1202
|
+
grpc_closure_run(exec_ctx, calld->original_on_complete,
|
1203
|
+
GRPC_ERROR_REF(error));
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
static void start_transport_stream_op_batch_locked(grpc_exec_ctx *exec_ctx,
|
1207
|
+
void *arg,
|
1208
|
+
grpc_error *error_ignored) {
|
1209
|
+
GPR_TIMER_BEGIN("start_transport_stream_op_batch_locked", 0);
|
1008
1210
|
|
1009
|
-
|
1010
|
-
grpc_call_element *elem = op->handler_private.
|
1211
|
+
grpc_transport_stream_op_batch *op = arg;
|
1212
|
+
grpc_call_element *elem = op->handler_private.extra_arg;
|
1011
1213
|
call_data *calld = elem->call_data;
|
1012
1214
|
|
1013
|
-
|
1215
|
+
if (op->recv_trailing_metadata) {
|
1216
|
+
GPR_ASSERT(op->on_complete != NULL);
|
1217
|
+
calld->original_on_complete = op->on_complete;
|
1218
|
+
grpc_closure_init(&calld->on_complete, on_complete, elem,
|
1219
|
+
grpc_schedule_on_exec_ctx);
|
1220
|
+
op->on_complete = &calld->on_complete;
|
1221
|
+
}
|
1222
|
+
|
1223
|
+
start_transport_stream_op_batch_locked_inner(exec_ctx, op, elem);
|
1014
1224
|
|
1015
1225
|
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
|
1016
|
-
"
|
1017
|
-
GPR_TIMER_END("
|
1226
|
+
"start_transport_stream_op_batch");
|
1227
|
+
GPR_TIMER_END("start_transport_stream_op_batch_locked", 0);
|
1018
1228
|
}
|
1019
1229
|
|
1020
1230
|
/* The logic here is fairly complicated, due to (a) the fact that we
|
@@ -1025,149 +1235,55 @@ static void start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
|
1025
1235
|
We use double-checked locking to initially see if initialization has been
|
1026
1236
|
performed. If it has not, we acquire the combiner and perform initialization.
|
1027
1237
|
If it has, we proceed on the fast path. */
|
1028
|
-
static void
|
1029
|
-
|
1030
|
-
|
1238
|
+
static void cc_start_transport_stream_op_batch(
|
1239
|
+
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
|
1240
|
+
grpc_transport_stream_op_batch *op) {
|
1031
1241
|
call_data *calld = elem->call_data;
|
1032
1242
|
channel_data *chand = elem->channel_data;
|
1033
1243
|
GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
|
1034
|
-
|
1244
|
+
grpc_deadline_state_client_start_transport_stream_op_batch(exec_ctx, elem,
|
1245
|
+
op);
|
1035
1246
|
/* try to (atomically) get the call */
|
1036
1247
|
grpc_subchannel_call *call = GET_CALL(calld);
|
1037
|
-
GPR_TIMER_BEGIN("
|
1248
|
+
GPR_TIMER_BEGIN("cc_start_transport_stream_op_batch", 0);
|
1038
1249
|
if (call == CANCELLED_CALL) {
|
1039
|
-
|
1250
|
+
grpc_transport_stream_op_batch_finish_with_failure(
|
1040
1251
|
exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
|
1041
|
-
GPR_TIMER_END("
|
1252
|
+
GPR_TIMER_END("cc_start_transport_stream_op_batch", 0);
|
1042
1253
|
/* early out */
|
1043
1254
|
return;
|
1044
1255
|
}
|
1045
1256
|
if (call != NULL) {
|
1046
1257
|
grpc_subchannel_call_process_op(exec_ctx, call, op);
|
1047
|
-
GPR_TIMER_END("
|
1258
|
+
GPR_TIMER_END("cc_start_transport_stream_op_batch", 0);
|
1048
1259
|
/* early out */
|
1049
1260
|
return;
|
1050
1261
|
}
|
1051
1262
|
/* we failed; lock and figure out what to do */
|
1052
|
-
GRPC_CALL_STACK_REF(calld->owning_call, "
|
1053
|
-
op->handler_private.
|
1263
|
+
GRPC_CALL_STACK_REF(calld->owning_call, "start_transport_stream_op_batch");
|
1264
|
+
op->handler_private.extra_arg = elem;
|
1054
1265
|
grpc_closure_sched(
|
1055
1266
|
exec_ctx,
|
1056
1267
|
grpc_closure_init(&op->handler_private.closure,
|
1057
|
-
|
1268
|
+
start_transport_stream_op_batch_locked, op,
|
1058
1269
|
grpc_combiner_scheduler(chand->combiner, false)),
|
1059
1270
|
GRPC_ERROR_NONE);
|
1060
|
-
GPR_TIMER_END("
|
1061
|
-
}
|
1062
|
-
|
1063
|
-
// Sets calld->method_params.
|
1064
|
-
// If the method params specify a timeout, populates
|
1065
|
-
// *per_method_deadline and returns true.
|
1066
|
-
static bool set_call_method_params_from_service_config_locked(
|
1067
|
-
grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
|
1068
|
-
gpr_timespec *per_method_deadline) {
|
1069
|
-
channel_data *chand = elem->channel_data;
|
1070
|
-
call_data *calld = elem->call_data;
|
1071
|
-
if (chand->method_params_table != NULL) {
|
1072
|
-
calld->method_params = grpc_method_config_table_get(
|
1073
|
-
exec_ctx, chand->method_params_table, calld->path);
|
1074
|
-
if (calld->method_params != NULL) {
|
1075
|
-
method_parameters_ref(calld->method_params);
|
1076
|
-
if (gpr_time_cmp(calld->method_params->timeout,
|
1077
|
-
gpr_time_0(GPR_TIMESPAN)) != 0) {
|
1078
|
-
*per_method_deadline =
|
1079
|
-
gpr_time_add(calld->call_start_time, calld->method_params->timeout);
|
1080
|
-
return true;
|
1081
|
-
}
|
1082
|
-
}
|
1083
|
-
}
|
1084
|
-
return false;
|
1085
|
-
}
|
1086
|
-
|
1087
|
-
// Gets data from the service config. Invoked when the resolver returns
|
1088
|
-
// its initial result.
|
1089
|
-
static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
1090
|
-
grpc_error *error) {
|
1091
|
-
grpc_call_element *elem = arg;
|
1092
|
-
call_data *calld = elem->call_data;
|
1093
|
-
// If this is an error, there's no point in looking at the service config.
|
1094
|
-
if (error == GRPC_ERROR_NONE) {
|
1095
|
-
gpr_timespec per_method_deadline;
|
1096
|
-
if (set_call_method_params_from_service_config_locked(
|
1097
|
-
exec_ctx, elem, &per_method_deadline)) {
|
1098
|
-
// If the deadline from the service config is shorter than the one
|
1099
|
-
// from the client API, reset the deadline timer.
|
1100
|
-
if (gpr_time_cmp(per_method_deadline, calld->deadline) < 0) {
|
1101
|
-
calld->deadline = per_method_deadline;
|
1102
|
-
grpc_deadline_state_reset(exec_ctx, elem, calld->deadline);
|
1103
|
-
}
|
1104
|
-
}
|
1105
|
-
}
|
1106
|
-
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "read_service_config");
|
1107
|
-
}
|
1108
|
-
|
1109
|
-
static void initial_read_service_config_locked(grpc_exec_ctx *exec_ctx,
|
1110
|
-
void *arg,
|
1111
|
-
grpc_error *error_ignored) {
|
1112
|
-
grpc_call_element *elem = arg;
|
1113
|
-
channel_data *chand = elem->channel_data;
|
1114
|
-
call_data *calld = elem->call_data;
|
1115
|
-
// If the resolver has already returned results, then we can access
|
1116
|
-
// the service config parameters immediately. Otherwise, we need to
|
1117
|
-
// defer that work until the resolver returns an initial result.
|
1118
|
-
if (chand->lb_policy != NULL) {
|
1119
|
-
// We already have a resolver result, so check for service config.
|
1120
|
-
gpr_timespec per_method_deadline;
|
1121
|
-
if (set_call_method_params_from_service_config_locked(
|
1122
|
-
exec_ctx, elem, &per_method_deadline)) {
|
1123
|
-
calld->deadline = gpr_time_min(calld->deadline, per_method_deadline);
|
1124
|
-
}
|
1125
|
-
} else {
|
1126
|
-
// We don't yet have a resolver result, so register a callback to
|
1127
|
-
// get the service config data once the resolver returns.
|
1128
|
-
// Take a reference to the call stack to be owned by the callback.
|
1129
|
-
GRPC_CALL_STACK_REF(calld->owning_call, "read_service_config");
|
1130
|
-
grpc_closure_init(&calld->read_service_config, read_service_config_locked,
|
1131
|
-
elem, grpc_combiner_scheduler(chand->combiner, false));
|
1132
|
-
grpc_closure_list_append(&chand->waiting_for_config_closures,
|
1133
|
-
&calld->read_service_config, GRPC_ERROR_NONE);
|
1134
|
-
}
|
1135
|
-
// Start the deadline timer with the current deadline value. If we
|
1136
|
-
// do not yet have service config data, then the timer may be reset
|
1137
|
-
// later.
|
1138
|
-
grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
|
1139
|
-
GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
|
1140
|
-
"initial_read_service_config");
|
1271
|
+
GPR_TIMER_END("cc_start_transport_stream_op_batch", 0);
|
1141
1272
|
}
|
1142
1273
|
|
1143
1274
|
/* Constructor for call_data */
|
1144
1275
|
static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
|
1145
1276
|
grpc_call_element *elem,
|
1146
1277
|
const grpc_call_element_args *args) {
|
1147
|
-
channel_data *chand = elem->channel_data;
|
1148
1278
|
call_data *calld = elem->call_data;
|
1149
1279
|
// Initialize data members.
|
1150
1280
|
grpc_deadline_state_init(exec_ctx, elem, args->call_stack);
|
1151
1281
|
calld->path = grpc_slice_ref_internal(args->path);
|
1152
1282
|
calld->call_start_time = args->start_time;
|
1153
1283
|
calld->deadline = gpr_convert_clock_type(args->deadline, GPR_CLOCK_MONOTONIC);
|
1154
|
-
calld->method_params = NULL;
|
1155
|
-
calld->cancel_error = GRPC_ERROR_NONE;
|
1156
|
-
gpr_atm_rel_store(&calld->subchannel_call, 0);
|
1157
|
-
calld->connected_subchannel = NULL;
|
1158
|
-
calld->waiting_ops = NULL;
|
1159
|
-
calld->waiting_ops_count = 0;
|
1160
|
-
calld->waiting_ops_capacity = 0;
|
1161
|
-
calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
|
1162
1284
|
calld->owning_call = args->call_stack;
|
1163
|
-
calld->
|
1164
|
-
|
1165
|
-
grpc_closure_sched(
|
1166
|
-
exec_ctx,
|
1167
|
-
grpc_closure_init(&calld->read_service_config,
|
1168
|
-
initial_read_service_config_locked, elem,
|
1169
|
-
grpc_combiner_scheduler(chand->combiner, false)),
|
1170
|
-
GRPC_ERROR_NONE);
|
1285
|
+
calld->arena = args->arena;
|
1286
|
+
grpc_deadline_state_start(exec_ctx, elem, calld->deadline);
|
1171
1287
|
return GRPC_ERROR_NONE;
|
1172
1288
|
}
|
1173
1289
|
|
@@ -1175,7 +1291,7 @@ static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
|
|
1175
1291
|
static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
1176
1292
|
grpc_call_element *elem,
|
1177
1293
|
const grpc_call_final_info *final_info,
|
1178
|
-
|
1294
|
+
grpc_closure *then_schedule_closure) {
|
1179
1295
|
call_data *calld = elem->call_data;
|
1180
1296
|
grpc_deadline_state_destroy(exec_ctx, elem);
|
1181
1297
|
grpc_slice_unref_internal(exec_ctx, calld->path);
|
@@ -1185,6 +1301,8 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
|
1185
1301
|
GRPC_ERROR_UNREF(calld->cancel_error);
|
1186
1302
|
grpc_subchannel_call *call = GET_CALL(calld);
|
1187
1303
|
if (call != NULL && call != CANCELLED_CALL) {
|
1304
|
+
grpc_subchannel_call_set_cleanup_closure(call, then_schedule_closure);
|
1305
|
+
then_schedule_closure = NULL;
|
1188
1306
|
GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
|
1189
1307
|
}
|
1190
1308
|
GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
|
@@ -1194,7 +1312,7 @@ static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx,
|
|
1194
1312
|
"picked");
|
1195
1313
|
}
|
1196
1314
|
gpr_free(calld->waiting_ops);
|
1197
|
-
|
1315
|
+
grpc_closure_sched(exec_ctx, then_schedule_closure, GRPC_ERROR_NONE);
|
1198
1316
|
}
|
1199
1317
|
|
1200
1318
|
static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
|
@@ -1209,7 +1327,7 @@ static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
|
|
1209
1327
|
*/
|
1210
1328
|
|
1211
1329
|
const grpc_channel_filter grpc_client_channel_filter = {
|
1212
|
-
|
1330
|
+
cc_start_transport_stream_op_batch,
|
1213
1331
|
cc_start_transport_op,
|
1214
1332
|
sizeof(call_data),
|
1215
1333
|
cc_init_call_elem,
|
@@ -1257,14 +1375,79 @@ grpc_connectivity_state grpc_client_channel_check_connectivity_state(
|
|
1257
1375
|
return out;
|
1258
1376
|
}
|
1259
1377
|
|
1260
|
-
typedef struct {
|
1378
|
+
typedef struct external_connectivity_watcher {
|
1261
1379
|
channel_data *chand;
|
1262
1380
|
grpc_pollset *pollset;
|
1263
1381
|
grpc_closure *on_complete;
|
1382
|
+
grpc_closure *watcher_timer_init;
|
1264
1383
|
grpc_connectivity_state *state;
|
1265
1384
|
grpc_closure my_closure;
|
1385
|
+
struct external_connectivity_watcher *next;
|
1266
1386
|
} external_connectivity_watcher;
|
1267
1387
|
|
1388
|
+
static external_connectivity_watcher *lookup_external_connectivity_watcher(
|
1389
|
+
channel_data *chand, grpc_closure *on_complete) {
|
1390
|
+
gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
|
1391
|
+
external_connectivity_watcher *w =
|
1392
|
+
chand->external_connectivity_watcher_list_head;
|
1393
|
+
while (w != NULL && w->on_complete != on_complete) {
|
1394
|
+
w = w->next;
|
1395
|
+
}
|
1396
|
+
gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
|
1397
|
+
return w;
|
1398
|
+
}
|
1399
|
+
|
1400
|
+
static void external_connectivity_watcher_list_append(
|
1401
|
+
channel_data *chand, external_connectivity_watcher *w) {
|
1402
|
+
GPR_ASSERT(!lookup_external_connectivity_watcher(chand, w->on_complete));
|
1403
|
+
|
1404
|
+
gpr_mu_lock(&w->chand->external_connectivity_watcher_list_mu);
|
1405
|
+
GPR_ASSERT(!w->next);
|
1406
|
+
w->next = chand->external_connectivity_watcher_list_head;
|
1407
|
+
chand->external_connectivity_watcher_list_head = w;
|
1408
|
+
gpr_mu_unlock(&w->chand->external_connectivity_watcher_list_mu);
|
1409
|
+
}
|
1410
|
+
|
1411
|
+
static void external_connectivity_watcher_list_remove(
|
1412
|
+
channel_data *chand, external_connectivity_watcher *too_remove) {
|
1413
|
+
GPR_ASSERT(
|
1414
|
+
lookup_external_connectivity_watcher(chand, too_remove->on_complete));
|
1415
|
+
gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
|
1416
|
+
if (too_remove == chand->external_connectivity_watcher_list_head) {
|
1417
|
+
chand->external_connectivity_watcher_list_head = too_remove->next;
|
1418
|
+
gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
|
1419
|
+
return;
|
1420
|
+
}
|
1421
|
+
external_connectivity_watcher *w =
|
1422
|
+
chand->external_connectivity_watcher_list_head;
|
1423
|
+
while (w != NULL) {
|
1424
|
+
if (w->next == too_remove) {
|
1425
|
+
w->next = w->next->next;
|
1426
|
+
gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
|
1427
|
+
return;
|
1428
|
+
}
|
1429
|
+
w = w->next;
|
1430
|
+
}
|
1431
|
+
GPR_UNREACHABLE_CODE(return );
|
1432
|
+
}
|
1433
|
+
|
1434
|
+
int grpc_client_channel_num_external_connectivity_watchers(
|
1435
|
+
grpc_channel_element *elem) {
|
1436
|
+
channel_data *chand = elem->channel_data;
|
1437
|
+
int count = 0;
|
1438
|
+
|
1439
|
+
gpr_mu_lock(&chand->external_connectivity_watcher_list_mu);
|
1440
|
+
external_connectivity_watcher *w =
|
1441
|
+
chand->external_connectivity_watcher_list_head;
|
1442
|
+
while (w != NULL) {
|
1443
|
+
count++;
|
1444
|
+
w = w->next;
|
1445
|
+
}
|
1446
|
+
gpr_mu_unlock(&chand->external_connectivity_watcher_list_mu);
|
1447
|
+
|
1448
|
+
return count;
|
1449
|
+
}
|
1450
|
+
|
1268
1451
|
static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg,
|
1269
1452
|
grpc_error *error) {
|
1270
1453
|
external_connectivity_watcher *w = arg;
|
@@ -1273,6 +1456,7 @@ static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg,
|
|
1273
1456
|
w->pollset);
|
1274
1457
|
GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack,
|
1275
1458
|
"external_connectivity_watcher");
|
1459
|
+
external_connectivity_watcher_list_remove(w->chand, w);
|
1276
1460
|
gpr_free(w);
|
1277
1461
|
grpc_closure_run(exec_ctx, follow_up, GRPC_ERROR_REF(error));
|
1278
1462
|
}
|
@@ -1280,21 +1464,42 @@ static void on_external_watch_complete(grpc_exec_ctx *exec_ctx, void *arg,
|
|
1280
1464
|
static void watch_connectivity_state_locked(grpc_exec_ctx *exec_ctx, void *arg,
|
1281
1465
|
grpc_error *error_ignored) {
|
1282
1466
|
external_connectivity_watcher *w = arg;
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1467
|
+
external_connectivity_watcher *found = NULL;
|
1468
|
+
if (w->state != NULL) {
|
1469
|
+
external_connectivity_watcher_list_append(w->chand, w);
|
1470
|
+
grpc_closure_run(exec_ctx, w->watcher_timer_init, GRPC_ERROR_NONE);
|
1471
|
+
grpc_closure_init(&w->my_closure, on_external_watch_complete, w,
|
1472
|
+
grpc_schedule_on_exec_ctx);
|
1473
|
+
grpc_connectivity_state_notify_on_state_change(
|
1474
|
+
exec_ctx, &w->chand->state_tracker, w->state, &w->my_closure);
|
1475
|
+
} else {
|
1476
|
+
GPR_ASSERT(w->watcher_timer_init == NULL);
|
1477
|
+
found = lookup_external_connectivity_watcher(w->chand, w->on_complete);
|
1478
|
+
if (found) {
|
1479
|
+
GPR_ASSERT(found->on_complete == w->on_complete);
|
1480
|
+
grpc_connectivity_state_notify_on_state_change(
|
1481
|
+
exec_ctx, &found->chand->state_tracker, NULL, &found->my_closure);
|
1482
|
+
}
|
1483
|
+
grpc_pollset_set_del_pollset(exec_ctx, w->chand->interested_parties,
|
1484
|
+
w->pollset);
|
1485
|
+
GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack,
|
1486
|
+
"external_connectivity_watcher");
|
1487
|
+
gpr_free(w);
|
1488
|
+
}
|
1287
1489
|
}
|
1288
1490
|
|
1289
1491
|
void grpc_client_channel_watch_connectivity_state(
|
1290
1492
|
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
|
1291
|
-
grpc_connectivity_state *state, grpc_closure *on_complete
|
1493
|
+
grpc_connectivity_state *state, grpc_closure *on_complete,
|
1494
|
+
grpc_closure *watcher_timer_init) {
|
1292
1495
|
channel_data *chand = elem->channel_data;
|
1293
|
-
external_connectivity_watcher *w =
|
1496
|
+
external_connectivity_watcher *w = gpr_zalloc(sizeof(*w));
|
1294
1497
|
w->chand = chand;
|
1295
1498
|
w->pollset = pollset;
|
1296
1499
|
w->on_complete = on_complete;
|
1297
1500
|
w->state = state;
|
1501
|
+
w->watcher_timer_init = watcher_timer_init;
|
1502
|
+
|
1298
1503
|
grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
|
1299
1504
|
GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
|
1300
1505
|
"external_connectivity_watcher");
|