grpc 1.31.1 → 1.32.0.pre1
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 +595 -15723
- data/include/grpc/grpc_security.h +31 -14
- data/include/grpc/impl/codegen/README.md +22 -0
- data/include/grpc/impl/codegen/port_platform.h +6 -1
- data/src/core/ext/filters/client_channel/backup_poller.cc +3 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +64 -20
- data/src/core/ext/filters/client_channel/client_channel.h +1 -1
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +0 -3
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +6 -1
- data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +2 -3
- data/src/core/ext/filters/client_channel/lb_policy.h +2 -0
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +6 -4
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +20 -13
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +0 -13
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h +0 -3
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +1 -37
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +19 -13
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +29 -10
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +5 -4
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +20 -9
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +18 -12
- data/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc +22 -14
- data/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc +18 -9
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +54 -56
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +3 -3
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +363 -14
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +0 -1
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +5 -4
- data/src/core/ext/filters/client_channel/server_address.cc +40 -7
- data/src/core/ext/filters/client_channel/server_address.h +42 -4
- data/src/core/ext/filters/client_channel/subchannel.cc +64 -23
- data/src/core/ext/filters/client_channel/subchannel.h +16 -4
- data/src/core/ext/filters/max_age/max_age_filter.cc +2 -1
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +87 -31
- data/src/core/ext/transport/chttp2/client/chttp2_connector.h +18 -1
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +10 -35
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +19 -25
- data/src/core/ext/transport/chttp2/server/chttp2_server.h +2 -1
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc +2 -2
- data/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc +6 -6
- data/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc +3 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +239 -277
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/internal.h +5 -1
- data/src/core/ext/transport/chttp2/transport/parsing.cc +1 -28
- data/src/core/ext/transport/chttp2/transport/writing.cc +6 -5
- data/src/core/ext/transport/inproc/inproc_transport.cc +12 -12
- data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c +224 -0
- data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h +700 -0
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.c +74 -0
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/circuit_breaker.upb.h +226 -0
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +380 -0
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +1378 -0
- data/src/core/ext/upb-generated/envoy/{api/v2/cluster → config/cluster/v3}/filter.upb.c +8 -8
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/filter.upb.h +69 -0
- data/src/core/ext/upb-generated/envoy/{api/v2/cluster → config/cluster/v3}/outlier_detection.upb.c +8 -8
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/outlier_detection.upb.h +323 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c +112 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h +334 -0
- data/src/core/ext/upb-generated/envoy/{api/v2/core → config/core/v3}/backoff.upb.c +8 -8
- data/src/core/ext/upb-generated/envoy/config/core/v3/backoff.upb.h +79 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +309 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.h +869 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c +96 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h +328 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.c +34 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/event_service_config.upb.h +71 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c +195 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h +634 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.c +170 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/health_check.upb.h +684 -0
- data/src/core/ext/upb-generated/envoy/{api/v2/core → config/core/v3}/http_uri.upb.c +8 -8
- data/src/core/ext/upb-generated/envoy/config/core/v3/http_uri.upb.h +80 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +152 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +536 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.c +28 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/proxy_protocol.upb.h +58 -0
- data/src/core/ext/upb-generated/envoy/{api/v2/core → config/core/v3}/socket_option.upb.c +6 -6
- data/src/core/ext/upb-generated/envoy/config/core/v3/socket_option.upb.h +88 -0
- data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.c +91 -0
- data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint.upb.h +220 -0
- data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.c +91 -0
- data/src/core/ext/upb-generated/envoy/config/endpoint/v3/endpoint_components.upb.h +273 -0
- data/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.c +112 -0
- data/src/core/ext/upb-generated/envoy/config/endpoint/v3/load_report.upb.h +332 -0
- data/src/core/ext/upb-generated/envoy/config/listener/{v2 → v3}/api_listener.upb.c +8 -8
- data/src/core/ext/upb-generated/envoy/config/listener/v3/api_listener.upb.h +65 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +108 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +401 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +138 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +490 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.c +41 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/udp_listener_config.upb.h +94 -0
- data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +174 -0
- data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h +599 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.c +63 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route.upb.h +204 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +773 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +2855 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c +59 -0
- data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h +135 -0
- data/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c +50 -0
- data/src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h +108 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +312 -0
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +1125 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c +20 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h +34 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +111 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +401 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c +72 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +198 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c +105 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +388 -0
- data/src/core/ext/upb-generated/envoy/{api/v2 → service/cluster/v3}/cds.upb.c +5 -6
- data/src/core/ext/upb-generated/envoy/service/cluster/v3/cds.upb.h +49 -0
- data/src/core/ext/upb-generated/envoy/service/discovery/{v2 → v3}/ads.upb.c +5 -4
- data/src/core/ext/upb-generated/envoy/service/discovery/v3/ads.upb.h +49 -0
- data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c +129 -0
- data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h +386 -0
- data/src/core/ext/upb-generated/envoy/{api/v2 → service/endpoint/v3}/eds.upb.c +5 -6
- data/src/core/ext/upb-generated/envoy/service/endpoint/v3/eds.upb.h +49 -0
- data/src/core/ext/upb-generated/envoy/{api/v2 → service/listener/v3}/lds.upb.c +5 -6
- data/src/core/ext/upb-generated/envoy/service/listener/v3/lds.upb.h +49 -0
- data/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.c +55 -0
- data/src/core/ext/upb-generated/envoy/service/load_stats/v3/lrs.upb.h +136 -0
- data/src/core/ext/upb-generated/envoy/{api/v2 → service/route/v3}/rds.upb.c +5 -6
- data/src/core/ext/upb-generated/envoy/service/route/v3/rds.upb.h +49 -0
- data/src/core/ext/upb-generated/envoy/{api/v2 → service/route/v3}/srds.upb.c +5 -6
- data/src/core/ext/upb-generated/envoy/service/route/v3/srds.upb.h +49 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.c +47 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/metadata.upb.h +114 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.c +35 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/number.upb.h +77 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.c +34 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/path.upb.h +71 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.c +64 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/regex.upb.h +145 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c +53 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h +127 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.c +63 -0
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/value.upb.h +188 -0
- data/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.c +88 -0
- data/src/core/ext/upb-generated/envoy/type/metadata/v3/metadata.upb.h +258 -0
- data/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.c +90 -0
- data/src/core/ext/upb-generated/envoy/type/tracing/v3/custom_tag.upb.h +250 -0
- data/src/core/ext/upb-generated/envoy/type/{http.upb.c → v3/http.upb.c} +2 -2
- data/src/core/ext/upb-generated/envoy/type/{http.upb.h → v3/http.upb.h} +8 -8
- data/src/core/ext/upb-generated/envoy/type/{percent.upb.c → v3/percent.upb.c} +9 -8
- data/src/core/ext/upb-generated/envoy/type/v3/percent.upb.h +86 -0
- data/src/core/ext/upb-generated/envoy/type/{range.upb.c → v3/range.upb.c} +12 -11
- data/src/core/ext/upb-generated/envoy/type/v3/range.upb.h +111 -0
- data/src/core/ext/upb-generated/envoy/type/{semantic_version.upb.c → v3/semantic_version.upb.c} +6 -5
- data/src/core/ext/upb-generated/envoy/type/v3/semantic_version.upb.h +61 -0
- data/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.c +234 -0
- data/src/core/ext/upb-generated/google/api/expr/v1alpha1/syntax.upb.h +759 -0
- data/src/core/ext/upb-generated/google/protobuf/descriptor.upb.c +36 -36
- data/src/core/ext/upb-generated/google/protobuf/struct.upb.h +1 -1
- data/src/core/ext/upb-generated/udpa/annotations/versioning.upb.c +27 -0
- data/src/core/ext/upb-generated/udpa/annotations/versioning.upb.h +53 -0
- data/src/core/ext/upb-generated/validate/validate.upb.c +11 -11
- data/src/core/ext/upb-generated/validate/validate.upb.h +1 -1
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_api.cc +1045 -767
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_api.h +114 -99
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_bootstrap.cc +44 -2
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_bootstrap.h +8 -3
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_channel.h +4 -4
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_channel_args.h +3 -3
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_channel_secure.cc +2 -5
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_client.cc +85 -417
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_client.h +12 -45
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_client_stats.cc +2 -2
- data/src/core/ext/{filters/client_channel/xds → xds}/xds_client_stats.h +3 -3
- data/src/core/lib/channel/channelz.cc +14 -15
- data/src/core/lib/channel/channelz.h +1 -1
- data/src/core/lib/channel/channelz_registry.cc +3 -1
- data/src/core/lib/gpr/sync_posix.cc +2 -8
- data/src/core/lib/iomgr/endpoint.cc +5 -1
- data/src/core/lib/iomgr/endpoint.h +7 -3
- data/src/core/lib/iomgr/endpoint_cfstream.cc +32 -11
- data/src/core/lib/iomgr/ev_posix.cc +0 -2
- data/src/core/lib/iomgr/iomgr.cc +0 -10
- data/src/core/lib/iomgr/iomgr.h +0 -10
- data/src/core/{ext/filters/client_channel → lib/iomgr}/parse_address.cc +1 -1
- data/src/core/{ext/filters/client_channel → lib/iomgr}/parse_address.h +3 -3
- data/src/core/lib/iomgr/sockaddr_utils.cc +2 -1
- data/src/core/lib/iomgr/sockaddr_utils.h +2 -1
- data/src/core/lib/iomgr/tcp_custom.cc +32 -16
- data/src/core/lib/iomgr/tcp_posix.cc +31 -13
- data/src/core/lib/iomgr/tcp_windows.cc +26 -10
- data/src/core/lib/security/authorization/authorization_engine.cc +177 -0
- data/src/core/lib/security/authorization/authorization_engine.h +84 -0
- data/src/core/lib/security/authorization/evaluate_args.cc +153 -0
- data/src/core/lib/security/authorization/evaluate_args.h +59 -0
- data/src/core/lib/security/authorization/mock_cel/activation.h +57 -0
- data/src/core/lib/security/authorization/mock_cel/cel_expr_builder_factory.h +42 -0
- data/src/core/lib/security/authorization/mock_cel/cel_expression.h +68 -0
- data/src/core/lib/security/authorization/mock_cel/cel_value.h +93 -0
- data/src/core/lib/security/authorization/mock_cel/evaluator_core.h +67 -0
- data/src/core/lib/security/authorization/mock_cel/flat_expr_builder.h +56 -0
- data/src/core/lib/security/authorization/mock_cel/statusor.h +50 -0
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +56 -38
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +1 -2
- data/src/core/lib/security/transport/secure_endpoint.cc +7 -1
- data/src/core/lib/surface/call.cc +12 -12
- data/src/core/lib/surface/call.h +2 -1
- data/src/core/lib/surface/channel.cc +28 -20
- data/src/core/lib/surface/channel.h +12 -2
- data/src/core/lib/surface/completion_queue.cc +10 -272
- data/src/core/lib/surface/completion_queue.h +0 -8
- data/src/core/lib/surface/init.cc +1 -3
- data/src/core/lib/surface/server.cc +1066 -1244
- data/src/core/lib/surface/server.h +363 -87
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/authority_override.cc +38 -0
- data/src/core/lib/transport/authority_override.h +32 -0
- data/src/core/lib/transport/connectivity_state.cc +18 -13
- data/src/core/lib/transport/connectivity_state.h +18 -6
- data/src/core/lib/transport/error_utils.cc +13 -0
- data/src/core/lib/transport/error_utils.h +6 -0
- data/src/core/lib/transport/static_metadata.cc +295 -276
- data/src/core/lib/transport/static_metadata.h +80 -73
- data/src/core/lib/transport/transport.h +7 -0
- data/src/core/lib/uri/uri_parser.cc +23 -21
- data/src/core/lib/uri/uri_parser.h +3 -1
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +22 -0
- data/src/core/tsi/ssl_transport_security.cc +3 -9
- data/src/ruby/ext/grpc/rb_channel_credentials.c +9 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +4 -4
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/spec/channel_credentials_spec.rb +10 -0
- data/src/ruby/spec/generic/active_call_spec.rb +19 -8
- data/third_party/abseil-cpp/absl/algorithm/container.h +1727 -0
- data/third_party/abseil-cpp/absl/base/internal/direct_mmap.h +161 -0
- data/third_party/abseil-cpp/absl/base/internal/exponential_biased.cc +93 -0
- data/third_party/abseil-cpp/absl/base/internal/exponential_biased.h +130 -0
- data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +620 -0
- data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h +126 -0
- data/third_party/abseil-cpp/absl/container/fixed_array.h +515 -0
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +503 -0
- data/third_party/abseil-cpp/absl/container/internal/common.h +202 -0
- data/third_party/abseil-cpp/absl/container/internal/container_memory.h +440 -0
- data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +146 -0
- data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +191 -0
- data/third_party/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h +85 -0
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +269 -0
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +297 -0
- data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc +30 -0
- data/third_party/abseil-cpp/absl/container/internal/have_sse.h +49 -0
- data/third_party/abseil-cpp/absl/container/internal/layout.h +741 -0
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +48 -0
- data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +1882 -0
- data/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc +138 -0
- data/third_party/abseil-cpp/absl/debugging/internal/address_is_readable.h +32 -0
- data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +1895 -0
- data/third_party/abseil-cpp/absl/debugging/internal/demangle.h +71 -0
- data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc +382 -0
- data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +134 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +192 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_arm-inl.inc +125 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +70 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +99 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +248 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_unimplemented-inl.inc +24 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_win32-inl.inc +85 -0
- data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +346 -0
- data/third_party/abseil-cpp/absl/debugging/internal/symbolize.h +128 -0
- data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +194 -0
- data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.h +158 -0
- data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +140 -0
- data/third_party/abseil-cpp/absl/debugging/stacktrace.h +231 -0
- data/third_party/abseil-cpp/absl/debugging/symbolize.cc +25 -0
- data/third_party/abseil-cpp/absl/debugging/symbolize.h +99 -0
- data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +1480 -0
- data/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +40 -0
- data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +81 -0
- data/third_party/abseil-cpp/absl/functional/function_ref.h +139 -0
- data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +106 -0
- data/third_party/abseil-cpp/absl/hash/hash.h +324 -0
- data/third_party/abseil-cpp/absl/hash/internal/city.cc +346 -0
- data/third_party/abseil-cpp/absl/hash/internal/city.h +96 -0
- data/third_party/abseil-cpp/absl/hash/internal/hash.cc +55 -0
- data/third_party/abseil-cpp/absl/hash/internal/hash.h +988 -0
- data/third_party/abseil-cpp/absl/status/status.cc +447 -0
- data/third_party/abseil-cpp/absl/status/status.h +428 -0
- data/third_party/abseil-cpp/absl/status/status_payload_printer.cc +43 -0
- data/third_party/abseil-cpp/absl/status/status_payload_printer.h +51 -0
- data/third_party/abseil-cpp/absl/strings/cord.cc +2019 -0
- data/third_party/abseil-cpp/absl/strings/cord.h +1121 -0
- data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +151 -0
- data/third_party/abseil-cpp/absl/synchronization/barrier.cc +52 -0
- data/third_party/abseil-cpp/absl/synchronization/barrier.h +79 -0
- data/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc +57 -0
- data/third_party/abseil-cpp/absl/synchronization/blocking_counter.h +99 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +140 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.h +60 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc +697 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h +141 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +155 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/mutex_nonprod.inc +261 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc +106 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +115 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/waiter.cc +484 -0
- data/third_party/abseil-cpp/absl/synchronization/internal/waiter.h +159 -0
- data/third_party/abseil-cpp/absl/synchronization/mutex.cc +2728 -0
- data/third_party/abseil-cpp/absl/synchronization/mutex.h +1056 -0
- data/third_party/abseil-cpp/absl/synchronization/notification.cc +78 -0
- data/third_party/abseil-cpp/absl/synchronization/notification.h +123 -0
- data/third_party/abseil-cpp/absl/types/bad_variant_access.cc +64 -0
- data/third_party/abseil-cpp/absl/types/bad_variant_access.h +82 -0
- data/third_party/abseil-cpp/absl/types/internal/variant.h +1646 -0
- data/third_party/abseil-cpp/absl/types/variant.h +861 -0
- data/third_party/boringssl-with-bazel/err_data.c +263 -257
- data/third_party/boringssl-with-bazel/src/crypto/evp/evp_asn1.c +16 -0
- data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +456 -0
- data/third_party/boringssl-with-bazel/src/crypto/hpke/internal.h +192 -0
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_sig.c +20 -0
- data/third_party/boringssl-with-bazel/src/include/openssl/arm_arch.h +52 -0
- data/third_party/boringssl-with-bazel/src/include/openssl/base.h +1 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +39 -7
- data/third_party/boringssl-with-bazel/src/include/openssl/tls1.h +2 -3
- data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +11 -0
- data/third_party/boringssl-with-bazel/src/ssl/internal.h +4 -0
- data/third_party/boringssl-with-bazel/src/ssl/ssl_cert.cc +3 -6
- data/third_party/boringssl-with-bazel/src/ssl/ssl_lib.cc +10 -0
- data/third_party/boringssl-with-bazel/src/ssl/t1_lib.cc +34 -9
- data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +5 -0
- data/third_party/boringssl-with-bazel/src/ssl/tls_record.cc +5 -3
- data/third_party/upb/upb/decode.c +64 -15
- data/third_party/upb/upb/encode.c +2 -2
- data/third_party/upb/upb/msg.h +2 -2
- data/third_party/upb/upb/port_def.inc +1 -1
- data/third_party/upb/upb/table.c +0 -11
- data/third_party/upb/upb/table.int.h +0 -9
- data/third_party/upb/upb/upb.c +16 -14
- data/third_party/upb/upb/upb.h +26 -0
- data/third_party/upb/upb/upb.hpp +2 -0
- metadata +257 -155
- data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.c +0 -21
- data/src/core/ext/upb-generated/envoy/api/v2/auth/cert.upb.h +0 -34
- data/src/core/ext/upb-generated/envoy/api/v2/auth/common.upb.c +0 -114
- data/src/core/ext/upb-generated/envoy/api/v2/auth/common.upb.h +0 -429
- data/src/core/ext/upb-generated/envoy/api/v2/auth/secret.upb.c +0 -72
- data/src/core/ext/upb-generated/envoy/api/v2/auth/secret.upb.h +0 -198
- data/src/core/ext/upb-generated/envoy/api/v2/auth/tls.upb.c +0 -105
- data/src/core/ext/upb-generated/envoy/api/v2/auth/tls.upb.h +0 -388
- data/src/core/ext/upb-generated/envoy/api/v2/cds.upb.h +0 -52
- data/src/core/ext/upb-generated/envoy/api/v2/cluster.upb.c +0 -403
- data/src/core/ext/upb-generated/envoy/api/v2/cluster.upb.h +0 -1453
- data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.c +0 -74
- data/src/core/ext/upb-generated/envoy/api/v2/cluster/circuit_breaker.upb.h +0 -226
- data/src/core/ext/upb-generated/envoy/api/v2/cluster/filter.upb.h +0 -69
- data/src/core/ext/upb-generated/envoy/api/v2/cluster/outlier_detection.upb.h +0 -323
- data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.c +0 -112
- data/src/core/ext/upb-generated/envoy/api/v2/core/address.upb.h +0 -334
- data/src/core/ext/upb-generated/envoy/api/v2/core/backoff.upb.h +0 -79
- data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.c +0 -313
- data/src/core/ext/upb-generated/envoy/api/v2/core/base.upb.h +0 -891
- data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.c +0 -96
- data/src/core/ext/upb-generated/envoy/api/v2/core/config_source.upb.h +0 -328
- data/src/core/ext/upb-generated/envoy/api/v2/core/event_service_config.upb.c +0 -34
- data/src/core/ext/upb-generated/envoy/api/v2/core/event_service_config.upb.h +0 -71
- data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.c +0 -197
- data/src/core/ext/upb-generated/envoy/api/v2/core/grpc_service.upb.h +0 -649
- data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.c +0 -172
- data/src/core/ext/upb-generated/envoy/api/v2/core/health_check.upb.h +0 -693
- data/src/core/ext/upb-generated/envoy/api/v2/core/http_uri.upb.h +0 -80
- data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.c +0 -152
- data/src/core/ext/upb-generated/envoy/api/v2/core/protocol.upb.h +0 -536
- data/src/core/ext/upb-generated/envoy/api/v2/core/socket_option.upb.h +0 -88
- data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.c +0 -129
- data/src/core/ext/upb-generated/envoy/api/v2/discovery.upb.h +0 -386
- data/src/core/ext/upb-generated/envoy/api/v2/eds.upb.h +0 -52
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint.upb.c +0 -92
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint.upb.h +0 -224
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.c +0 -18
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint.upb.h +0 -32
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint_components.upb.c +0 -91
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint/endpoint_components.upb.h +0 -273
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.c +0 -112
- data/src/core/ext/upb-generated/envoy/api/v2/endpoint/load_report.upb.h +0 -332
- data/src/core/ext/upb-generated/envoy/api/v2/lds.upb.h +0 -52
- data/src/core/ext/upb-generated/envoy/api/v2/listener.upb.c +0 -109
- data/src/core/ext/upb-generated/envoy/api/v2/listener.upb.h +0 -415
- data/src/core/ext/upb-generated/envoy/api/v2/listener/listener.upb.c +0 -18
- data/src/core/ext/upb-generated/envoy/api/v2/listener/listener.upb.h +0 -32
- data/src/core/ext/upb-generated/envoy/api/v2/listener/listener_components.upb.c +0 -145
- data/src/core/ext/upb-generated/envoy/api/v2/listener/listener_components.upb.h +0 -538
- data/src/core/ext/upb-generated/envoy/api/v2/listener/udp_listener_config.upb.c +0 -43
- data/src/core/ext/upb-generated/envoy/api/v2/listener/udp_listener_config.upb.h +0 -111
- data/src/core/ext/upb-generated/envoy/api/v2/rds.upb.h +0 -52
- data/src/core/ext/upb-generated/envoy/api/v2/route.upb.c +0 -63
- data/src/core/ext/upb-generated/envoy/api/v2/route.upb.h +0 -204
- data/src/core/ext/upb-generated/envoy/api/v2/route/route.upb.c +0 -18
- data/src/core/ext/upb-generated/envoy/api/v2/route/route.upb.h +0 -32
- data/src/core/ext/upb-generated/envoy/api/v2/route/route_components.upb.c +0 -815
- data/src/core/ext/upb-generated/envoy/api/v2/route/route_components.upb.h +0 -2984
- data/src/core/ext/upb-generated/envoy/api/v2/scoped_route.upb.c +0 -59
- data/src/core/ext/upb-generated/envoy/api/v2/scoped_route.upb.h +0 -135
- data/src/core/ext/upb-generated/envoy/api/v2/srds.upb.h +0 -52
- data/src/core/ext/upb-generated/envoy/config/filter/accesslog/v2/accesslog.upb.c +0 -228
- data/src/core/ext/upb-generated/envoy/config/filter/accesslog/v2/accesslog.upb.h +0 -732
- data/src/core/ext/upb-generated/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.upb.c +0 -316
- data/src/core/ext/upb-generated/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.upb.h +0 -1167
- data/src/core/ext/upb-generated/envoy/config/listener/v2/api_listener.upb.h +0 -65
- data/src/core/ext/upb-generated/envoy/config/trace/v2/http_tracer.upb.c +0 -51
- data/src/core/ext/upb-generated/envoy/config/trace/v2/http_tracer.upb.h +0 -125
- data/src/core/ext/upb-generated/envoy/service/discovery/v2/ads.upb.h +0 -49
- data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.c +0 -54
- data/src/core/ext/upb-generated/envoy/service/load_stats/v2/lrs.upb.h +0 -136
- data/src/core/ext/upb-generated/envoy/type/matcher/regex.upb.c +0 -63
- data/src/core/ext/upb-generated/envoy/type/matcher/regex.upb.h +0 -145
- data/src/core/ext/upb-generated/envoy/type/matcher/string.upb.c +0 -53
- data/src/core/ext/upb-generated/envoy/type/matcher/string.upb.h +0 -133
- data/src/core/ext/upb-generated/envoy/type/metadata/v2/metadata.upb.c +0 -88
- data/src/core/ext/upb-generated/envoy/type/metadata/v2/metadata.upb.h +0 -258
- data/src/core/ext/upb-generated/envoy/type/percent.upb.h +0 -86
- data/src/core/ext/upb-generated/envoy/type/range.upb.h +0 -111
- data/src/core/ext/upb-generated/envoy/type/semantic_version.upb.h +0 -61
- data/src/core/ext/upb-generated/envoy/type/tracing/v2/custom_tag.upb.c +0 -89
- data/src/core/ext/upb-generated/envoy/type/tracing/v2/custom_tag.upb.h +0 -250
- data/src/core/lib/security/transport/target_authority_table.cc +0 -75
- data/src/core/lib/security/transport/target_authority_table.h +0 -40
- data/src/core/lib/slice/slice_hash_table.h +0 -199
- data/src/core/lib/slice/slice_weak_hash_table.h +0 -102
@@ -69,14 +69,6 @@ void grpc_cq_internal_unref(grpc_completion_queue* cc);
|
|
69
69
|
/* Initializes global variables used by completion queues */
|
70
70
|
void grpc_cq_global_init();
|
71
71
|
|
72
|
-
// Completion queue initializations that must be done after iomgr
|
73
|
-
// TODO(vjpai): Remove when callback_alternative is no longer needed.
|
74
|
-
void grpc_cq_init();
|
75
|
-
|
76
|
-
// Completion queue shutdowns that must be done before iomgr shutdown.
|
77
|
-
// TODO(vjpai): Remove when callback_alternative is no longer needed.
|
78
|
-
void grpc_cq_shutdown();
|
79
|
-
|
80
72
|
/* Flag that an operation is beginning: the completion channel will not finish
|
81
73
|
shutdown until a corrensponding grpc_cq_end_* call is made.
|
82
74
|
\a tag is currently used only in debug builds. Return true on success, and
|
@@ -102,7 +102,7 @@ static void register_builtin_channel_init() {
|
|
102
102
|
GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
|
103
103
|
append_filter, (void*)&grpc_lame_filter);
|
104
104
|
grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter,
|
105
|
-
(void*)&
|
105
|
+
(void*)&grpc_core::Server::kServerTopFilter);
|
106
106
|
}
|
107
107
|
|
108
108
|
typedef struct grpc_plugin {
|
@@ -144,7 +144,6 @@ void grpc_init(void) {
|
|
144
144
|
grpc_core::ApplicationCallbackExecCtx::GlobalInit();
|
145
145
|
grpc_core::ExecCtx::GlobalInit();
|
146
146
|
grpc_iomgr_init();
|
147
|
-
grpc_cq_init();
|
148
147
|
gpr_timers_global_init();
|
149
148
|
grpc_core::HandshakerRegistry::Init();
|
150
149
|
grpc_security_init();
|
@@ -170,7 +169,6 @@ void grpc_shutdown_internal_locked(void) {
|
|
170
169
|
int i;
|
171
170
|
{
|
172
171
|
grpc_core::ExecCtx exec_ctx(0);
|
173
|
-
grpc_cq_shutdown();
|
174
172
|
grpc_iomgr_shutdown_background_closure();
|
175
173
|
{
|
176
174
|
grpc_timer_manager_set_threading(false); // shutdown timer_manager thread
|
@@ -1,20 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
*
|
17
|
-
*/
|
1
|
+
//
|
2
|
+
// Copyright 2015-2016 gRPC authors.
|
3
|
+
//
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
// you may not use this file except in compliance with the License.
|
6
|
+
// You may obtain a copy of the License at
|
7
|
+
//
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
//
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
// See the License for the specific language governing permissions and
|
14
|
+
// limitations under the License.
|
15
|
+
//
|
18
16
|
|
19
17
|
#include <grpc/support/port_platform.h>
|
20
18
|
|
@@ -28,15 +26,16 @@
|
|
28
26
|
#include <atomic>
|
29
27
|
#include <iterator>
|
30
28
|
#include <list>
|
29
|
+
#include <queue>
|
31
30
|
#include <utility>
|
32
31
|
#include <vector>
|
33
32
|
|
33
|
+
#include "absl/types/optional.h"
|
34
|
+
|
34
35
|
#include <grpc/support/alloc.h>
|
35
36
|
#include <grpc/support/log.h>
|
36
37
|
#include <grpc/support/string_util.h>
|
37
38
|
|
38
|
-
#include "absl/types/optional.h"
|
39
|
-
|
40
39
|
#include "src/core/lib/channel/channel_args.h"
|
41
40
|
#include "src/core/lib/channel/channelz.h"
|
42
41
|
#include "src/core/lib/channel/connected_channel.h"
|
@@ -59,28 +58,17 @@ namespace grpc_core {
|
|
59
58
|
|
60
59
|
TraceFlag grpc_server_channel_trace(false, "server_channel");
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
void server_recv_trailing_metadata_ready(void* user_data, grpc_error* error);
|
66
|
-
|
67
|
-
struct Listener {
|
68
|
-
explicit Listener(OrphanablePtr<ServerListenerInterface> l)
|
69
|
-
: listener(std::move(l)) {}
|
70
|
-
|
71
|
-
OrphanablePtr<ServerListenerInterface> listener;
|
72
|
-
grpc_closure destroy_done;
|
73
|
-
};
|
74
|
-
|
75
|
-
enum class RequestedCallType { BATCH_CALL, REGISTERED_CALL };
|
61
|
+
//
|
62
|
+
// Server::RequestedCall
|
63
|
+
//
|
76
64
|
|
77
|
-
struct
|
65
|
+
struct Server::RequestedCall {
|
66
|
+
enum class Type { BATCH_CALL, REGISTERED_CALL };
|
78
67
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
: type(RequestedCallType::BATCH_CALL),
|
68
|
+
RequestedCall(void* tag_arg, grpc_completion_queue* call_cq,
|
69
|
+
grpc_call** call_arg, grpc_metadata_array* initial_md,
|
70
|
+
grpc_call_details* details)
|
71
|
+
: type(Type::BATCH_CALL),
|
84
72
|
tag(tag_arg),
|
85
73
|
cq_bound_to_call(call_cq),
|
86
74
|
call(call_arg),
|
@@ -89,11 +77,11 @@ struct requested_call {
|
|
89
77
|
data.batch.details = details;
|
90
78
|
}
|
91
79
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
: type(
|
80
|
+
RequestedCall(void* tag_arg, grpc_completion_queue* call_cq,
|
81
|
+
grpc_call** call_arg, grpc_metadata_array* initial_md,
|
82
|
+
RegisteredMethod* rm, gpr_timespec* deadline,
|
83
|
+
grpc_byte_buffer** optional_payload)
|
84
|
+
: type(Type::REGISTERED_CALL),
|
97
85
|
tag(tag_arg),
|
98
86
|
cq_bound_to_call(call_cq),
|
99
87
|
call(call_arg),
|
@@ -104,7 +92,7 @@ struct requested_call {
|
|
104
92
|
}
|
105
93
|
|
106
94
|
MultiProducerSingleConsumerQueue::Node mpscq_node;
|
107
|
-
const
|
95
|
+
const Type type;
|
108
96
|
void* const tag;
|
109
97
|
grpc_completion_queue* const cq_bound_to_call;
|
110
98
|
grpc_call** const call;
|
@@ -115,66 +103,40 @@ struct requested_call {
|
|
115
103
|
grpc_call_details* details;
|
116
104
|
} batch;
|
117
105
|
struct {
|
118
|
-
|
106
|
+
RegisteredMethod* method;
|
119
107
|
gpr_timespec* deadline;
|
120
108
|
grpc_byte_buffer** optional_payload;
|
121
109
|
} registered;
|
122
110
|
} data;
|
123
111
|
};
|
124
112
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
bool has_host;
|
129
|
-
ExternallyManagedSlice method;
|
130
|
-
ExternallyManagedSlice host;
|
131
|
-
};
|
132
|
-
|
133
|
-
struct channel_data {
|
134
|
-
channel_data() = default;
|
135
|
-
~channel_data();
|
136
|
-
|
137
|
-
grpc_server* server = nullptr;
|
138
|
-
grpc_channel* channel;
|
139
|
-
size_t cq_idx;
|
140
|
-
absl::optional<std::list<channel_data*>::iterator> list_position;
|
141
|
-
|
142
|
-
// registered_methods is a hash-table of the methods and hosts of the
|
143
|
-
// registered methods.
|
144
|
-
// TODO(vjpai): Convert this to an STL map type as opposed to a direct bucket
|
145
|
-
// implementation. (Consider performance impact, hash function to use, etc.)
|
146
|
-
std::unique_ptr<std::vector<channel_registered_method>> registered_methods;
|
147
|
-
uint32_t registered_method_max_probes;
|
148
|
-
|
149
|
-
grpc_closure finish_destroy_channel_closure;
|
150
|
-
intptr_t channelz_socket_uuid;
|
151
|
-
};
|
113
|
+
//
|
114
|
+
// Server::RegisteredMethod
|
115
|
+
//
|
152
116
|
|
153
|
-
struct
|
154
|
-
|
155
|
-
|
117
|
+
struct Server::RegisteredMethod {
|
118
|
+
RegisteredMethod(
|
119
|
+
const char* method_arg, const char* host_arg,
|
120
|
+
grpc_server_register_method_payload_handling payload_handling_arg,
|
121
|
+
uint32_t flags_arg)
|
122
|
+
: method(method_arg == nullptr ? "" : method_arg),
|
123
|
+
host(host_arg == nullptr ? "" : host_arg),
|
124
|
+
payload_handling(payload_handling_arg),
|
125
|
+
flags(flags_arg) {}
|
156
126
|
|
157
|
-
|
158
|
-
grpc_completion_queue* const cq;
|
159
|
-
grpc_cq_completion completion;
|
160
|
-
};
|
127
|
+
~RegisteredMethod() = default;
|
161
128
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
ACTIVATED,
|
169
|
-
/* cancelled before being queued */
|
170
|
-
ZOMBIED
|
129
|
+
const std::string method;
|
130
|
+
const std::string host;
|
131
|
+
const grpc_server_register_method_payload_handling payload_handling;
|
132
|
+
const uint32_t flags;
|
133
|
+
// One request matcher per method.
|
134
|
+
std::unique_ptr<RequestMatcherInterface> matcher;
|
171
135
|
};
|
172
136
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
grpc_completion_queue* cq_for_notification, void* tag,
|
177
|
-
grpc_byte_buffer** optional_payload, registered_method* rm);
|
137
|
+
//
|
138
|
+
// Server::RequestMatcherInterface
|
139
|
+
//
|
178
140
|
|
179
141
|
// RPCs that come in from the transport must be matched against RPC requests
|
180
142
|
// from the application. An incoming request from the application can be matched
|
@@ -185,7 +147,7 @@ grpc_call_error ValidateServerRequest(
|
|
185
147
|
// on the request's notification CQ.
|
186
148
|
//
|
187
149
|
// RequestMatcherInterface is the base class to provide this functionality.
|
188
|
-
class RequestMatcherInterface {
|
150
|
+
class Server::RequestMatcherInterface {
|
189
151
|
public:
|
190
152
|
virtual ~RequestMatcherInterface() {}
|
191
153
|
|
@@ -208,7 +170,7 @@ class RequestMatcherInterface {
|
|
208
170
|
// CQ. If there are pending RPCs waiting to be matched, publish one (match it
|
209
171
|
// and notify the CQ).
|
210
172
|
virtual void RequestCallWithPossiblePublish(size_t request_queue_index,
|
211
|
-
|
173
|
+
RequestedCall* call) = 0;
|
212
174
|
|
213
175
|
// This function is invoked on an incoming RPC, represented by the calld
|
214
176
|
// object. The RequestMatcher will try to match it against an
|
@@ -217,339 +179,21 @@ class RequestMatcherInterface {
|
|
217
179
|
// is done starting at the start_request_queue_index parameter in a cyclic
|
218
180
|
// order rather than always starting at 0.
|
219
181
|
virtual void MatchOrQueue(size_t start_request_queue_index,
|
220
|
-
|
182
|
+
CallData* calld) = 0;
|
221
183
|
|
222
184
|
// Returns the server associated with this request matcher
|
223
|
-
virtual
|
224
|
-
};
|
225
|
-
|
226
|
-
struct call_data {
|
227
|
-
call_data(grpc_call_element* elem, const grpc_call_element_args& args)
|
228
|
-
: call(grpc_call_from_top_element(elem)),
|
229
|
-
call_combiner(args.call_combiner) {
|
230
|
-
GRPC_CLOSURE_INIT(&on_recv_initial_metadata,
|
231
|
-
server_on_recv_initial_metadata, elem,
|
232
|
-
grpc_schedule_on_exec_ctx);
|
233
|
-
GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready,
|
234
|
-
server_recv_trailing_metadata_ready, elem,
|
235
|
-
grpc_schedule_on_exec_ctx);
|
236
|
-
}
|
237
|
-
~call_data() {
|
238
|
-
GPR_ASSERT(state.Load(grpc_core::MemoryOrder::RELAXED) !=
|
239
|
-
CallState::PENDING);
|
240
|
-
GRPC_ERROR_UNREF(recv_initial_metadata_error);
|
241
|
-
if (host_set) {
|
242
|
-
grpc_slice_unref_internal(host);
|
243
|
-
}
|
244
|
-
if (path_set) {
|
245
|
-
grpc_slice_unref_internal(path);
|
246
|
-
}
|
247
|
-
grpc_metadata_array_destroy(&initial_metadata);
|
248
|
-
grpc_byte_buffer_destroy(payload);
|
249
|
-
}
|
250
|
-
|
251
|
-
grpc_call* call;
|
252
|
-
|
253
|
-
Atomic<CallState> state{CallState::NOT_STARTED};
|
254
|
-
|
255
|
-
bool path_set = false;
|
256
|
-
bool host_set = false;
|
257
|
-
grpc_slice path;
|
258
|
-
grpc_slice host;
|
259
|
-
grpc_millis deadline = GRPC_MILLIS_INF_FUTURE;
|
260
|
-
|
261
|
-
grpc_completion_queue* cq_new = nullptr;
|
262
|
-
|
263
|
-
grpc_metadata_batch* recv_initial_metadata = nullptr;
|
264
|
-
uint32_t recv_initial_metadata_flags = 0;
|
265
|
-
grpc_metadata_array initial_metadata =
|
266
|
-
grpc_metadata_array(); // Zero-initialize the C struct.
|
267
|
-
|
268
|
-
RequestMatcherInterface* matcher = nullptr;
|
269
|
-
grpc_byte_buffer* payload = nullptr;
|
270
|
-
|
271
|
-
grpc_closure got_initial_metadata;
|
272
|
-
grpc_closure on_recv_initial_metadata;
|
273
|
-
grpc_closure kill_zombie_closure;
|
274
|
-
grpc_closure* on_done_recv_initial_metadata;
|
275
|
-
grpc_closure recv_trailing_metadata_ready;
|
276
|
-
grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE;
|
277
|
-
grpc_closure* original_recv_trailing_metadata_ready;
|
278
|
-
grpc_error* recv_trailing_metadata_error = GRPC_ERROR_NONE;
|
279
|
-
bool seen_recv_trailing_metadata_ready = false;
|
280
|
-
|
281
|
-
grpc_closure publish;
|
282
|
-
|
283
|
-
CallCombiner* call_combiner;
|
284
|
-
};
|
285
|
-
|
286
|
-
struct registered_method {
|
287
|
-
registered_method(
|
288
|
-
const char* method_arg, const char* host_arg,
|
289
|
-
grpc_server_register_method_payload_handling payload_handling_arg,
|
290
|
-
uint32_t flags_arg)
|
291
|
-
: method(method_arg == nullptr ? "" : method_arg),
|
292
|
-
host(host_arg == nullptr ? "" : host_arg),
|
293
|
-
payload_handling(payload_handling_arg),
|
294
|
-
flags(flags_arg) {}
|
295
|
-
|
296
|
-
~registered_method() = default;
|
297
|
-
|
298
|
-
const std::string method;
|
299
|
-
const std::string host;
|
300
|
-
const grpc_server_register_method_payload_handling payload_handling;
|
301
|
-
const uint32_t flags;
|
302
|
-
/* one request matcher per method */
|
303
|
-
std::unique_ptr<RequestMatcherInterface> matcher;
|
304
|
-
};
|
305
|
-
|
306
|
-
} // namespace
|
307
|
-
} // namespace grpc_core
|
308
|
-
|
309
|
-
struct grpc_server {
|
310
|
-
explicit grpc_server(const grpc_channel_args* args)
|
311
|
-
: channel_args(grpc_channel_args_copy(args)) {
|
312
|
-
if (grpc_channel_args_find_bool(args, GRPC_ARG_ENABLE_CHANNELZ,
|
313
|
-
GRPC_ENABLE_CHANNELZ_DEFAULT)) {
|
314
|
-
size_t channel_tracer_max_memory = grpc_channel_args_find_integer(
|
315
|
-
args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE,
|
316
|
-
{GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX});
|
317
|
-
channelz_server =
|
318
|
-
grpc_core::MakeRefCounted<grpc_core::channelz::ServerNode>(
|
319
|
-
this, channel_tracer_max_memory);
|
320
|
-
channelz_server->AddTraceEvent(
|
321
|
-
grpc_core::channelz::ChannelTrace::Severity::Info,
|
322
|
-
grpc_slice_from_static_string("Server created"));
|
323
|
-
}
|
324
|
-
|
325
|
-
if (args != nullptr) {
|
326
|
-
grpc_resource_quota* resource_quota =
|
327
|
-
grpc_resource_quota_from_channel_args(args, false /* create */);
|
328
|
-
if (resource_quota != nullptr) {
|
329
|
-
default_resource_user =
|
330
|
-
grpc_resource_user_create(resource_quota, "default");
|
331
|
-
}
|
332
|
-
}
|
333
|
-
}
|
334
|
-
|
335
|
-
~grpc_server() {
|
336
|
-
grpc_channel_args_destroy(channel_args);
|
337
|
-
for (size_t i = 0; i < cqs.size(); i++) {
|
338
|
-
GRPC_CQ_INTERNAL_UNREF(cqs[i], "server");
|
339
|
-
}
|
340
|
-
}
|
341
|
-
|
342
|
-
grpc_channel_args* const channel_args;
|
343
|
-
|
344
|
-
grpc_resource_user* default_resource_user = nullptr;
|
345
|
-
|
346
|
-
std::vector<grpc_completion_queue*> cqs;
|
347
|
-
std::vector<grpc_pollset*> pollsets;
|
348
|
-
bool started = false;
|
349
|
-
|
350
|
-
/* The two following mutexes control access to server-state
|
351
|
-
mu_global controls access to non-call-related state (e.g., channel state)
|
352
|
-
mu_call controls access to call-related state (e.g., the call lists)
|
353
|
-
|
354
|
-
If they are ever required to be nested, you must lock mu_global
|
355
|
-
before mu_call. This is currently used in shutdown processing
|
356
|
-
(grpc_server_shutdown_and_notify and maybe_finish_shutdown) */
|
357
|
-
grpc_core::Mutex mu_global; // mutex for server and channel state
|
358
|
-
grpc_core::Mutex mu_call; // mutex for call-specific state
|
359
|
-
|
360
|
-
/* startup synchronization: flag is protected by mu_global, signals whether
|
361
|
-
we are doing the listener start routine or not */
|
362
|
-
bool starting = false;
|
363
|
-
grpc_core::CondVar starting_cv;
|
364
|
-
|
365
|
-
std::vector<std::unique_ptr<grpc_core::registered_method>> registered_methods;
|
366
|
-
|
367
|
-
// one request matcher for unregistered methods
|
368
|
-
std::unique_ptr<grpc_core::RequestMatcherInterface>
|
369
|
-
unregistered_request_matcher;
|
370
|
-
|
371
|
-
std::atomic_bool shutdown_flag{false};
|
372
|
-
bool shutdown_published = false;
|
373
|
-
std::vector<grpc_core::shutdown_tag> shutdown_tags;
|
374
|
-
|
375
|
-
std::list<grpc_core::channel_data*> channels;
|
376
|
-
|
377
|
-
std::list<grpc_core::Listener> listeners;
|
378
|
-
size_t listeners_destroyed = 0;
|
379
|
-
grpc_core::RefCount internal_refcount;
|
380
|
-
|
381
|
-
/** when did we print the last shutdown progress message */
|
382
|
-
gpr_timespec last_shutdown_message_time;
|
383
|
-
|
384
|
-
grpc_core::RefCountedPtr<grpc_core::channelz::ServerNode> channelz_server;
|
385
|
-
};
|
386
|
-
|
387
|
-
// Non-API functions of the server that are only for gRPC core internal use.
|
388
|
-
// TODO(markdroth): Make these class member functions
|
389
|
-
void grpc_server_add_listener(
|
390
|
-
grpc_server* server,
|
391
|
-
grpc_core::OrphanablePtr<grpc_core::ServerListenerInterface> listener) {
|
392
|
-
grpc_core::channelz::ListenSocketNode* listen_socket_node =
|
393
|
-
listener->channelz_listen_socket_node();
|
394
|
-
if (listen_socket_node != nullptr && server->channelz_server != nullptr) {
|
395
|
-
server->channelz_server->AddChildListenSocket(listen_socket_node->Ref());
|
396
|
-
}
|
397
|
-
server->listeners.emplace_back(std::move(listener));
|
398
|
-
}
|
399
|
-
|
400
|
-
const grpc_channel_args* grpc_server_get_channel_args(grpc_server* server) {
|
401
|
-
return server->channel_args;
|
402
|
-
}
|
403
|
-
|
404
|
-
grpc_resource_user* grpc_server_get_default_resource_user(grpc_server* server) {
|
405
|
-
return server->default_resource_user;
|
406
|
-
}
|
407
|
-
|
408
|
-
bool grpc_server_has_open_connections(grpc_server* server) {
|
409
|
-
grpc_core::MutexLock lock(&server->mu_global);
|
410
|
-
return !server->channels.empty();
|
411
|
-
}
|
412
|
-
|
413
|
-
grpc_core::channelz::ServerNode* grpc_server_get_channelz_node(
|
414
|
-
grpc_server* server) {
|
415
|
-
if (server == nullptr) {
|
416
|
-
return nullptr;
|
417
|
-
}
|
418
|
-
return server->channelz_server.get();
|
419
|
-
}
|
420
|
-
|
421
|
-
namespace grpc_core {
|
422
|
-
namespace {
|
423
|
-
|
424
|
-
void publish_call(grpc_server* server, call_data* calld, size_t cq_idx,
|
425
|
-
requested_call* rc);
|
426
|
-
void fail_call(grpc_server* server, size_t cq_idx, requested_call* rc,
|
427
|
-
grpc_error* error);
|
428
|
-
/* Before calling maybe_finish_shutdown, we must hold mu_global and not
|
429
|
-
hold mu_call */
|
430
|
-
void maybe_finish_shutdown(grpc_server* server);
|
431
|
-
|
432
|
-
void kill_zombie(void* elem, grpc_error* /*error*/) {
|
433
|
-
grpc_call_unref(
|
434
|
-
grpc_call_from_top_element(static_cast<grpc_call_element*>(elem)));
|
435
|
-
}
|
436
|
-
|
437
|
-
// Validate a requested RPC for a server CQ and bind it to that CQ
|
438
|
-
grpc_call_error ValidateServerRequest(
|
439
|
-
grpc_completion_queue* cq_for_notification, void* tag,
|
440
|
-
grpc_byte_buffer** optional_payload, registered_method* rm) {
|
441
|
-
if ((rm == nullptr && optional_payload != nullptr) ||
|
442
|
-
((rm != nullptr) && ((optional_payload == nullptr) !=
|
443
|
-
(rm->payload_handling == GRPC_SRM_PAYLOAD_NONE)))) {
|
444
|
-
return GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH;
|
445
|
-
}
|
446
|
-
if (grpc_cq_begin_op(cq_for_notification, tag) == false) {
|
447
|
-
return GRPC_CALL_ERROR_COMPLETION_QUEUE_SHUTDOWN;
|
448
|
-
}
|
449
|
-
return GRPC_CALL_OK;
|
450
|
-
}
|
451
|
-
|
452
|
-
// Validate that a requested RPC has a valid server CQ and is valid, and bind it
|
453
|
-
grpc_call_error ValidateServerRequestAndCq(
|
454
|
-
size_t* cq_idx, grpc_server* server,
|
455
|
-
grpc_completion_queue* cq_for_notification, void* tag,
|
456
|
-
grpc_byte_buffer** optional_payload, registered_method* rm) {
|
457
|
-
size_t idx;
|
458
|
-
for (idx = 0; idx < server->cqs.size(); idx++) {
|
459
|
-
if (server->cqs[idx] == cq_for_notification) {
|
460
|
-
break;
|
461
|
-
}
|
462
|
-
}
|
463
|
-
if (idx == server->cqs.size()) {
|
464
|
-
return GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
|
465
|
-
}
|
466
|
-
grpc_call_error error =
|
467
|
-
ValidateServerRequest(cq_for_notification, tag, optional_payload, rm);
|
468
|
-
if (error != GRPC_CALL_OK) {
|
469
|
-
return error;
|
470
|
-
}
|
471
|
-
|
472
|
-
*cq_idx = idx;
|
473
|
-
return GRPC_CALL_OK;
|
474
|
-
}
|
475
|
-
/*
|
476
|
-
* channel broadcaster
|
477
|
-
*/
|
478
|
-
|
479
|
-
struct shutdown_cleanup_args {
|
480
|
-
grpc_closure closure;
|
481
|
-
grpc_slice slice;
|
482
|
-
};
|
483
|
-
|
484
|
-
void shutdown_cleanup(void* arg, grpc_error* /*error*/) {
|
485
|
-
shutdown_cleanup_args* a = static_cast<shutdown_cleanup_args*>(arg);
|
486
|
-
grpc_slice_unref_internal(a->slice);
|
487
|
-
delete a;
|
488
|
-
}
|
489
|
-
|
490
|
-
void send_shutdown(grpc_channel* channel, bool send_goaway,
|
491
|
-
grpc_error* send_disconnect) {
|
492
|
-
shutdown_cleanup_args* sc = new shutdown_cleanup_args;
|
493
|
-
GRPC_CLOSURE_INIT(&sc->closure, shutdown_cleanup, sc,
|
494
|
-
grpc_schedule_on_exec_ctx);
|
495
|
-
grpc_transport_op* op = grpc_make_transport_op(&sc->closure);
|
496
|
-
grpc_channel_element* elem;
|
497
|
-
|
498
|
-
op->goaway_error =
|
499
|
-
send_goaway ? grpc_error_set_int(
|
500
|
-
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"),
|
501
|
-
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK)
|
502
|
-
: GRPC_ERROR_NONE;
|
503
|
-
op->set_accept_stream = true;
|
504
|
-
sc->slice = grpc_slice_from_copied_string("Server shutdown");
|
505
|
-
op->disconnect_with_error = send_disconnect;
|
506
|
-
|
507
|
-
elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
|
508
|
-
elem->filter->start_transport_op(elem, op);
|
509
|
-
}
|
510
|
-
|
511
|
-
class ChannelBroadcaster {
|
512
|
-
public:
|
513
|
-
// This can have an empty constructor and destructor since we want to control
|
514
|
-
// when the actual setup and shutdown broadcast take place
|
515
|
-
|
516
|
-
// This function copies over the channels from the locked server
|
517
|
-
void FillChannelsLocked(const grpc_server* s) {
|
518
|
-
GPR_DEBUG_ASSERT(channels_.empty());
|
519
|
-
channels_.reserve(s->channels.size());
|
520
|
-
for (const channel_data* chand : s->channels) {
|
521
|
-
channels_.push_back(chand->channel);
|
522
|
-
GRPC_CHANNEL_INTERNAL_REF(chand->channel, "broadcast");
|
523
|
-
}
|
524
|
-
}
|
525
|
-
|
526
|
-
// Broadcast a shutdown on each channel
|
527
|
-
void BroadcastShutdown(bool send_goaway, grpc_error* force_disconnect) {
|
528
|
-
for (grpc_channel* channel : channels_) {
|
529
|
-
send_shutdown(channel, send_goaway, GRPC_ERROR_REF(force_disconnect));
|
530
|
-
GRPC_CHANNEL_INTERNAL_UNREF(channel, "broadcast");
|
531
|
-
}
|
532
|
-
channels_.clear(); // just for safety against double broadcast
|
533
|
-
GRPC_ERROR_UNREF(force_disconnect);
|
534
|
-
}
|
535
|
-
|
536
|
-
private:
|
537
|
-
std::vector<grpc_channel*> channels_;
|
185
|
+
virtual Server* server() const = 0;
|
538
186
|
};
|
539
187
|
|
540
|
-
/*
|
541
|
-
* request_matcher
|
542
|
-
*/
|
543
|
-
|
544
188
|
// The RealRequestMatcher is an implementation of RequestMatcherInterface that
|
545
189
|
// actually uses all the features of RequestMatcherInterface: expecting the
|
546
190
|
// application to explicitly request RPCs and then matching those to incoming
|
547
191
|
// RPCs, along with a slow path by which incoming RPCs are put on a locked
|
548
192
|
// pending list if they aren't able to be matched to an application request.
|
549
|
-
class RealRequestMatcher : public RequestMatcherInterface {
|
193
|
+
class Server::RealRequestMatcher : public RequestMatcherInterface {
|
550
194
|
public:
|
551
|
-
explicit RealRequestMatcher(
|
552
|
-
: server_(server), requests_per_cq_(server->
|
195
|
+
explicit RealRequestMatcher(Server* server)
|
196
|
+
: server_(server), requests_per_cq_(server->cqs_.size()) {}
|
553
197
|
|
554
198
|
~RealRequestMatcher() override {
|
555
199
|
for (LockedMultiProducerSingleConsumerQueue& queue : requests_per_cq_) {
|
@@ -558,24 +202,20 @@ class RealRequestMatcher : public RequestMatcherInterface {
|
|
558
202
|
}
|
559
203
|
|
560
204
|
void ZombifyPending() override {
|
561
|
-
|
562
|
-
calld
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
grpc_schedule_on_exec_ctx);
|
567
|
-
ExecCtx::Run(DEBUG_LOCATION, &calld->kill_zombie_closure,
|
568
|
-
GRPC_ERROR_NONE);
|
205
|
+
while (!pending_.empty()) {
|
206
|
+
CallData* calld = pending_.front();
|
207
|
+
calld->SetState(CallData::CallState::ZOMBIED);
|
208
|
+
calld->KillZombie();
|
209
|
+
pending_.pop();
|
569
210
|
}
|
570
|
-
pending_.clear();
|
571
211
|
}
|
572
212
|
|
573
213
|
void KillRequests(grpc_error* error) override {
|
574
214
|
for (size_t i = 0; i < requests_per_cq_.size(); i++) {
|
575
|
-
|
576
|
-
while ((rc = reinterpret_cast<
|
215
|
+
RequestedCall* rc;
|
216
|
+
while ((rc = reinterpret_cast<RequestedCall*>(
|
577
217
|
requests_per_cq_[i].Pop())) != nullptr) {
|
578
|
-
|
218
|
+
server_->FailCall(i, rc, GRPC_ERROR_REF(error));
|
579
219
|
}
|
580
220
|
}
|
581
221
|
GRPC_ERROR_UNREF(error);
|
@@ -586,106 +226,90 @@ class RealRequestMatcher : public RequestMatcherInterface {
|
|
586
226
|
}
|
587
227
|
|
588
228
|
void RequestCallWithPossiblePublish(size_t request_queue_index,
|
589
|
-
|
229
|
+
RequestedCall* call) override {
|
590
230
|
if (requests_per_cq_[request_queue_index].Push(&call->mpscq_node)) {
|
591
231
|
/* this was the first queued request: we need to lock and start
|
592
232
|
matching calls */
|
593
233
|
struct PendingCall {
|
594
|
-
|
595
|
-
|
234
|
+
RequestedCall* rc = nullptr;
|
235
|
+
CallData* calld;
|
596
236
|
};
|
597
237
|
auto pop_next_pending = [this, request_queue_index] {
|
598
|
-
PendingCall
|
238
|
+
PendingCall pending_call;
|
599
239
|
{
|
600
|
-
MutexLock lock(&server_->
|
240
|
+
MutexLock lock(&server_->mu_call_);
|
601
241
|
if (!pending_.empty()) {
|
602
|
-
|
242
|
+
pending_call.rc = reinterpret_cast<RequestedCall*>(
|
603
243
|
requests_per_cq_[request_queue_index].Pop());
|
604
|
-
if (
|
605
|
-
|
606
|
-
pending_.
|
244
|
+
if (pending_call.rc != nullptr) {
|
245
|
+
pending_call.calld = pending_.front();
|
246
|
+
pending_.pop();
|
607
247
|
}
|
608
248
|
}
|
609
249
|
}
|
610
|
-
return
|
250
|
+
return pending_call;
|
611
251
|
};
|
612
252
|
while (true) {
|
613
253
|
PendingCall next_pending = pop_next_pending();
|
614
254
|
if (next_pending.rc == nullptr) break;
|
615
|
-
|
616
|
-
if (!next_pending.calld->state.CompareExchangeStrong(
|
617
|
-
&expect_pending, CallState::ACTIVATED,
|
618
|
-
grpc_core::MemoryOrder::ACQ_REL,
|
619
|
-
grpc_core::MemoryOrder::RELAXED)) {
|
255
|
+
if (!next_pending.calld->MaybeActivate()) {
|
620
256
|
// Zombied Call
|
621
|
-
|
622
|
-
&next_pending.calld->kill_zombie_closure, kill_zombie,
|
623
|
-
grpc_call_stack_element(
|
624
|
-
grpc_call_get_call_stack(next_pending.calld->call), 0),
|
625
|
-
grpc_schedule_on_exec_ctx);
|
626
|
-
ExecCtx::Run(DEBUG_LOCATION, &next_pending.calld->kill_zombie_closure,
|
627
|
-
GRPC_ERROR_NONE);
|
257
|
+
next_pending.calld->KillZombie();
|
628
258
|
} else {
|
629
|
-
|
630
|
-
next_pending.rc);
|
259
|
+
next_pending.calld->Publish(request_queue_index, next_pending.rc);
|
631
260
|
}
|
632
261
|
}
|
633
262
|
}
|
634
263
|
}
|
635
264
|
|
636
265
|
void MatchOrQueue(size_t start_request_queue_index,
|
637
|
-
|
266
|
+
CallData* calld) override {
|
638
267
|
for (size_t i = 0; i < requests_per_cq_.size(); i++) {
|
639
268
|
size_t cq_idx = (start_request_queue_index + i) % requests_per_cq_.size();
|
640
|
-
|
641
|
-
reinterpret_cast<
|
642
|
-
if (rc
|
643
|
-
continue;
|
644
|
-
} else {
|
269
|
+
RequestedCall* rc =
|
270
|
+
reinterpret_cast<RequestedCall*>(requests_per_cq_[cq_idx].TryPop());
|
271
|
+
if (rc != nullptr) {
|
645
272
|
GRPC_STATS_INC_SERVER_CQS_CHECKED(i);
|
646
|
-
calld->
|
647
|
-
|
648
|
-
|
649
|
-
return; /* early out */
|
273
|
+
calld->SetState(CallData::CallState::ACTIVATED);
|
274
|
+
calld->Publish(cq_idx, rc);
|
275
|
+
return;
|
650
276
|
}
|
651
277
|
}
|
652
|
-
|
653
|
-
/* no cq to take the request found: queue it on the slow list */
|
278
|
+
// No cq to take the request found; queue it on the slow list.
|
654
279
|
GRPC_STATS_INC_SERVER_SLOWPATH_REQUESTS_QUEUED();
|
655
|
-
|
656
280
|
// We need to ensure that all the queues are empty. We do this under
|
657
|
-
// the server
|
281
|
+
// the server mu_call_ lock to ensure that if something is added to
|
658
282
|
// an empty request queue, it will block until the call is actually
|
659
283
|
// added to the pending list.
|
660
|
-
|
284
|
+
RequestedCall* rc = nullptr;
|
661
285
|
size_t cq_idx = 0;
|
662
286
|
size_t loop_count;
|
663
287
|
{
|
664
|
-
MutexLock lock(&server_->
|
288
|
+
MutexLock lock(&server_->mu_call_);
|
665
289
|
for (loop_count = 0; loop_count < requests_per_cq_.size(); loop_count++) {
|
666
290
|
cq_idx =
|
667
291
|
(start_request_queue_index + loop_count) % requests_per_cq_.size();
|
668
|
-
rc = reinterpret_cast<
|
292
|
+
rc = reinterpret_cast<RequestedCall*>(requests_per_cq_[cq_idx].Pop());
|
669
293
|
if (rc != nullptr) {
|
670
294
|
break;
|
671
295
|
}
|
672
296
|
}
|
673
297
|
if (rc == nullptr) {
|
674
|
-
calld->
|
675
|
-
pending_.
|
298
|
+
calld->SetState(CallData::CallState::PENDING);
|
299
|
+
pending_.push(calld);
|
676
300
|
return;
|
677
301
|
}
|
678
302
|
}
|
679
303
|
GRPC_STATS_INC_SERVER_CQS_CHECKED(loop_count + requests_per_cq_.size());
|
680
|
-
calld->
|
681
|
-
|
304
|
+
calld->SetState(CallData::CallState::ACTIVATED);
|
305
|
+
calld->Publish(cq_idx, rc);
|
682
306
|
}
|
683
307
|
|
684
|
-
|
308
|
+
Server* server() const override { return server_; }
|
685
309
|
|
686
310
|
private:
|
687
|
-
|
688
|
-
std::
|
311
|
+
Server* const server_;
|
312
|
+
std::queue<CallData*> pending_;
|
689
313
|
std::vector<LockedMultiProducerSingleConsumerQueue> requests_per_cq_;
|
690
314
|
};
|
691
315
|
|
@@ -694,17 +318,17 @@ class RealRequestMatcher : public RequestMatcherInterface {
|
|
694
318
|
// will call out to an allocation function passed in at the construction of the
|
695
319
|
// object. These request matchers are designed for the C++ callback API, so they
|
696
320
|
// only support 1 completion queue (passed in at the constructor).
|
697
|
-
class AllocatingRequestMatcherBase : public RequestMatcherInterface {
|
321
|
+
class Server::AllocatingRequestMatcherBase : public RequestMatcherInterface {
|
698
322
|
public:
|
699
|
-
AllocatingRequestMatcherBase(
|
323
|
+
AllocatingRequestMatcherBase(Server* server, grpc_completion_queue* cq)
|
700
324
|
: server_(server), cq_(cq) {
|
701
325
|
size_t idx;
|
702
|
-
for (idx = 0; idx < server->
|
703
|
-
if (server->
|
326
|
+
for (idx = 0; idx < server->cqs_.size(); idx++) {
|
327
|
+
if (server->cqs_[idx] == cq) {
|
704
328
|
break;
|
705
329
|
}
|
706
330
|
}
|
707
|
-
GPR_ASSERT(idx < server->
|
331
|
+
GPR_ASSERT(idx < server->cqs_.size());
|
708
332
|
cq_idx_ = idx;
|
709
333
|
}
|
710
334
|
|
@@ -715,11 +339,11 @@ class AllocatingRequestMatcherBase : public RequestMatcherInterface {
|
|
715
339
|
size_t request_queue_count() const override { return 0; }
|
716
340
|
|
717
341
|
void RequestCallWithPossiblePublish(size_t /*request_queue_index*/,
|
718
|
-
|
342
|
+
RequestedCall* /*call*/) final {
|
719
343
|
GPR_ASSERT(false);
|
720
344
|
}
|
721
345
|
|
722
|
-
|
346
|
+
Server* server() const override { return server_; }
|
723
347
|
|
724
348
|
// Supply the completion queue related to this request matcher
|
725
349
|
grpc_completion_queue* cq() const { return cq_; }
|
@@ -728,433 +352,746 @@ class AllocatingRequestMatcherBase : public RequestMatcherInterface {
|
|
728
352
|
size_t cq_idx() const { return cq_idx_; }
|
729
353
|
|
730
354
|
private:
|
731
|
-
|
355
|
+
Server* const server_;
|
732
356
|
grpc_completion_queue* const cq_;
|
733
357
|
size_t cq_idx_;
|
734
358
|
};
|
735
359
|
|
736
360
|
// An allocating request matcher for non-registered methods (used for generic
|
737
361
|
// API and unimplemented RPCs).
|
738
|
-
class AllocatingRequestMatcherBatch
|
362
|
+
class Server::AllocatingRequestMatcherBatch
|
363
|
+
: public AllocatingRequestMatcherBase {
|
739
364
|
public:
|
740
|
-
AllocatingRequestMatcherBatch(
|
741
|
-
|
742
|
-
std::function<ServerBatchCallAllocation()> allocator)
|
365
|
+
AllocatingRequestMatcherBatch(Server* server, grpc_completion_queue* cq,
|
366
|
+
std::function<BatchCallAllocation()> allocator)
|
743
367
|
: AllocatingRequestMatcherBase(server, cq),
|
744
368
|
allocator_(std::move(allocator)) {}
|
369
|
+
|
745
370
|
void MatchOrQueue(size_t /*start_request_queue_index*/,
|
746
|
-
|
747
|
-
|
748
|
-
GPR_ASSERT(
|
749
|
-
|
750
|
-
|
371
|
+
CallData* calld) override {
|
372
|
+
BatchCallAllocation call_info = allocator_();
|
373
|
+
GPR_ASSERT(server()->ValidateServerRequest(
|
374
|
+
cq(), static_cast<void*>(call_info.tag), nullptr, nullptr) ==
|
375
|
+
GRPC_CALL_OK);
|
376
|
+
RequestedCall* rc = new RequestedCall(
|
751
377
|
static_cast<void*>(call_info.tag), cq(), call_info.call,
|
752
378
|
call_info.initial_metadata, call_info.details);
|
753
|
-
calld->
|
754
|
-
|
379
|
+
calld->SetState(CallData::CallState::ACTIVATED);
|
380
|
+
calld->Publish(cq_idx(), rc);
|
755
381
|
}
|
756
382
|
|
757
383
|
private:
|
758
|
-
std::function<
|
384
|
+
std::function<BatchCallAllocation()> allocator_;
|
759
385
|
};
|
760
386
|
|
761
387
|
// An allocating request matcher for registered methods.
|
762
|
-
class AllocatingRequestMatcherRegistered
|
388
|
+
class Server::AllocatingRequestMatcherRegistered
|
389
|
+
: public AllocatingRequestMatcherBase {
|
763
390
|
public:
|
764
391
|
AllocatingRequestMatcherRegistered(
|
765
|
-
|
766
|
-
std::function<
|
392
|
+
Server* server, grpc_completion_queue* cq, RegisteredMethod* rm,
|
393
|
+
std::function<RegisteredCallAllocation()> allocator)
|
767
394
|
: AllocatingRequestMatcherBase(server, cq),
|
768
395
|
registered_method_(rm),
|
769
396
|
allocator_(std::move(allocator)) {}
|
397
|
+
|
770
398
|
void MatchOrQueue(size_t /*start_request_queue_index*/,
|
771
|
-
|
772
|
-
|
773
|
-
GPR_ASSERT(
|
774
|
-
|
775
|
-
|
776
|
-
|
399
|
+
CallData* calld) override {
|
400
|
+
RegisteredCallAllocation call_info = allocator_();
|
401
|
+
GPR_ASSERT(
|
402
|
+
server()->ValidateServerRequest(cq(), static_cast<void*>(call_info.tag),
|
403
|
+
call_info.optional_payload,
|
404
|
+
registered_method_) == GRPC_CALL_OK);
|
405
|
+
RequestedCall* rc = new RequestedCall(
|
777
406
|
static_cast<void*>(call_info.tag), cq(), call_info.call,
|
778
407
|
call_info.initial_metadata, registered_method_, call_info.deadline,
|
779
408
|
call_info.optional_payload);
|
780
|
-
calld->
|
781
|
-
|
409
|
+
calld->SetState(CallData::CallState::ACTIVATED);
|
410
|
+
calld->Publish(cq_idx(), rc);
|
782
411
|
}
|
783
412
|
|
784
413
|
private:
|
785
|
-
|
786
|
-
std::function<
|
414
|
+
RegisteredMethod* const registered_method_;
|
415
|
+
std::function<RegisteredCallAllocation()> allocator_;
|
787
416
|
};
|
788
417
|
|
789
|
-
|
790
|
-
|
791
|
-
|
418
|
+
//
|
419
|
+
// ChannelBroadcaster
|
420
|
+
//
|
421
|
+
|
422
|
+
namespace {
|
792
423
|
|
793
|
-
|
424
|
+
class ChannelBroadcaster {
|
425
|
+
public:
|
426
|
+
// This can have an empty constructor and destructor since we want to control
|
427
|
+
// when the actual setup and shutdown broadcast take place.
|
794
428
|
|
795
|
-
|
796
|
-
|
797
|
-
|
429
|
+
// Copies over the channels from the locked server.
|
430
|
+
void FillChannelsLocked(std::vector<grpc_channel*> channels) {
|
431
|
+
GPR_DEBUG_ASSERT(channels_.empty());
|
432
|
+
channels_ = std::move(channels);
|
798
433
|
}
|
799
|
-
}
|
800
434
|
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
}
|
435
|
+
// Broadcasts a shutdown on each channel.
|
436
|
+
void BroadcastShutdown(bool send_goaway, grpc_error* force_disconnect) {
|
437
|
+
for (grpc_channel* channel : channels_) {
|
438
|
+
SendShutdown(channel, send_goaway, GRPC_ERROR_REF(force_disconnect));
|
439
|
+
GRPC_CHANNEL_INTERNAL_UNREF(channel, "broadcast");
|
440
|
+
}
|
441
|
+
channels_.clear(); // just for safety against double broadcast
|
442
|
+
GRPC_ERROR_UNREF(force_disconnect);
|
443
|
+
}
|
807
444
|
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
server_ref(chand->server);
|
814
|
-
maybe_finish_shutdown(chand->server);
|
815
|
-
GRPC_CLOSURE_INIT(&chand->finish_destroy_channel_closure,
|
816
|
-
finish_destroy_channel, chand, grpc_schedule_on_exec_ctx);
|
445
|
+
private:
|
446
|
+
struct ShutdownCleanupArgs {
|
447
|
+
grpc_closure closure;
|
448
|
+
grpc_slice slice;
|
449
|
+
};
|
817
450
|
|
818
|
-
|
819
|
-
|
451
|
+
static void ShutdownCleanup(void* arg, grpc_error* /*error*/) {
|
452
|
+
ShutdownCleanupArgs* a = static_cast<ShutdownCleanupArgs*>(arg);
|
453
|
+
grpc_slice_unref_internal(a->slice);
|
454
|
+
delete a;
|
820
455
|
}
|
821
456
|
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
457
|
+
static void SendShutdown(grpc_channel* channel, bool send_goaway,
|
458
|
+
grpc_error* send_disconnect) {
|
459
|
+
ShutdownCleanupArgs* sc = new ShutdownCleanupArgs;
|
460
|
+
GRPC_CLOSURE_INIT(&sc->closure, ShutdownCleanup, sc,
|
461
|
+
grpc_schedule_on_exec_ctx);
|
462
|
+
grpc_transport_op* op = grpc_make_transport_op(&sc->closure);
|
463
|
+
grpc_channel_element* elem;
|
464
|
+
op->goaway_error =
|
465
|
+
send_goaway
|
466
|
+
? grpc_error_set_int(
|
467
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown"),
|
468
|
+
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_OK)
|
469
|
+
: GRPC_ERROR_NONE;
|
470
|
+
op->set_accept_stream = true;
|
471
|
+
sc->slice = grpc_slice_from_copied_string("Server shutdown");
|
472
|
+
op->disconnect_with_error = send_disconnect;
|
473
|
+
elem =
|
474
|
+
grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
|
475
|
+
elem->filter->start_transport_op(elem, op);
|
476
|
+
}
|
829
477
|
|
830
|
-
|
831
|
-
|
832
|
-
}
|
478
|
+
std::vector<grpc_channel*> channels_;
|
479
|
+
};
|
833
480
|
|
834
|
-
|
835
|
-
requested_call* rc) {
|
836
|
-
grpc_call_set_completion_queue(calld->call, rc->cq_bound_to_call);
|
837
|
-
grpc_call* call = calld->call;
|
838
|
-
*rc->call = call;
|
839
|
-
calld->cq_new = server->cqs[cq_idx];
|
840
|
-
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, calld->initial_metadata);
|
841
|
-
switch (rc->type) {
|
842
|
-
case RequestedCallType::BATCH_CALL:
|
843
|
-
GPR_ASSERT(calld->host_set);
|
844
|
-
GPR_ASSERT(calld->path_set);
|
845
|
-
rc->data.batch.details->host = grpc_slice_ref_internal(calld->host);
|
846
|
-
rc->data.batch.details->method = grpc_slice_ref_internal(calld->path);
|
847
|
-
rc->data.batch.details->deadline =
|
848
|
-
grpc_millis_to_timespec(calld->deadline, GPR_CLOCK_MONOTONIC);
|
849
|
-
rc->data.batch.details->flags = calld->recv_initial_metadata_flags;
|
850
|
-
break;
|
851
|
-
case RequestedCallType::REGISTERED_CALL:
|
852
|
-
*rc->data.registered.deadline =
|
853
|
-
grpc_millis_to_timespec(calld->deadline, GPR_CLOCK_MONOTONIC);
|
854
|
-
if (rc->data.registered.optional_payload) {
|
855
|
-
*rc->data.registered.optional_payload = calld->payload;
|
856
|
-
calld->payload = nullptr;
|
857
|
-
}
|
858
|
-
break;
|
859
|
-
default:
|
860
|
-
GPR_UNREACHABLE_CODE(return );
|
861
|
-
}
|
481
|
+
} // namespace
|
862
482
|
|
863
|
-
|
864
|
-
|
865
|
-
|
483
|
+
//
|
484
|
+
// Server
|
485
|
+
//
|
866
486
|
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
487
|
+
const grpc_channel_filter Server::kServerTopFilter = {
|
488
|
+
Server::CallData::StartTransportStreamOpBatch,
|
489
|
+
grpc_channel_next_op,
|
490
|
+
sizeof(Server::CallData),
|
491
|
+
Server::CallData::InitCallElement,
|
492
|
+
grpc_call_stack_ignore_set_pollset_or_pollset_set,
|
493
|
+
Server::CallData::DestroyCallElement,
|
494
|
+
sizeof(Server::ChannelData),
|
495
|
+
Server::ChannelData::InitChannelElement,
|
496
|
+
Server::ChannelData::DestroyChannelElement,
|
497
|
+
grpc_channel_next_get_info,
|
498
|
+
"server",
|
499
|
+
};
|
873
500
|
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
return;
|
501
|
+
namespace {
|
502
|
+
|
503
|
+
grpc_resource_user* CreateDefaultResourceUser(const grpc_channel_args* args) {
|
504
|
+
if (args != nullptr) {
|
505
|
+
grpc_resource_quota* resource_quota =
|
506
|
+
grpc_resource_quota_from_channel_args(args, false /* create */);
|
507
|
+
if (resource_quota != nullptr) {
|
508
|
+
return grpc_resource_user_create(resource_quota, "default");
|
509
|
+
}
|
884
510
|
}
|
511
|
+
return nullptr;
|
512
|
+
}
|
885
513
|
|
886
|
-
|
514
|
+
RefCountedPtr<channelz::ServerNode> CreateChannelzNode(
|
515
|
+
Server* server, const grpc_channel_args* args) {
|
516
|
+
RefCountedPtr<channelz::ServerNode> channelz_node;
|
517
|
+
if (grpc_channel_args_find_bool(args, GRPC_ARG_ENABLE_CHANNELZ,
|
518
|
+
GRPC_ENABLE_CHANNELZ_DEFAULT)) {
|
519
|
+
size_t channel_tracer_max_memory = grpc_channel_args_find_integer(
|
520
|
+
args, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE,
|
521
|
+
{GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX});
|
522
|
+
channelz_node =
|
523
|
+
MakeRefCounted<channelz::ServerNode>(channel_tracer_max_memory);
|
524
|
+
channelz_node->AddTraceEvent(
|
525
|
+
channelz::ChannelTrace::Severity::Info,
|
526
|
+
grpc_slice_from_static_string("Server created"));
|
527
|
+
}
|
528
|
+
return channelz_node;
|
887
529
|
}
|
888
530
|
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
531
|
+
} // namespace
|
532
|
+
|
533
|
+
Server::Server(const grpc_channel_args* args)
|
534
|
+
: channel_args_(grpc_channel_args_copy(args)),
|
535
|
+
default_resource_user_(CreateDefaultResourceUser(args)),
|
536
|
+
channelz_node_(CreateChannelzNode(this, args)) {}
|
893
537
|
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
ExecCtx::Run(DEBUG_LOCATION, &calld->kill_zombie_closure, GRPC_ERROR_NONE);
|
899
|
-
return;
|
538
|
+
Server::~Server() {
|
539
|
+
grpc_channel_args_destroy(channel_args_);
|
540
|
+
for (size_t i = 0; i < cqs_.size(); i++) {
|
541
|
+
GRPC_CQ_INTERNAL_UNREF(cqs_[i], "server");
|
900
542
|
}
|
543
|
+
}
|
901
544
|
|
902
|
-
|
545
|
+
void Server::AddListener(OrphanablePtr<ListenerInterface> listener) {
|
546
|
+
channelz::ListenSocketNode* listen_socket_node =
|
547
|
+
listener->channelz_listen_socket_node();
|
548
|
+
if (listen_socket_node != nullptr && channelz_node_ != nullptr) {
|
549
|
+
channelz_node_->AddChildListenSocket(listen_socket_node->Ref());
|
550
|
+
}
|
551
|
+
listeners_.emplace_back(std::move(listener));
|
552
|
+
}
|
903
553
|
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
break;
|
554
|
+
void Server::Start() {
|
555
|
+
started_ = true;
|
556
|
+
for (grpc_completion_queue* cq : cqs_) {
|
557
|
+
if (grpc_cq_can_listen(cq)) {
|
558
|
+
pollsets_.push_back(grpc_cq_pollset(cq));
|
559
|
+
}
|
560
|
+
}
|
561
|
+
if (unregistered_request_matcher_ == nullptr) {
|
562
|
+
unregistered_request_matcher_ = absl::make_unique<RealRequestMatcher>(this);
|
563
|
+
}
|
564
|
+
for (std::unique_ptr<RegisteredMethod>& rm : registered_methods_) {
|
565
|
+
if (rm->matcher == nullptr) {
|
566
|
+
rm->matcher = absl::make_unique<RealRequestMatcher>(this);
|
918
567
|
}
|
919
568
|
}
|
569
|
+
{
|
570
|
+
MutexLock lock(&mu_global_);
|
571
|
+
starting_ = true;
|
572
|
+
}
|
573
|
+
for (auto& listener : listeners_) {
|
574
|
+
listener.listener->Start(this, &pollsets_);
|
575
|
+
}
|
576
|
+
MutexLock lock(&mu_global_);
|
577
|
+
starting_ = false;
|
578
|
+
starting_cv_.Signal();
|
920
579
|
}
|
921
580
|
|
922
|
-
void
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
chand->registered_methods->size()];
|
938
|
-
if (rm->server_registered_method == nullptr) break;
|
939
|
-
if (!rm->has_host) continue;
|
940
|
-
if (rm->host != calld->host) continue;
|
941
|
-
if (rm->method != calld->path) continue;
|
942
|
-
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
|
943
|
-
0 == (calld->recv_initial_metadata_flags &
|
944
|
-
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST)) {
|
945
|
-
continue;
|
946
|
-
}
|
947
|
-
finish_start_new_rpc(server, elem,
|
948
|
-
rm->server_registered_method->matcher.get(),
|
949
|
-
rm->server_registered_method->payload_handling);
|
950
|
-
return;
|
951
|
-
}
|
952
|
-
/* check for a wildcard method definition (no host set) */
|
953
|
-
hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash_internal(calld->path));
|
954
|
-
for (i = 0; i <= chand->registered_method_max_probes; i++) {
|
955
|
-
rm = &(*chand->registered_methods)[(hash + i) %
|
956
|
-
chand->registered_methods->size()];
|
957
|
-
if (rm->server_registered_method == nullptr) break;
|
958
|
-
if (rm->has_host) continue;
|
959
|
-
if (rm->method != calld->path) continue;
|
960
|
-
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
|
961
|
-
0 == (calld->recv_initial_metadata_flags &
|
962
|
-
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST)) {
|
963
|
-
continue;
|
964
|
-
}
|
965
|
-
finish_start_new_rpc(server, elem,
|
966
|
-
rm->server_registered_method->matcher.get(),
|
967
|
-
rm->server_registered_method->payload_handling);
|
968
|
-
return;
|
969
|
-
}
|
581
|
+
void Server::SetupTransport(
|
582
|
+
grpc_transport* transport, grpc_pollset* accepting_pollset,
|
583
|
+
const grpc_channel_args* args,
|
584
|
+
const RefCountedPtr<grpc_core::channelz::SocketNode>& socket_node,
|
585
|
+
grpc_resource_user* resource_user) {
|
586
|
+
// Create channel.
|
587
|
+
grpc_channel* channel = grpc_channel_create(
|
588
|
+
nullptr, args, GRPC_SERVER_CHANNEL, transport, resource_user);
|
589
|
+
ChannelData* chand = static_cast<ChannelData*>(
|
590
|
+
grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0)
|
591
|
+
->channel_data);
|
592
|
+
// Set up CQs.
|
593
|
+
size_t cq_idx;
|
594
|
+
for (cq_idx = 0; cq_idx < cqs_.size(); cq_idx++) {
|
595
|
+
if (grpc_cq_pollset(cqs_[cq_idx]) == accepting_pollset) break;
|
970
596
|
}
|
971
|
-
|
972
|
-
|
597
|
+
if (cq_idx == cqs_.size()) {
|
598
|
+
// Completion queue not found. Pick a random one to publish new calls to.
|
599
|
+
cq_idx = static_cast<size_t>(rand()) % cqs_.size();
|
600
|
+
}
|
601
|
+
// Set up channelz node.
|
602
|
+
intptr_t channelz_socket_uuid = 0;
|
603
|
+
if (socket_node != nullptr) {
|
604
|
+
channelz_socket_uuid = socket_node->uuid();
|
605
|
+
channelz_node_->AddChildSocket(socket_node);
|
606
|
+
}
|
607
|
+
// Initialize chand.
|
608
|
+
chand->InitTransport(Ref(), channel, cq_idx, transport, channelz_socket_uuid);
|
609
|
+
}
|
610
|
+
|
611
|
+
bool Server::HasOpenConnections() {
|
612
|
+
MutexLock lock(&mu_global_);
|
613
|
+
return !channels_.empty();
|
973
614
|
}
|
974
615
|
|
975
|
-
void
|
976
|
-
|
616
|
+
void Server::SetRegisteredMethodAllocator(
|
617
|
+
grpc_completion_queue* cq, void* method_tag,
|
618
|
+
std::function<RegisteredCallAllocation()> allocator) {
|
619
|
+
RegisteredMethod* rm = static_cast<RegisteredMethod*>(method_tag);
|
620
|
+
rm->matcher = absl::make_unique<AllocatingRequestMatcherRegistered>(
|
621
|
+
this, cq, rm, std::move(allocator));
|
977
622
|
}
|
978
623
|
|
979
|
-
|
624
|
+
void Server::SetBatchMethodAllocator(
|
625
|
+
grpc_completion_queue* cq, std::function<BatchCallAllocation()> allocator) {
|
626
|
+
GPR_DEBUG_ASSERT(unregistered_request_matcher_ == nullptr);
|
627
|
+
unregistered_request_matcher_ =
|
628
|
+
absl::make_unique<AllocatingRequestMatcherBatch>(this, cq,
|
629
|
+
std::move(allocator));
|
630
|
+
}
|
980
631
|
|
981
|
-
void
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
632
|
+
void Server::RegisterCompletionQueue(grpc_completion_queue* cq) {
|
633
|
+
for (grpc_completion_queue* queue : cqs_) {
|
634
|
+
if (queue == cq) return;
|
635
|
+
}
|
636
|
+
GRPC_CQ_INTERNAL_REF(cq, "server");
|
637
|
+
cqs_.push_back(cq);
|
638
|
+
}
|
639
|
+
|
640
|
+
namespace {
|
641
|
+
|
642
|
+
bool streq(const std::string& a, const char* b) {
|
643
|
+
return (a.empty() && b == nullptr) ||
|
644
|
+
((b != nullptr) && !strcmp(a.c_str(), b));
|
645
|
+
}
|
646
|
+
|
647
|
+
} // namespace
|
648
|
+
|
649
|
+
Server::RegisteredMethod* Server::RegisterMethod(
|
650
|
+
const char* method, const char* host,
|
651
|
+
grpc_server_register_method_payload_handling payload_handling,
|
652
|
+
uint32_t flags) {
|
653
|
+
if (!method) {
|
654
|
+
gpr_log(GPR_ERROR,
|
655
|
+
"grpc_server_register_method method string cannot be NULL");
|
656
|
+
return nullptr;
|
657
|
+
}
|
658
|
+
for (std::unique_ptr<RegisteredMethod>& m : registered_methods_) {
|
659
|
+
if (streq(m->method, method) && streq(m->host, host)) {
|
660
|
+
gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
|
661
|
+
host ? host : "*");
|
662
|
+
return nullptr;
|
988
663
|
}
|
989
664
|
}
|
990
|
-
|
665
|
+
if ((flags & ~GRPC_INITIAL_METADATA_USED_MASK) != 0) {
|
666
|
+
gpr_log(GPR_ERROR, "grpc_server_register_method invalid flags 0x%08x",
|
667
|
+
flags);
|
668
|
+
return nullptr;
|
669
|
+
}
|
670
|
+
registered_methods_.emplace_back(absl::make_unique<RegisteredMethod>(
|
671
|
+
method, host, payload_handling, flags));
|
672
|
+
return registered_methods_.back().get();
|
673
|
+
}
|
674
|
+
|
675
|
+
void Server::DoneRequestEvent(void* req, grpc_cq_completion* /*c*/) {
|
676
|
+
delete static_cast<RequestedCall*>(req);
|
991
677
|
}
|
992
678
|
|
993
|
-
void
|
994
|
-
|
995
|
-
|
996
|
-
|
679
|
+
void Server::FailCall(size_t cq_idx, RequestedCall* rc, grpc_error* error) {
|
680
|
+
*rc->call = nullptr;
|
681
|
+
rc->initial_metadata->count = 0;
|
682
|
+
GPR_ASSERT(error != GRPC_ERROR_NONE);
|
683
|
+
grpc_cq_end_op(cqs_[cq_idx], rc->tag, error, DoneRequestEvent, rc,
|
684
|
+
&rc->completion);
|
685
|
+
}
|
686
|
+
|
687
|
+
// Before calling MaybeFinishShutdown(), we must hold mu_global_ and not
|
688
|
+
// hold mu_call_.
|
689
|
+
void Server::MaybeFinishShutdown() {
|
690
|
+
if (!shutdown_flag_.load(std::memory_order_acquire) || shutdown_published_) {
|
997
691
|
return;
|
998
692
|
}
|
999
|
-
|
1000
693
|
{
|
1001
|
-
MutexLock lock(&
|
1002
|
-
|
1003
|
-
|
694
|
+
MutexLock lock(&mu_call_);
|
695
|
+
KillPendingWorkLocked(
|
696
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
|
1004
697
|
}
|
1005
|
-
|
1006
|
-
if (!server->channels.empty() ||
|
1007
|
-
server->listeners_destroyed < server->listeners.size()) {
|
698
|
+
if (!channels_.empty() || listeners_destroyed_ < listeners_.size()) {
|
1008
699
|
if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME),
|
1009
|
-
|
700
|
+
last_shutdown_message_time_),
|
1010
701
|
gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) {
|
1011
|
-
|
702
|
+
last_shutdown_message_time_ = gpr_now(GPR_CLOCK_REALTIME);
|
1012
703
|
gpr_log(GPR_DEBUG,
|
1013
|
-
"Waiting for %
|
704
|
+
"Waiting for %" PRIuPTR " channels and %" PRIuPTR "/%" PRIuPTR
|
1014
705
|
" listeners to be destroyed before shutting down server",
|
1015
|
-
|
1016
|
-
|
1017
|
-
server->listeners.size());
|
706
|
+
channels_.size(), listeners_.size() - listeners_destroyed_,
|
707
|
+
listeners_.size());
|
1018
708
|
}
|
1019
709
|
return;
|
1020
710
|
}
|
1021
|
-
|
1022
|
-
for (
|
1023
|
-
|
1024
|
-
grpc_cq_end_op(
|
1025
|
-
|
1026
|
-
&server->shutdown_tags[i].completion);
|
711
|
+
shutdown_published_ = true;
|
712
|
+
for (auto& shutdown_tag : shutdown_tags_) {
|
713
|
+
Ref().release();
|
714
|
+
grpc_cq_end_op(shutdown_tag.cq, shutdown_tag.tag, GRPC_ERROR_NONE,
|
715
|
+
DoneShutdownEvent, this, &shutdown_tag.completion);
|
1027
716
|
}
|
1028
717
|
}
|
1029
718
|
|
1030
|
-
void
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
719
|
+
void Server::KillPendingWorkLocked(grpc_error* error) {
|
720
|
+
if (started_) {
|
721
|
+
unregistered_request_matcher_->KillRequests(GRPC_ERROR_REF(error));
|
722
|
+
unregistered_request_matcher_->ZombifyPending();
|
723
|
+
for (std::unique_ptr<RegisteredMethod>& rm : registered_methods_) {
|
724
|
+
rm->matcher->KillRequests(GRPC_ERROR_REF(error));
|
725
|
+
rm->matcher->ZombifyPending();
|
726
|
+
}
|
727
|
+
}
|
728
|
+
GRPC_ERROR_UNREF(error);
|
729
|
+
}
|
1034
730
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
calld->host = grpc_slice_ref_internal(
|
1042
|
-
GRPC_MDVALUE(calld->recv_initial_metadata->idx.named.authority->md));
|
1043
|
-
calld->path_set = true;
|
1044
|
-
calld->host_set = true;
|
1045
|
-
grpc_metadata_batch_remove(calld->recv_initial_metadata, GRPC_BATCH_PATH);
|
1046
|
-
grpc_metadata_batch_remove(calld->recv_initial_metadata,
|
1047
|
-
GRPC_BATCH_AUTHORITY);
|
1048
|
-
} else {
|
1049
|
-
GRPC_ERROR_REF(error);
|
731
|
+
std::vector<grpc_channel*> Server::GetChannelsLocked() const {
|
732
|
+
std::vector<grpc_channel*> channels;
|
733
|
+
channels.reserve(channels_.size());
|
734
|
+
for (const ChannelData* chand : channels_) {
|
735
|
+
channels.push_back(chand->channel());
|
736
|
+
GRPC_CHANNEL_INTERNAL_REF(chand->channel(), "broadcast");
|
1050
737
|
}
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
738
|
+
return channels;
|
739
|
+
}
|
740
|
+
|
741
|
+
void Server::ListenerDestroyDone(void* arg, grpc_error* /*error*/) {
|
742
|
+
Server* server = static_cast<Server*>(arg);
|
743
|
+
MutexLock lock(&server->mu_global_);
|
744
|
+
server->listeners_destroyed_++;
|
745
|
+
server->MaybeFinishShutdown();
|
746
|
+
}
|
747
|
+
|
748
|
+
namespace {
|
749
|
+
|
750
|
+
void DonePublishedShutdown(void* /*done_arg*/, grpc_cq_completion* storage) {
|
751
|
+
delete storage;
|
752
|
+
}
|
753
|
+
|
754
|
+
} // namespace
|
755
|
+
|
756
|
+
// - Kills all pending requests-for-incoming-RPC-calls (i.e., the requests made
|
757
|
+
// via grpc_server_request_call() and grpc_server_request_registered_call()
|
758
|
+
// will now be cancelled). See KillPendingWorkLocked().
|
759
|
+
//
|
760
|
+
// - Shuts down the listeners (i.e., the server will no longer listen on the
|
761
|
+
// port for new incoming channels).
|
762
|
+
//
|
763
|
+
// - Iterates through all channels on the server and sends shutdown msg (see
|
764
|
+
// ChannelBroadcaster::BroadcastShutdown() for details) to the clients via
|
765
|
+
// the transport layer. The transport layer then guarantees the following:
|
766
|
+
// -- Sends shutdown to the client (e.g., HTTP2 transport sends GOAWAY).
|
767
|
+
// -- If the server has outstanding calls that are in the process, the
|
768
|
+
// connection is NOT closed until the server is done with all those calls.
|
769
|
+
// -- Once there are no more calls in progress, the channel is closed.
|
770
|
+
void Server::ShutdownAndNotify(grpc_completion_queue* cq, void* tag) {
|
771
|
+
ChannelBroadcaster broadcaster;
|
772
|
+
{
|
773
|
+
// Wait for startup to be finished. Locks mu_global.
|
774
|
+
MutexLock lock(&mu_global_);
|
775
|
+
starting_cv_.WaitUntil(&mu_global_, [this] { return !starting_; });
|
776
|
+
// Stay locked, and gather up some stuff to do.
|
777
|
+
GPR_ASSERT(grpc_cq_begin_op(cq, tag));
|
778
|
+
if (shutdown_published_) {
|
779
|
+
grpc_cq_end_op(cq, tag, GRPC_ERROR_NONE, DonePublishedShutdown, nullptr,
|
780
|
+
new grpc_cq_completion);
|
781
|
+
return;
|
782
|
+
}
|
783
|
+
shutdown_tags_.emplace_back(tag, cq);
|
784
|
+
if (shutdown_flag_.load(std::memory_order_acquire)) {
|
785
|
+
return;
|
786
|
+
}
|
787
|
+
last_shutdown_message_time_ = gpr_now(GPR_CLOCK_REALTIME);
|
788
|
+
broadcaster.FillChannelsLocked(GetChannelsLocked());
|
789
|
+
shutdown_flag_.store(true, std::memory_order_release);
|
790
|
+
// Collect all unregistered then registered calls.
|
791
|
+
{
|
792
|
+
MutexLock lock(&mu_call_);
|
793
|
+
KillPendingWorkLocked(
|
794
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
|
795
|
+
}
|
796
|
+
MaybeFinishShutdown();
|
1054
797
|
}
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
798
|
+
// Shutdown listeners.
|
799
|
+
for (auto& listener : listeners_) {
|
800
|
+
channelz::ListenSocketNode* channelz_listen_socket_node =
|
801
|
+
listener.listener->channelz_listen_socket_node();
|
802
|
+
if (channelz_node_ != nullptr && channelz_listen_socket_node != nullptr) {
|
803
|
+
channelz_node_->RemoveChildListenSocket(
|
804
|
+
channelz_listen_socket_node->uuid());
|
805
|
+
}
|
806
|
+
GRPC_CLOSURE_INIT(&listener.destroy_done, ListenerDestroyDone, this,
|
807
|
+
grpc_schedule_on_exec_ctx);
|
808
|
+
listener.listener->SetOnDestroyDone(&listener.destroy_done);
|
809
|
+
listener.listener.reset();
|
1064
810
|
}
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
811
|
+
broadcaster.BroadcastShutdown(/*send_goaway=*/true, GRPC_ERROR_NONE);
|
812
|
+
}
|
813
|
+
|
814
|
+
void Server::CancelAllCalls() {
|
815
|
+
ChannelBroadcaster broadcaster;
|
816
|
+
{
|
817
|
+
MutexLock lock(&mu_global_);
|
818
|
+
broadcaster.FillChannelsLocked(GetChannelsLocked());
|
1072
819
|
}
|
1073
|
-
|
820
|
+
broadcaster.BroadcastShutdown(
|
821
|
+
/*send_goaway=*/false,
|
822
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Cancelling all calls"));
|
1074
823
|
}
|
1075
824
|
|
1076
|
-
void
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready,
|
1083
|
-
server_recv_trailing_metadata_ready, elem,
|
1084
|
-
grpc_schedule_on_exec_ctx);
|
1085
|
-
GRPC_CALL_COMBINER_STOP(calld->call_combiner,
|
1086
|
-
"deferring server_recv_trailing_metadata_ready "
|
1087
|
-
"until after server_on_recv_initial_metadata");
|
1088
|
-
return;
|
825
|
+
void Server::Orphan() {
|
826
|
+
{
|
827
|
+
MutexLock lock(&mu_global_);
|
828
|
+
GPR_ASSERT(shutdown_flag_.load(std::memory_order_acquire) ||
|
829
|
+
listeners_.empty());
|
830
|
+
GPR_ASSERT(listeners_destroyed_ == listeners_.size());
|
1089
831
|
}
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
832
|
+
if (default_resource_user_ != nullptr) {
|
833
|
+
grpc_resource_quota_unref(grpc_resource_user_quota(default_resource_user_));
|
834
|
+
grpc_resource_user_shutdown(default_resource_user_);
|
835
|
+
grpc_resource_user_unref(default_resource_user_);
|
836
|
+
}
|
837
|
+
Unref();
|
838
|
+
}
|
839
|
+
|
840
|
+
grpc_call_error Server::ValidateServerRequest(
|
841
|
+
grpc_completion_queue* cq_for_notification, void* tag,
|
842
|
+
grpc_byte_buffer** optional_payload, RegisteredMethod* rm) {
|
843
|
+
if ((rm == nullptr && optional_payload != nullptr) ||
|
844
|
+
((rm != nullptr) && ((optional_payload == nullptr) !=
|
845
|
+
(rm->payload_handling == GRPC_SRM_PAYLOAD_NONE)))) {
|
846
|
+
return GRPC_CALL_ERROR_PAYLOAD_TYPE_MISMATCH;
|
847
|
+
}
|
848
|
+
if (grpc_cq_begin_op(cq_for_notification, tag) == false) {
|
849
|
+
return GRPC_CALL_ERROR_COMPLETION_QUEUE_SHUTDOWN;
|
850
|
+
}
|
851
|
+
return GRPC_CALL_OK;
|
1095
852
|
}
|
1096
853
|
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
&calld->on_recv_initial_metadata;
|
1109
|
-
op->payload->recv_initial_metadata.recv_flags =
|
1110
|
-
&calld->recv_initial_metadata_flags;
|
1111
|
-
}
|
1112
|
-
if (op->recv_trailing_metadata) {
|
1113
|
-
calld->original_recv_trailing_metadata_ready =
|
1114
|
-
op->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
|
1115
|
-
op->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
|
1116
|
-
&calld->recv_trailing_metadata_ready;
|
854
|
+
grpc_call_error Server::ValidateServerRequestAndCq(
|
855
|
+
size_t* cq_idx, grpc_completion_queue* cq_for_notification, void* tag,
|
856
|
+
grpc_byte_buffer** optional_payload, RegisteredMethod* rm) {
|
857
|
+
size_t idx;
|
858
|
+
for (idx = 0; idx < cqs_.size(); idx++) {
|
859
|
+
if (cqs_[idx] == cq_for_notification) {
|
860
|
+
break;
|
861
|
+
}
|
862
|
+
}
|
863
|
+
if (idx == cqs_.size()) {
|
864
|
+
return GRPC_CALL_ERROR_NOT_SERVER_COMPLETION_QUEUE;
|
1117
865
|
}
|
866
|
+
grpc_call_error error =
|
867
|
+
ValidateServerRequest(cq_for_notification, tag, optional_payload, rm);
|
868
|
+
if (error != GRPC_CALL_OK) {
|
869
|
+
return error;
|
870
|
+
}
|
871
|
+
*cq_idx = idx;
|
872
|
+
return GRPC_CALL_OK;
|
1118
873
|
}
|
1119
874
|
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
875
|
+
grpc_call_error Server::QueueRequestedCall(size_t cq_idx, RequestedCall* rc) {
|
876
|
+
if (shutdown_flag_.load(std::memory_order_acquire)) {
|
877
|
+
FailCall(cq_idx, rc,
|
878
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
|
879
|
+
return GRPC_CALL_OK;
|
880
|
+
}
|
881
|
+
RequestMatcherInterface* rm;
|
882
|
+
switch (rc->type) {
|
883
|
+
case RequestedCall::Type::BATCH_CALL:
|
884
|
+
rm = unregistered_request_matcher_.get();
|
885
|
+
break;
|
886
|
+
case RequestedCall::Type::REGISTERED_CALL:
|
887
|
+
rm = rc->data.registered.method->matcher.get();
|
888
|
+
break;
|
889
|
+
}
|
890
|
+
rm->RequestCallWithPossiblePublish(cq_idx, rc);
|
891
|
+
return GRPC_CALL_OK;
|
1124
892
|
}
|
1125
893
|
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
894
|
+
grpc_call_error Server::RequestCall(grpc_call** call,
|
895
|
+
grpc_call_details* details,
|
896
|
+
grpc_metadata_array* request_metadata,
|
897
|
+
grpc_completion_queue* cq_bound_to_call,
|
898
|
+
grpc_completion_queue* cq_for_notification,
|
899
|
+
void* tag) {
|
900
|
+
size_t cq_idx;
|
901
|
+
grpc_call_error error = ValidateServerRequestAndCq(
|
902
|
+
&cq_idx, cq_for_notification, tag, nullptr, nullptr);
|
903
|
+
if (error != GRPC_CALL_OK) {
|
904
|
+
return error;
|
905
|
+
}
|
906
|
+
RequestedCall* rc =
|
907
|
+
new RequestedCall(tag, cq_bound_to_call, call, request_metadata, details);
|
908
|
+
return QueueRequestedCall(cq_idx, rc);
|
909
|
+
}
|
910
|
+
|
911
|
+
grpc_call_error Server::RequestRegisteredCall(
|
912
|
+
RegisteredMethod* rm, grpc_call** call, gpr_timespec* deadline,
|
913
|
+
grpc_metadata_array* request_metadata, grpc_byte_buffer** optional_payload,
|
914
|
+
grpc_completion_queue* cq_bound_to_call,
|
915
|
+
grpc_completion_queue* cq_for_notification, void* tag_new) {
|
916
|
+
size_t cq_idx;
|
917
|
+
grpc_call_error error = ValidateServerRequestAndCq(
|
918
|
+
&cq_idx, cq_for_notification, tag_new, optional_payload, rm);
|
919
|
+
if (error != GRPC_CALL_OK) {
|
920
|
+
return error;
|
921
|
+
}
|
922
|
+
RequestedCall* rc =
|
923
|
+
new RequestedCall(tag_new, cq_bound_to_call, call, request_metadata, rm,
|
924
|
+
deadline, optional_payload);
|
925
|
+
return QueueRequestedCall(cq_idx, rc);
|
926
|
+
}
|
927
|
+
|
928
|
+
//
|
929
|
+
// Server::ChannelData::ConnectivityWatcher
|
930
|
+
//
|
931
|
+
|
932
|
+
class Server::ChannelData::ConnectivityWatcher
|
933
|
+
: public AsyncConnectivityStateWatcherInterface {
|
934
|
+
public:
|
935
|
+
explicit ConnectivityWatcher(ChannelData* chand) : chand_(chand) {
|
936
|
+
GRPC_CHANNEL_INTERNAL_REF(chand_->channel_, "connectivity");
|
937
|
+
}
|
938
|
+
|
939
|
+
~ConnectivityWatcher() {
|
940
|
+
GRPC_CHANNEL_INTERNAL_UNREF(chand_->channel_, "connectivity");
|
941
|
+
}
|
942
|
+
|
943
|
+
private:
|
944
|
+
void OnConnectivityStateChange(grpc_connectivity_state new_state,
|
945
|
+
const absl::Status& /*status*/) override {
|
946
|
+
// Don't do anything until we are being shut down.
|
947
|
+
if (new_state != GRPC_CHANNEL_SHUTDOWN) return;
|
948
|
+
// Shut down channel.
|
949
|
+
MutexLock lock(&chand_->server_->mu_global_);
|
950
|
+
chand_->Destroy();
|
951
|
+
}
|
952
|
+
|
953
|
+
ChannelData* chand_;
|
954
|
+
};
|
955
|
+
|
956
|
+
//
|
957
|
+
// Server::ChannelData
|
958
|
+
//
|
959
|
+
|
960
|
+
Server::ChannelData::~ChannelData() {
|
961
|
+
if (registered_methods_ != nullptr) {
|
962
|
+
for (const ChannelRegisteredMethod& crm : *registered_methods_) {
|
963
|
+
grpc_slice_unref_internal(crm.method);
|
964
|
+
GPR_DEBUG_ASSERT(crm.method.refcount == &kNoopRefcount ||
|
965
|
+
crm.method.refcount == nullptr);
|
966
|
+
if (crm.has_host) {
|
967
|
+
grpc_slice_unref_internal(crm.host);
|
968
|
+
GPR_DEBUG_ASSERT(crm.host.refcount == &kNoopRefcount ||
|
969
|
+
crm.host.refcount == nullptr);
|
970
|
+
}
|
971
|
+
}
|
972
|
+
registered_methods_.reset();
|
973
|
+
}
|
974
|
+
if (server_ != nullptr) {
|
975
|
+
if (server_->channelz_node_ != nullptr && channelz_socket_uuid_ != 0) {
|
976
|
+
server_->channelz_node_->RemoveChildSocket(channelz_socket_uuid_);
|
977
|
+
}
|
978
|
+
{
|
979
|
+
MutexLock lock(&server_->mu_global_);
|
980
|
+
if (list_position_.has_value()) {
|
981
|
+
server_->channels_.erase(*list_position_);
|
982
|
+
list_position_.reset();
|
983
|
+
}
|
984
|
+
server_->MaybeFinishShutdown();
|
985
|
+
}
|
986
|
+
}
|
987
|
+
}
|
988
|
+
|
989
|
+
void Server::ChannelData::InitTransport(RefCountedPtr<Server> server,
|
990
|
+
grpc_channel* channel, size_t cq_idx,
|
991
|
+
grpc_transport* transport,
|
992
|
+
intptr_t channelz_socket_uuid) {
|
993
|
+
server_ = std::move(server);
|
994
|
+
channel_ = channel;
|
995
|
+
cq_idx_ = cq_idx;
|
996
|
+
channelz_socket_uuid_ = channelz_socket_uuid;
|
997
|
+
// Build a lookup table phrased in terms of mdstr's in this channels context
|
998
|
+
// to quickly find registered methods.
|
999
|
+
size_t num_registered_methods = server_->registered_methods_.size();
|
1000
|
+
if (num_registered_methods > 0) {
|
1001
|
+
uint32_t max_probes = 0;
|
1002
|
+
size_t slots = 2 * num_registered_methods;
|
1003
|
+
registered_methods_.reset(new std::vector<ChannelRegisteredMethod>(slots));
|
1004
|
+
for (std::unique_ptr<RegisteredMethod>& rm : server_->registered_methods_) {
|
1005
|
+
ExternallyManagedSlice host;
|
1006
|
+
ExternallyManagedSlice method(rm->method.c_str());
|
1007
|
+
const bool has_host = !rm->host.empty();
|
1008
|
+
if (has_host) {
|
1009
|
+
host = ExternallyManagedSlice(rm->host.c_str());
|
1010
|
+
}
|
1011
|
+
uint32_t hash =
|
1012
|
+
GRPC_MDSTR_KV_HASH(has_host ? host.Hash() : 0, method.Hash());
|
1013
|
+
uint32_t probes = 0;
|
1014
|
+
for (probes = 0; (*registered_methods_)[(hash + probes) % slots]
|
1015
|
+
.server_registered_method != nullptr;
|
1016
|
+
probes++) {
|
1017
|
+
}
|
1018
|
+
if (probes > max_probes) max_probes = probes;
|
1019
|
+
ChannelRegisteredMethod* crm =
|
1020
|
+
&(*registered_methods_)[(hash + probes) % slots];
|
1021
|
+
crm->server_registered_method = rm.get();
|
1022
|
+
crm->flags = rm->flags;
|
1023
|
+
crm->has_host = has_host;
|
1024
|
+
if (has_host) {
|
1025
|
+
crm->host = host;
|
1026
|
+
}
|
1027
|
+
crm->method = method;
|
1028
|
+
}
|
1029
|
+
GPR_ASSERT(slots <= UINT32_MAX);
|
1030
|
+
registered_method_max_probes_ = max_probes;
|
1031
|
+
}
|
1032
|
+
// Publish channel.
|
1033
|
+
{
|
1034
|
+
MutexLock lock(&server_->mu_global_);
|
1035
|
+
server_->channels_.push_front(this);
|
1036
|
+
list_position_ = server_->channels_.begin();
|
1037
|
+
}
|
1038
|
+
// Start accept_stream transport op.
|
1039
|
+
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
1040
|
+
op->set_accept_stream = true;
|
1041
|
+
op->set_accept_stream_fn = AcceptStream;
|
1042
|
+
op->set_accept_stream_user_data = this;
|
1043
|
+
op->start_connectivity_watch = MakeOrphanable<ConnectivityWatcher>(this);
|
1044
|
+
if (server_->shutdown_flag_.load(std::memory_order_acquire)) {
|
1045
|
+
op->disconnect_with_error =
|
1046
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown");
|
1047
|
+
}
|
1048
|
+
grpc_transport_perform_op(transport, op);
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
Server::ChannelRegisteredMethod* Server::ChannelData::GetRegisteredMethod(
|
1052
|
+
const grpc_slice& host, const grpc_slice& path, bool is_idempotent) {
|
1053
|
+
if (registered_methods_ == nullptr) return nullptr;
|
1054
|
+
/* TODO(ctiller): unify these two searches */
|
1055
|
+
/* check for an exact match with host */
|
1056
|
+
uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash_internal(host),
|
1057
|
+
grpc_slice_hash_internal(path));
|
1058
|
+
for (size_t i = 0; i <= registered_method_max_probes_; i++) {
|
1059
|
+
ChannelRegisteredMethod* rm =
|
1060
|
+
&(*registered_methods_)[(hash + i) % registered_methods_->size()];
|
1061
|
+
if (rm->server_registered_method == nullptr) break;
|
1062
|
+
if (!rm->has_host) continue;
|
1063
|
+
if (rm->host != host) continue;
|
1064
|
+
if (rm->method != path) continue;
|
1065
|
+
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
|
1066
|
+
!is_idempotent) {
|
1067
|
+
continue;
|
1147
1068
|
}
|
1069
|
+
return rm;
|
1070
|
+
}
|
1071
|
+
/* check for a wildcard method definition (no host set) */
|
1072
|
+
hash = GRPC_MDSTR_KV_HASH(0, grpc_slice_hash_internal(path));
|
1073
|
+
for (size_t i = 0; i <= registered_method_max_probes_; i++) {
|
1074
|
+
ChannelRegisteredMethod* rm =
|
1075
|
+
&(*registered_methods_)[(hash + i) % registered_methods_->size()];
|
1076
|
+
if (rm->server_registered_method == nullptr) break;
|
1077
|
+
if (rm->has_host) continue;
|
1078
|
+
if (rm->method != path) continue;
|
1079
|
+
if ((rm->flags & GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) &&
|
1080
|
+
!is_idempotent) {
|
1081
|
+
continue;
|
1082
|
+
}
|
1083
|
+
return rm;
|
1148
1084
|
}
|
1085
|
+
return nullptr;
|
1149
1086
|
}
|
1150
1087
|
|
1151
|
-
void
|
1152
|
-
|
1153
|
-
|
1088
|
+
void Server::ChannelData::AcceptStream(void* arg, grpc_transport* /*transport*/,
|
1089
|
+
const void* transport_server_data) {
|
1090
|
+
auto* chand = static_cast<Server::ChannelData*>(arg);
|
1154
1091
|
/* create a call */
|
1155
1092
|
grpc_call_create_args args;
|
1156
|
-
args.channel = chand->
|
1157
|
-
args.server = chand->
|
1093
|
+
args.channel = chand->channel_;
|
1094
|
+
args.server = chand->server_.get();
|
1158
1095
|
args.parent = nullptr;
|
1159
1096
|
args.propagation_mask = 0;
|
1160
1097
|
args.cq = nullptr;
|
@@ -1167,199 +1104,353 @@ void accept_stream(void* cd, grpc_transport* /*transport*/,
|
|
1167
1104
|
grpc_error* error = grpc_call_create(&args, &call);
|
1168
1105
|
grpc_call_element* elem =
|
1169
1106
|
grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
|
1107
|
+
auto* calld = static_cast<Server::CallData*>(elem->call_data);
|
1170
1108
|
if (error != GRPC_ERROR_NONE) {
|
1171
|
-
got_initial_metadata(elem, error);
|
1172
1109
|
GRPC_ERROR_UNREF(error);
|
1110
|
+
calld->FailCallCreation();
|
1173
1111
|
return;
|
1174
1112
|
}
|
1175
|
-
|
1176
|
-
grpc_op op;
|
1177
|
-
op.op = GRPC_OP_RECV_INITIAL_METADATA;
|
1178
|
-
op.flags = 0;
|
1179
|
-
op.reserved = nullptr;
|
1180
|
-
op.data.recv_initial_metadata.recv_initial_metadata =
|
1181
|
-
&calld->initial_metadata;
|
1182
|
-
GRPC_CLOSURE_INIT(&calld->got_initial_metadata, got_initial_metadata, elem,
|
1183
|
-
grpc_schedule_on_exec_ctx);
|
1184
|
-
grpc_call_start_batch_and_execute(call, &op, 1, &calld->got_initial_metadata);
|
1113
|
+
calld->Start(elem);
|
1185
1114
|
}
|
1186
1115
|
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
return GRPC_ERROR_NONE;
|
1116
|
+
void Server::ChannelData::FinishDestroy(void* cd, grpc_error* /*error*/) {
|
1117
|
+
auto* chand = static_cast<Server::ChannelData*>(cd);
|
1118
|
+
Server* server = chand->server_.get();
|
1119
|
+
GRPC_CHANNEL_INTERNAL_UNREF(chand->channel_, "server");
|
1120
|
+
server->Unref();
|
1193
1121
|
}
|
1194
1122
|
|
1195
|
-
void
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1123
|
+
void Server::ChannelData::Destroy() {
|
1124
|
+
if (!list_position_.has_value()) return;
|
1125
|
+
GPR_ASSERT(server_ != nullptr);
|
1126
|
+
server_->channels_.erase(*list_position_);
|
1127
|
+
list_position_.reset();
|
1128
|
+
server_->Ref().release();
|
1129
|
+
server_->MaybeFinishShutdown();
|
1130
|
+
GRPC_CLOSURE_INIT(&finish_destroy_channel_closure_, FinishDestroy, this,
|
1131
|
+
grpc_schedule_on_exec_ctx);
|
1132
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_server_channel_trace)) {
|
1133
|
+
gpr_log(GPR_INFO, "Disconnected client");
|
1134
|
+
}
|
1135
|
+
grpc_transport_op* op =
|
1136
|
+
grpc_make_transport_op(&finish_destroy_channel_closure_);
|
1137
|
+
op->set_accept_stream = true;
|
1138
|
+
grpc_channel_next_op(
|
1139
|
+
grpc_channel_stack_element(grpc_channel_get_channel_stack(channel_), 0),
|
1140
|
+
op);
|
1202
1141
|
}
|
1203
1142
|
|
1204
|
-
grpc_error*
|
1205
|
-
|
1143
|
+
grpc_error* Server::ChannelData::InitChannelElement(
|
1144
|
+
grpc_channel_element* elem, grpc_channel_element_args* args) {
|
1206
1145
|
GPR_ASSERT(args->is_first);
|
1207
|
-
GPR_ASSERT(!args->is_last);
|
1208
|
-
|
1209
|
-
|
1210
|
-
return GRPC_ERROR_NONE;
|
1211
|
-
}
|
1212
|
-
|
1213
|
-
channel_data::~channel_data() {
|
1214
|
-
if (registered_methods) {
|
1215
|
-
for (const channel_registered_method& crm : *registered_methods) {
|
1216
|
-
grpc_slice_unref_internal(crm.method);
|
1217
|
-
GPR_DEBUG_ASSERT(crm.method.refcount == &kNoopRefcount ||
|
1218
|
-
crm.method.refcount == nullptr);
|
1219
|
-
if (crm.has_host) {
|
1220
|
-
grpc_slice_unref_internal(crm.host);
|
1221
|
-
GPR_DEBUG_ASSERT(crm.host.refcount == &kNoopRefcount ||
|
1222
|
-
crm.host.refcount == nullptr);
|
1223
|
-
}
|
1224
|
-
}
|
1225
|
-
}
|
1226
|
-
if (server) {
|
1227
|
-
if (server->channelz_server != nullptr && channelz_socket_uuid != 0) {
|
1228
|
-
server->channelz_server->RemoveChildSocket(channelz_socket_uuid);
|
1229
|
-
}
|
1230
|
-
{
|
1231
|
-
MutexLock lock(&server->mu_global);
|
1232
|
-
if (list_position.has_value()) {
|
1233
|
-
server->channels.erase(*list_position);
|
1234
|
-
}
|
1235
|
-
maybe_finish_shutdown(server);
|
1236
|
-
}
|
1237
|
-
server_unref(server);
|
1238
|
-
}
|
1146
|
+
GPR_ASSERT(!args->is_last);
|
1147
|
+
new (elem->channel_data) ChannelData();
|
1148
|
+
return GRPC_ERROR_NONE;
|
1239
1149
|
}
|
1240
1150
|
|
1241
|
-
void
|
1242
|
-
|
1243
|
-
chand->~
|
1151
|
+
void Server::ChannelData::DestroyChannelElement(grpc_channel_element* elem) {
|
1152
|
+
auto* chand = static_cast<ChannelData*>(elem->channel_data);
|
1153
|
+
chand->~ChannelData();
|
1244
1154
|
}
|
1245
1155
|
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1156
|
+
//
|
1157
|
+
// Server::CallData
|
1158
|
+
//
|
1159
|
+
|
1160
|
+
Server::CallData::CallData(grpc_call_element* elem,
|
1161
|
+
const grpc_call_element_args& args,
|
1162
|
+
RefCountedPtr<Server> server)
|
1163
|
+
: server_(std::move(server)),
|
1164
|
+
call_(grpc_call_from_top_element(elem)),
|
1165
|
+
call_combiner_(args.call_combiner) {
|
1166
|
+
GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady,
|
1167
|
+
elem, grpc_schedule_on_exec_ctx);
|
1168
|
+
GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady,
|
1169
|
+
elem, grpc_schedule_on_exec_ctx);
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
Server::CallData::~CallData() {
|
1173
|
+
GPR_ASSERT(state_.Load(MemoryOrder::RELAXED) != CallState::PENDING);
|
1174
|
+
GRPC_ERROR_UNREF(recv_initial_metadata_error_);
|
1175
|
+
if (host_.has_value()) {
|
1176
|
+
grpc_slice_unref_internal(*host_);
|
1252
1177
|
}
|
1178
|
+
if (path_.has_value()) {
|
1179
|
+
grpc_slice_unref_internal(*path_);
|
1180
|
+
}
|
1181
|
+
grpc_metadata_array_destroy(&initial_metadata_);
|
1182
|
+
grpc_byte_buffer_destroy(payload_);
|
1183
|
+
}
|
1253
1184
|
|
1254
|
-
|
1255
|
-
|
1185
|
+
void Server::CallData::SetState(CallState state) {
|
1186
|
+
state_.Store(state, MemoryOrder::RELAXED);
|
1256
1187
|
}
|
1257
1188
|
|
1258
|
-
bool
|
1259
|
-
|
1260
|
-
|
1189
|
+
bool Server::CallData::MaybeActivate() {
|
1190
|
+
CallState expected = CallState::PENDING;
|
1191
|
+
return state_.CompareExchangeStrong(&expected, CallState::ACTIVATED,
|
1192
|
+
MemoryOrder::ACQ_REL,
|
1193
|
+
MemoryOrder::RELAXED);
|
1261
1194
|
}
|
1262
1195
|
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1196
|
+
void Server::CallData::FailCallCreation() {
|
1197
|
+
CallState expected_not_started = CallState::NOT_STARTED;
|
1198
|
+
CallState expected_pending = CallState::PENDING;
|
1199
|
+
if (state_.CompareExchangeStrong(&expected_not_started, CallState::ZOMBIED,
|
1200
|
+
MemoryOrder::ACQ_REL,
|
1201
|
+
MemoryOrder::ACQUIRE)) {
|
1202
|
+
KillZombie();
|
1203
|
+
} else if (state_.CompareExchangeStrong(&expected_pending, CallState::ZOMBIED,
|
1204
|
+
MemoryOrder::ACQ_REL,
|
1205
|
+
MemoryOrder::RELAXED)) {
|
1206
|
+
// Zombied call will be destroyed when it's removed from the pending
|
1207
|
+
// queue... later.
|
1267
1208
|
}
|
1209
|
+
}
|
1268
1210
|
|
1269
|
-
|
1270
|
-
|
1211
|
+
void Server::CallData::Start(grpc_call_element* elem) {
|
1212
|
+
grpc_op op;
|
1213
|
+
op.op = GRPC_OP_RECV_INITIAL_METADATA;
|
1214
|
+
op.flags = 0;
|
1215
|
+
op.reserved = nullptr;
|
1216
|
+
op.data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_;
|
1217
|
+
GRPC_CLOSURE_INIT(&recv_initial_metadata_batch_complete_,
|
1218
|
+
RecvInitialMetadataBatchComplete, elem,
|
1219
|
+
grpc_schedule_on_exec_ctx);
|
1220
|
+
grpc_call_start_batch_and_execute(call_, &op, 1,
|
1221
|
+
&recv_initial_metadata_batch_complete_);
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
void Server::CallData::Publish(size_t cq_idx, RequestedCall* rc) {
|
1225
|
+
grpc_call_set_completion_queue(call_, rc->cq_bound_to_call);
|
1226
|
+
*rc->call = call_;
|
1227
|
+
cq_new_ = server_->cqs_[cq_idx];
|
1228
|
+
GPR_SWAP(grpc_metadata_array, *rc->initial_metadata, initial_metadata_);
|
1229
|
+
switch (rc->type) {
|
1230
|
+
case RequestedCall::Type::BATCH_CALL:
|
1231
|
+
GPR_ASSERT(host_.has_value());
|
1232
|
+
GPR_ASSERT(path_.has_value());
|
1233
|
+
rc->data.batch.details->host = grpc_slice_ref_internal(*host_);
|
1234
|
+
rc->data.batch.details->method = grpc_slice_ref_internal(*path_);
|
1235
|
+
rc->data.batch.details->deadline =
|
1236
|
+
grpc_millis_to_timespec(deadline_, GPR_CLOCK_MONOTONIC);
|
1237
|
+
rc->data.batch.details->flags = recv_initial_metadata_flags_;
|
1238
|
+
break;
|
1239
|
+
case RequestedCall::Type::REGISTERED_CALL:
|
1240
|
+
*rc->data.registered.deadline =
|
1241
|
+
grpc_millis_to_timespec(deadline_, GPR_CLOCK_MONOTONIC);
|
1242
|
+
if (rc->data.registered.optional_payload != nullptr) {
|
1243
|
+
*rc->data.registered.optional_payload = payload_;
|
1244
|
+
payload_ = nullptr;
|
1245
|
+
}
|
1246
|
+
break;
|
1247
|
+
default:
|
1248
|
+
GPR_UNREACHABLE_CODE(return );
|
1271
1249
|
}
|
1250
|
+
grpc_cq_end_op(cq_new_, rc->tag, GRPC_ERROR_NONE, Server::DoneRequestEvent,
|
1251
|
+
rc, &rc->completion, true);
|
1252
|
+
}
|
1272
1253
|
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1254
|
+
void Server::CallData::PublishNewRpc(void* arg, grpc_error* error) {
|
1255
|
+
grpc_call_element* call_elem = static_cast<grpc_call_element*>(arg);
|
1256
|
+
auto* calld = static_cast<Server::CallData*>(call_elem->call_data);
|
1257
|
+
auto* chand = static_cast<Server::ChannelData*>(call_elem->channel_data);
|
1258
|
+
RequestMatcherInterface* rm = calld->matcher_;
|
1259
|
+
Server* server = rm->server();
|
1260
|
+
if (error != GRPC_ERROR_NONE ||
|
1261
|
+
server->shutdown_flag_.load(std::memory_order_acquire)) {
|
1262
|
+
calld->state_.Store(CallState::ZOMBIED, MemoryOrder::RELAXED);
|
1263
|
+
calld->KillZombie();
|
1264
|
+
return;
|
1281
1265
|
}
|
1266
|
+
rm->MatchOrQueue(chand->cq_idx(), calld);
|
1267
|
+
}
|
1282
1268
|
|
1283
|
-
|
1284
|
-
};
|
1269
|
+
namespace {
|
1285
1270
|
|
1286
|
-
void
|
1287
|
-
|
1271
|
+
void KillZombieClosure(void* call, grpc_error* /*error*/) {
|
1272
|
+
grpc_call_unref(static_cast<grpc_call*>(call));
|
1288
1273
|
}
|
1289
1274
|
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1275
|
+
} // namespace
|
1276
|
+
|
1277
|
+
void Server::CallData::KillZombie() {
|
1278
|
+
GRPC_CLOSURE_INIT(&kill_zombie_closure_, KillZombieClosure, call_,
|
1279
|
+
grpc_schedule_on_exec_ctx);
|
1280
|
+
ExecCtx::Run(DEBUG_LOCATION, &kill_zombie_closure_, GRPC_ERROR_NONE);
|
1295
1281
|
}
|
1296
1282
|
|
1297
|
-
|
1298
|
-
|
1299
|
-
if (
|
1300
|
-
|
1301
|
-
|
1302
|
-
return
|
1283
|
+
void Server::CallData::StartNewRpc(grpc_call_element* elem) {
|
1284
|
+
auto* chand = static_cast<ChannelData*>(elem->channel_data);
|
1285
|
+
if (server_->shutdown_flag_.load(std::memory_order_acquire)) {
|
1286
|
+
state_.Store(CallState::ZOMBIED, MemoryOrder::RELAXED);
|
1287
|
+
KillZombie();
|
1288
|
+
return;
|
1303
1289
|
}
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1290
|
+
// Find request matcher.
|
1291
|
+
matcher_ = server_->unregistered_request_matcher_.get();
|
1292
|
+
grpc_server_register_method_payload_handling payload_handling =
|
1293
|
+
GRPC_SRM_PAYLOAD_NONE;
|
1294
|
+
if (path_.has_value() && host_.has_value()) {
|
1295
|
+
ChannelRegisteredMethod* rm =
|
1296
|
+
chand->GetRegisteredMethod(*host_, *path_,
|
1297
|
+
(recv_initial_metadata_flags_ &
|
1298
|
+
GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST));
|
1299
|
+
if (rm != nullptr) {
|
1300
|
+
matcher_ = rm->server_registered_method->matcher.get();
|
1301
|
+
payload_handling = rm->server_registered_method->payload_handling;
|
1302
|
+
}
|
1303
|
+
}
|
1304
|
+
// Start recv_message op if needed.
|
1305
|
+
switch (payload_handling) {
|
1306
|
+
case GRPC_SRM_PAYLOAD_NONE:
|
1307
|
+
PublishNewRpc(elem, GRPC_ERROR_NONE);
|
1308
1308
|
break;
|
1309
|
-
case
|
1310
|
-
|
1309
|
+
case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: {
|
1310
|
+
grpc_op op;
|
1311
|
+
op.op = GRPC_OP_RECV_MESSAGE;
|
1312
|
+
op.flags = 0;
|
1313
|
+
op.reserved = nullptr;
|
1314
|
+
op.data.recv_message.recv_message = &payload_;
|
1315
|
+
GRPC_CLOSURE_INIT(&publish_, PublishNewRpc, elem,
|
1316
|
+
grpc_schedule_on_exec_ctx);
|
1317
|
+
grpc_call_start_batch_and_execute(call_, &op, 1, &publish_);
|
1311
1318
|
break;
|
1319
|
+
}
|
1312
1320
|
}
|
1313
|
-
rm->RequestCallWithPossiblePublish(cq_idx, rc);
|
1314
|
-
return GRPC_CALL_OK;
|
1315
1321
|
}
|
1316
1322
|
|
1317
|
-
void
|
1318
|
-
|
1319
|
-
*
|
1320
|
-
|
1321
|
-
|
1323
|
+
void Server::CallData::RecvInitialMetadataBatchComplete(void* arg,
|
1324
|
+
grpc_error* error) {
|
1325
|
+
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
|
1326
|
+
auto* calld = static_cast<Server::CallData*>(elem->call_data);
|
1327
|
+
if (error != GRPC_ERROR_NONE) {
|
1328
|
+
calld->FailCallCreation();
|
1329
|
+
return;
|
1330
|
+
}
|
1331
|
+
calld->StartNewRpc(elem);
|
1332
|
+
}
|
1322
1333
|
|
1323
|
-
|
1324
|
-
|
1334
|
+
void Server::CallData::StartTransportStreamOpBatchImpl(
|
1335
|
+
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
|
1336
|
+
if (batch->recv_initial_metadata) {
|
1337
|
+
GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr);
|
1338
|
+
recv_initial_metadata_ =
|
1339
|
+
batch->payload->recv_initial_metadata.recv_initial_metadata;
|
1340
|
+
original_recv_initial_metadata_ready_ =
|
1341
|
+
batch->payload->recv_initial_metadata.recv_initial_metadata_ready;
|
1342
|
+
batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
|
1343
|
+
&recv_initial_metadata_ready_;
|
1344
|
+
batch->payload->recv_initial_metadata.recv_flags =
|
1345
|
+
&recv_initial_metadata_flags_;
|
1346
|
+
}
|
1347
|
+
if (batch->recv_trailing_metadata) {
|
1348
|
+
original_recv_trailing_metadata_ready_ =
|
1349
|
+
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
|
1350
|
+
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
|
1351
|
+
&recv_trailing_metadata_ready_;
|
1352
|
+
}
|
1353
|
+
grpc_call_next_op(elem, batch);
|
1325
1354
|
}
|
1326
1355
|
|
1327
|
-
|
1356
|
+
void Server::CallData::RecvInitialMetadataReady(void* ptr, grpc_error* error) {
|
1357
|
+
grpc_call_element* elem = static_cast<grpc_call_element*>(ptr);
|
1358
|
+
CallData* calld = static_cast<CallData*>(elem->call_data);
|
1359
|
+
grpc_millis op_deadline;
|
1360
|
+
if (error == GRPC_ERROR_NONE) {
|
1361
|
+
GPR_DEBUG_ASSERT(calld->recv_initial_metadata_->idx.named.path != nullptr);
|
1362
|
+
GPR_DEBUG_ASSERT(calld->recv_initial_metadata_->idx.named.authority !=
|
1363
|
+
nullptr);
|
1364
|
+
calld->path_.emplace(grpc_slice_ref_internal(
|
1365
|
+
GRPC_MDVALUE(calld->recv_initial_metadata_->idx.named.path->md)));
|
1366
|
+
calld->host_.emplace(grpc_slice_ref_internal(
|
1367
|
+
GRPC_MDVALUE(calld->recv_initial_metadata_->idx.named.authority->md)));
|
1368
|
+
grpc_metadata_batch_remove(calld->recv_initial_metadata_, GRPC_BATCH_PATH);
|
1369
|
+
grpc_metadata_batch_remove(calld->recv_initial_metadata_,
|
1370
|
+
GRPC_BATCH_AUTHORITY);
|
1371
|
+
} else {
|
1372
|
+
GRPC_ERROR_REF(error);
|
1373
|
+
}
|
1374
|
+
op_deadline = calld->recv_initial_metadata_->deadline;
|
1375
|
+
if (op_deadline != GRPC_MILLIS_INF_FUTURE) {
|
1376
|
+
calld->deadline_ = op_deadline;
|
1377
|
+
}
|
1378
|
+
if (calld->host_.has_value() && calld->path_.has_value()) {
|
1379
|
+
/* do nothing */
|
1380
|
+
} else {
|
1381
|
+
/* Pass the error reference to calld->recv_initial_metadata_error */
|
1382
|
+
grpc_error* src_error = error;
|
1383
|
+
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
1384
|
+
"Missing :authority or :path", &src_error, 1);
|
1385
|
+
GRPC_ERROR_UNREF(src_error);
|
1386
|
+
calld->recv_initial_metadata_error_ = GRPC_ERROR_REF(error);
|
1387
|
+
}
|
1388
|
+
grpc_closure* closure = calld->original_recv_initial_metadata_ready_;
|
1389
|
+
calld->original_recv_initial_metadata_ready_ = nullptr;
|
1390
|
+
if (calld->seen_recv_trailing_metadata_ready_) {
|
1391
|
+
GRPC_CALL_COMBINER_START(calld->call_combiner_,
|
1392
|
+
&calld->recv_trailing_metadata_ready_,
|
1393
|
+
calld->recv_trailing_metadata_error_,
|
1394
|
+
"continue server recv_trailing_metadata_ready");
|
1395
|
+
}
|
1396
|
+
Closure::Run(DEBUG_LOCATION, closure, error);
|
1397
|
+
}
|
1328
1398
|
|
1329
|
-
void
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1399
|
+
void Server::CallData::RecvTrailingMetadataReady(void* user_data,
|
1400
|
+
grpc_error* error) {
|
1401
|
+
grpc_call_element* elem = static_cast<grpc_call_element*>(user_data);
|
1402
|
+
CallData* calld = static_cast<CallData*>(elem->call_data);
|
1403
|
+
if (calld->original_recv_initial_metadata_ready_ != nullptr) {
|
1404
|
+
calld->recv_trailing_metadata_error_ = GRPC_ERROR_REF(error);
|
1405
|
+
calld->seen_recv_trailing_metadata_ready_ = true;
|
1406
|
+
GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_,
|
1407
|
+
RecvTrailingMetadataReady, elem,
|
1408
|
+
grpc_schedule_on_exec_ctx);
|
1409
|
+
GRPC_CALL_COMBINER_STOP(calld->call_combiner_,
|
1410
|
+
"deferring server recv_trailing_metadata_ready "
|
1411
|
+
"until after recv_initial_metadata_ready");
|
1412
|
+
return;
|
1413
|
+
}
|
1414
|
+
error =
|
1415
|
+
grpc_error_add_child(GRPC_ERROR_REF(error),
|
1416
|
+
GRPC_ERROR_REF(calld->recv_initial_metadata_error_));
|
1417
|
+
Closure::Run(DEBUG_LOCATION, calld->original_recv_trailing_metadata_ready_,
|
1418
|
+
error);
|
1335
1419
|
}
|
1336
1420
|
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1421
|
+
grpc_error* Server::CallData::InitCallElement(
|
1422
|
+
grpc_call_element* elem, const grpc_call_element_args* args) {
|
1423
|
+
auto* chand = static_cast<ChannelData*>(elem->channel_data);
|
1424
|
+
new (elem->call_data) Server::CallData(elem, *args, chand->server());
|
1425
|
+
return GRPC_ERROR_NONE;
|
1426
|
+
}
|
1427
|
+
|
1428
|
+
void Server::CallData::DestroyCallElement(
|
1429
|
+
grpc_call_element* elem, const grpc_call_final_info* /*final_info*/,
|
1430
|
+
grpc_closure* /*ignored*/) {
|
1431
|
+
auto* calld = static_cast<CallData*>(elem->call_data);
|
1432
|
+
calld->~CallData();
|
1433
|
+
}
|
1434
|
+
|
1435
|
+
void Server::CallData::StartTransportStreamOpBatch(
|
1436
|
+
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
|
1437
|
+
auto* calld = static_cast<CallData*>(elem->call_data);
|
1438
|
+
calld->StartTransportStreamOpBatchImpl(elem, batch);
|
1344
1439
|
}
|
1345
1440
|
|
1346
1441
|
} // namespace grpc_core
|
1347
1442
|
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
sizeof(grpc_core::call_data),
|
1352
|
-
grpc_core::server_init_call_elem,
|
1353
|
-
grpc_call_stack_ignore_set_pollset_or_pollset_set,
|
1354
|
-
grpc_core::server_destroy_call_elem,
|
1355
|
-
sizeof(grpc_core::channel_data),
|
1356
|
-
grpc_core::server_init_channel_elem,
|
1357
|
-
grpc_core::server_destroy_channel_elem,
|
1358
|
-
grpc_channel_next_get_info,
|
1359
|
-
"server",
|
1360
|
-
};
|
1443
|
+
//
|
1444
|
+
// C-core API
|
1445
|
+
//
|
1361
1446
|
|
1362
|
-
|
1447
|
+
grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) {
|
1448
|
+
grpc_core::ExecCtx exec_ctx;
|
1449
|
+
GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
|
1450
|
+
grpc_server* c_server = new grpc_server;
|
1451
|
+
c_server->core_server = grpc_core::MakeOrphanable<grpc_core::Server>(args);
|
1452
|
+
return c_server;
|
1453
|
+
}
|
1363
1454
|
|
1364
1455
|
void grpc_server_register_completion_queue(grpc_server* server,
|
1365
1456
|
grpc_completion_queue* cq,
|
@@ -1367,7 +1458,7 @@ void grpc_server_register_completion_queue(grpc_server* server,
|
|
1367
1458
|
GRPC_API_TRACE(
|
1368
1459
|
"grpc_server_register_completion_queue(server=%p, cq=%p, reserved=%p)", 3,
|
1369
1460
|
(server, cq, reserved));
|
1370
|
-
|
1461
|
+
GPR_ASSERT(!reserved);
|
1371
1462
|
auto cq_type = grpc_get_cq_completion_type(cq);
|
1372
1463
|
if (cq_type != GRPC_CQ_NEXT && cq_type != GRPC_CQ_CALLBACK) {
|
1373
1464
|
gpr_log(GPR_INFO,
|
@@ -1377,15 +1468,7 @@ void grpc_server_register_completion_queue(grpc_server* server,
|
|
1377
1468
|
/* Ideally we should log an error and abort but ruby-wrapped-language API
|
1378
1469
|
calls grpc_completion_queue_pluck() on server completion queues */
|
1379
1470
|
}
|
1380
|
-
|
1381
|
-
grpc_core::register_completion_queue(server, cq, reserved);
|
1382
|
-
}
|
1383
|
-
|
1384
|
-
grpc_server* grpc_server_create(const grpc_channel_args* args, void* reserved) {
|
1385
|
-
grpc_core::ExecCtx exec_ctx;
|
1386
|
-
GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
|
1387
|
-
|
1388
|
-
return new grpc_server(args);
|
1471
|
+
server->core_server->RegisterCompletionQueue(cq);
|
1389
1472
|
}
|
1390
1473
|
|
1391
1474
|
void* grpc_server_register_method(
|
@@ -1396,285 +1479,42 @@ void* grpc_server_register_method(
|
|
1396
1479
|
"grpc_server_register_method(server=%p, method=%s, host=%s, "
|
1397
1480
|
"flags=0x%08x)",
|
1398
1481
|
4, (server, method, host, flags));
|
1399
|
-
|
1400
|
-
|
1401
|
-
"grpc_server_register_method method string cannot be NULL");
|
1402
|
-
return nullptr;
|
1403
|
-
}
|
1404
|
-
for (std::unique_ptr<grpc_core::registered_method>& m :
|
1405
|
-
server->registered_methods) {
|
1406
|
-
if (grpc_core::streq(m->method, method) &&
|
1407
|
-
grpc_core::streq(m->host, host)) {
|
1408
|
-
gpr_log(GPR_ERROR, "duplicate registration for %s@%s", method,
|
1409
|
-
host ? host : "*");
|
1410
|
-
return nullptr;
|
1411
|
-
}
|
1412
|
-
}
|
1413
|
-
if ((flags & ~GRPC_INITIAL_METADATA_USED_MASK) != 0) {
|
1414
|
-
gpr_log(GPR_ERROR, "grpc_server_register_method invalid flags 0x%08x",
|
1415
|
-
flags);
|
1416
|
-
return nullptr;
|
1417
|
-
}
|
1418
|
-
server->registered_methods.emplace_back(
|
1419
|
-
new grpc_core::registered_method(method, host, payload_handling, flags));
|
1420
|
-
return static_cast<void*>(server->registered_methods.back().get());
|
1482
|
+
return server->core_server->RegisterMethod(method, host, payload_handling,
|
1483
|
+
flags);
|
1421
1484
|
}
|
1422
1485
|
|
1423
1486
|
void grpc_server_start(grpc_server* server) {
|
1424
|
-
size_t i;
|
1425
1487
|
grpc_core::ExecCtx exec_ctx;
|
1426
|
-
|
1427
1488
|
GRPC_API_TRACE("grpc_server_start(server=%p)", 1, (server));
|
1428
|
-
|
1429
|
-
server->started = true;
|
1430
|
-
for (i = 0; i < server->cqs.size(); i++) {
|
1431
|
-
if (grpc_cq_can_listen(server->cqs[i])) {
|
1432
|
-
server->pollsets.push_back(grpc_cq_pollset(server->cqs[i]));
|
1433
|
-
}
|
1434
|
-
}
|
1435
|
-
if (server->unregistered_request_matcher == nullptr) {
|
1436
|
-
server->unregistered_request_matcher =
|
1437
|
-
absl::make_unique<grpc_core::RealRequestMatcher>(server);
|
1438
|
-
}
|
1439
|
-
for (std::unique_ptr<grpc_core::registered_method>& rm :
|
1440
|
-
server->registered_methods) {
|
1441
|
-
if (rm->matcher == nullptr) {
|
1442
|
-
rm->matcher = absl::make_unique<grpc_core::RealRequestMatcher>(server);
|
1443
|
-
}
|
1444
|
-
}
|
1445
|
-
|
1446
|
-
{
|
1447
|
-
grpc_core::MutexLock lock(&server->mu_global);
|
1448
|
-
server->starting = true;
|
1449
|
-
}
|
1450
|
-
|
1451
|
-
for (auto& listener : server->listeners) {
|
1452
|
-
listener.listener->Start(server, &server->pollsets);
|
1453
|
-
}
|
1454
|
-
|
1455
|
-
grpc_core::MutexLock lock(&server->mu_global);
|
1456
|
-
server->starting = false;
|
1457
|
-
server->starting_cv.Signal();
|
1489
|
+
server->core_server->Start();
|
1458
1490
|
}
|
1459
1491
|
|
1460
|
-
/*
|
1461
|
-
- Kills all pending requests-for-incoming-RPC-calls (i.e the requests made via
|
1462
|
-
grpc_server_request_call and grpc_server_request_registered call will now be
|
1463
|
-
cancelled). See 'kill_pending_work_locked()'
|
1464
|
-
|
1465
|
-
- Shuts down the listeners (i.e the server will no longer listen on the port
|
1466
|
-
for new incoming channels).
|
1467
|
-
|
1468
|
-
- Iterates through all channels on the server and sends shutdown msg (see
|
1469
|
-
'ChannelBroadcaster::BroadcastShutdown' for details) to the clients via the
|
1470
|
-
transport layer. The transport layer then guarantees the following:
|
1471
|
-
-- Sends shutdown to the client (for eg: HTTP2 transport sends GOAWAY)
|
1472
|
-
-- If the server has outstanding calls that are in the process, the
|
1473
|
-
connection is NOT closed until the server is done with all those calls
|
1474
|
-
-- Once, there are no more calls in progress, the channel is closed
|
1475
|
-
*/
|
1476
1492
|
void grpc_server_shutdown_and_notify(grpc_server* server,
|
1477
1493
|
grpc_completion_queue* cq, void* tag) {
|
1478
|
-
grpc_core::ChannelBroadcaster broadcaster;
|
1479
1494
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
|
1480
1495
|
grpc_core::ExecCtx exec_ctx;
|
1481
|
-
|
1482
1496
|
GRPC_API_TRACE("grpc_server_shutdown_and_notify(server=%p, cq=%p, tag=%p)", 3,
|
1483
1497
|
(server, cq, tag));
|
1484
|
-
|
1485
|
-
{
|
1486
|
-
/* wait for startup to be finished: locks mu_global */
|
1487
|
-
grpc_core::MutexLock lock(&server->mu_global);
|
1488
|
-
server->starting_cv.WaitUntil(&server->mu_global,
|
1489
|
-
[server] { return !server->starting; });
|
1490
|
-
|
1491
|
-
/* stay locked, and gather up some stuff to do */
|
1492
|
-
GPR_ASSERT(grpc_cq_begin_op(cq, tag));
|
1493
|
-
if (server->shutdown_published) {
|
1494
|
-
grpc_cq_end_op(cq, tag, GRPC_ERROR_NONE,
|
1495
|
-
grpc_core::done_published_shutdown, nullptr,
|
1496
|
-
new grpc_cq_completion);
|
1497
|
-
return;
|
1498
|
-
}
|
1499
|
-
server->shutdown_tags.emplace_back(tag, cq);
|
1500
|
-
if (server->shutdown_flag.load(std::memory_order_acquire)) {
|
1501
|
-
return;
|
1502
|
-
}
|
1503
|
-
|
1504
|
-
server->last_shutdown_message_time = gpr_now(GPR_CLOCK_REALTIME);
|
1505
|
-
|
1506
|
-
broadcaster.FillChannelsLocked(server);
|
1507
|
-
|
1508
|
-
server->shutdown_flag.store(true, std::memory_order_release);
|
1509
|
-
|
1510
|
-
/* collect all unregistered then registered calls */
|
1511
|
-
{
|
1512
|
-
grpc_core::MutexLock lock(&server->mu_call);
|
1513
|
-
grpc_core::kill_pending_work_locked(
|
1514
|
-
server, GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server Shutdown"));
|
1515
|
-
}
|
1516
|
-
|
1517
|
-
grpc_core::maybe_finish_shutdown(server);
|
1518
|
-
}
|
1519
|
-
|
1520
|
-
/* Shutdown listeners */
|
1521
|
-
for (auto& listener : server->listeners) {
|
1522
|
-
grpc_core::channelz::ListenSocketNode* channelz_listen_socket_node =
|
1523
|
-
listener.listener->channelz_listen_socket_node();
|
1524
|
-
if (server->channelz_server != nullptr &&
|
1525
|
-
channelz_listen_socket_node != nullptr) {
|
1526
|
-
server->channelz_server->RemoveChildListenSocket(
|
1527
|
-
channelz_listen_socket_node->uuid());
|
1528
|
-
}
|
1529
|
-
GRPC_CLOSURE_INIT(&listener.destroy_done, grpc_core::listener_destroy_done,
|
1530
|
-
server, grpc_schedule_on_exec_ctx);
|
1531
|
-
listener.listener->SetOnDestroyDone(&listener.destroy_done);
|
1532
|
-
listener.listener.reset();
|
1533
|
-
}
|
1534
|
-
|
1535
|
-
broadcaster.BroadcastShutdown(/*send_goaway=*/true, GRPC_ERROR_NONE);
|
1498
|
+
server->core_server->ShutdownAndNotify(cq, tag);
|
1536
1499
|
}
|
1537
1500
|
|
1538
1501
|
void grpc_server_cancel_all_calls(grpc_server* server) {
|
1539
|
-
grpc_core::ChannelBroadcaster broadcaster;
|
1540
1502
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
|
1541
1503
|
grpc_core::ExecCtx exec_ctx;
|
1542
|
-
|
1543
1504
|
GRPC_API_TRACE("grpc_server_cancel_all_calls(server=%p)", 1, (server));
|
1544
|
-
|
1545
|
-
{
|
1546
|
-
grpc_core::MutexLock lock(&server->mu_global);
|
1547
|
-
broadcaster.FillChannelsLocked(server);
|
1548
|
-
}
|
1549
|
-
|
1550
|
-
broadcaster.BroadcastShutdown(
|
1551
|
-
/*send_goaway=*/false,
|
1552
|
-
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Cancelling all calls"));
|
1505
|
+
server->core_server->CancelAllCalls();
|
1553
1506
|
}
|
1554
1507
|
|
1555
1508
|
void grpc_server_destroy(grpc_server* server) {
|
1556
1509
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
|
1557
1510
|
grpc_core::ExecCtx exec_ctx;
|
1558
|
-
|
1559
1511
|
GRPC_API_TRACE("grpc_server_destroy(server=%p)", 1, (server));
|
1560
|
-
|
1561
|
-
{
|
1562
|
-
grpc_core::MutexLock lock(&server->mu_global);
|
1563
|
-
GPR_ASSERT(server->shutdown_flag.load(std::memory_order_acquire) ||
|
1564
|
-
server->listeners.empty());
|
1565
|
-
GPR_ASSERT(server->listeners_destroyed == server->listeners.size());
|
1566
|
-
}
|
1567
|
-
|
1568
|
-
if (server->default_resource_user != nullptr) {
|
1569
|
-
grpc_resource_quota_unref(
|
1570
|
-
grpc_resource_user_quota(server->default_resource_user));
|
1571
|
-
grpc_resource_user_shutdown(server->default_resource_user);
|
1572
|
-
grpc_resource_user_unref(server->default_resource_user);
|
1573
|
-
}
|
1574
|
-
grpc_core::server_unref(server);
|
1575
|
-
}
|
1576
|
-
|
1577
|
-
const std::vector<grpc_pollset*>& grpc_server_get_pollsets(
|
1578
|
-
grpc_server* server) {
|
1579
|
-
return server->pollsets;
|
1580
|
-
}
|
1581
|
-
|
1582
|
-
void grpc_server_setup_transport(
|
1583
|
-
grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset,
|
1584
|
-
const grpc_channel_args* args,
|
1585
|
-
const grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>&
|
1586
|
-
socket_node,
|
1587
|
-
grpc_resource_user* resource_user) {
|
1588
|
-
size_t num_registered_methods;
|
1589
|
-
grpc_core::channel_registered_method* crm;
|
1590
|
-
grpc_channel* channel;
|
1591
|
-
grpc_core::channel_data* chand;
|
1592
|
-
uint32_t hash;
|
1593
|
-
size_t slots;
|
1594
|
-
uint32_t probes;
|
1595
|
-
uint32_t max_probes = 0;
|
1596
|
-
grpc_transport_op* op = nullptr;
|
1597
|
-
|
1598
|
-
channel = grpc_channel_create(nullptr, args, GRPC_SERVER_CHANNEL, transport,
|
1599
|
-
resource_user);
|
1600
|
-
chand = static_cast<grpc_core::channel_data*>(
|
1601
|
-
grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0)
|
1602
|
-
->channel_data);
|
1603
|
-
chand->server = s;
|
1604
|
-
grpc_core::server_ref(s);
|
1605
|
-
chand->channel = channel;
|
1606
|
-
if (socket_node != nullptr) {
|
1607
|
-
chand->channelz_socket_uuid = socket_node->uuid();
|
1608
|
-
s->channelz_server->AddChildSocket(socket_node);
|
1609
|
-
} else {
|
1610
|
-
chand->channelz_socket_uuid = 0;
|
1611
|
-
}
|
1612
|
-
|
1613
|
-
size_t cq_idx;
|
1614
|
-
for (cq_idx = 0; cq_idx < s->cqs.size(); cq_idx++) {
|
1615
|
-
if (grpc_cq_pollset(s->cqs[cq_idx]) == accepting_pollset) break;
|
1616
|
-
}
|
1617
|
-
if (cq_idx == s->cqs.size()) {
|
1618
|
-
/* completion queue not found: pick a random one to publish new calls to */
|
1619
|
-
cq_idx = static_cast<size_t>(rand()) % s->cqs.size();
|
1620
|
-
}
|
1621
|
-
chand->cq_idx = cq_idx;
|
1622
|
-
|
1623
|
-
num_registered_methods = s->registered_methods.size();
|
1624
|
-
/* build a lookup table phrased in terms of mdstr's in this channels context
|
1625
|
-
to quickly find registered methods */
|
1626
|
-
if (num_registered_methods > 0) {
|
1627
|
-
slots = 2 * num_registered_methods;
|
1628
|
-
chand->registered_methods.reset(
|
1629
|
-
new std::vector<grpc_core::channel_registered_method>(slots));
|
1630
|
-
for (std::unique_ptr<grpc_core::registered_method>& rm :
|
1631
|
-
s->registered_methods) {
|
1632
|
-
grpc_core::ExternallyManagedSlice host;
|
1633
|
-
grpc_core::ExternallyManagedSlice method(rm->method.c_str());
|
1634
|
-
const bool has_host = !rm->host.empty();
|
1635
|
-
if (has_host) {
|
1636
|
-
host = grpc_core::ExternallyManagedSlice(rm->host.c_str());
|
1637
|
-
}
|
1638
|
-
hash = GRPC_MDSTR_KV_HASH(has_host ? host.Hash() : 0, method.Hash());
|
1639
|
-
for (probes = 0; (*chand->registered_methods)[(hash + probes) % slots]
|
1640
|
-
.server_registered_method != nullptr;
|
1641
|
-
probes++) {
|
1642
|
-
}
|
1643
|
-
if (probes > max_probes) max_probes = probes;
|
1644
|
-
crm = &(*chand->registered_methods)[(hash + probes) % slots];
|
1645
|
-
crm->server_registered_method = rm.get();
|
1646
|
-
crm->flags = rm->flags;
|
1647
|
-
crm->has_host = has_host;
|
1648
|
-
if (has_host) {
|
1649
|
-
crm->host = host;
|
1650
|
-
}
|
1651
|
-
crm->method = method;
|
1652
|
-
}
|
1653
|
-
GPR_ASSERT(slots <= UINT32_MAX);
|
1654
|
-
chand->registered_method_max_probes = max_probes;
|
1655
|
-
}
|
1656
|
-
|
1657
|
-
{
|
1658
|
-
grpc_core::MutexLock lock(&s->mu_global);
|
1659
|
-
s->channels.push_front(chand);
|
1660
|
-
chand->list_position = s->channels.begin();
|
1661
|
-
}
|
1662
|
-
|
1663
|
-
op = grpc_make_transport_op(nullptr);
|
1664
|
-
op->set_accept_stream = true;
|
1665
|
-
op->set_accept_stream_fn = grpc_core::accept_stream;
|
1666
|
-
op->set_accept_stream_user_data = chand;
|
1667
|
-
op->start_connectivity_watch.reset(new grpc_core::ConnectivityWatcher(chand));
|
1668
|
-
if (s->shutdown_flag.load(std::memory_order_acquire)) {
|
1669
|
-
op->disconnect_with_error =
|
1670
|
-
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Server shutdown");
|
1671
|
-
}
|
1672
|
-
grpc_transport_perform_op(transport, op);
|
1512
|
+
delete server;
|
1673
1513
|
}
|
1674
1514
|
|
1675
1515
|
grpc_call_error grpc_server_request_call(
|
1676
1516
|
grpc_server* server, grpc_call** call, grpc_call_details* details,
|
1677
|
-
grpc_metadata_array*
|
1517
|
+
grpc_metadata_array* request_metadata,
|
1678
1518
|
grpc_completion_queue* cq_bound_to_call,
|
1679
1519
|
grpc_completion_queue* cq_for_notification, void* tag) {
|
1680
1520
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
|
@@ -1685,49 +1525,31 @@ grpc_call_error grpc_server_request_call(
|
|
1685
1525
|
"server=%p, call=%p, details=%p, initial_metadata=%p, "
|
1686
1526
|
"cq_bound_to_call=%p, cq_for_notification=%p, tag=%p)",
|
1687
1527
|
7,
|
1688
|
-
(server, call, details,
|
1528
|
+
(server, call, details, request_metadata, cq_bound_to_call,
|
1689
1529
|
cq_for_notification, tag));
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
&cq_idx, server, cq_for_notification, tag, nullptr, nullptr);
|
1694
|
-
if (error != GRPC_CALL_OK) {
|
1695
|
-
return error;
|
1696
|
-
}
|
1697
|
-
|
1698
|
-
grpc_core::requested_call* rc = new grpc_core::requested_call(
|
1699
|
-
tag, cq_bound_to_call, call, initial_metadata, details);
|
1700
|
-
return queue_call_request(server, cq_idx, rc);
|
1530
|
+
return server->core_server->RequestCall(call, details, request_metadata,
|
1531
|
+
cq_bound_to_call, cq_for_notification,
|
1532
|
+
tag);
|
1701
1533
|
}
|
1702
1534
|
|
1703
1535
|
grpc_call_error grpc_server_request_registered_call(
|
1704
1536
|
grpc_server* server, void* rmp, grpc_call** call, gpr_timespec* deadline,
|
1705
|
-
grpc_metadata_array*
|
1537
|
+
grpc_metadata_array* request_metadata, grpc_byte_buffer** optional_payload,
|
1706
1538
|
grpc_completion_queue* cq_bound_to_call,
|
1707
1539
|
grpc_completion_queue* cq_for_notification, void* tag_new) {
|
1708
1540
|
grpc_core::ApplicationCallbackExecCtx callback_exec_ctx;
|
1709
1541
|
grpc_core::ExecCtx exec_ctx;
|
1710
1542
|
GRPC_STATS_INC_SERVER_REQUESTED_CALLS();
|
1711
|
-
|
1712
|
-
static_cast<grpc_core::registered_method*>(rmp);
|
1543
|
+
auto* rm = static_cast<grpc_core::Server::RegisteredMethod*>(rmp);
|
1713
1544
|
GRPC_API_TRACE(
|
1714
1545
|
"grpc_server_request_registered_call("
|
1715
|
-
"server=%p, rmp=%p, call=%p, deadline=%p,
|
1546
|
+
"server=%p, rmp=%p, call=%p, deadline=%p, request_metadata=%p, "
|
1716
1547
|
"optional_payload=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
|
1717
1548
|
"tag=%p)",
|
1718
1549
|
9,
|
1719
|
-
(server, rmp, call, deadline,
|
1550
|
+
(server, rmp, call, deadline, request_metadata, optional_payload,
|
1720
1551
|
cq_bound_to_call, cq_for_notification, tag_new));
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
&cq_idx, server, cq_for_notification, tag_new, optional_payload, rm);
|
1725
|
-
if (error != GRPC_CALL_OK) {
|
1726
|
-
return error;
|
1727
|
-
}
|
1728
|
-
|
1729
|
-
grpc_core::requested_call* rc = new grpc_core::requested_call(
|
1730
|
-
tag_new, cq_bound_to_call, call, initial_metadata, rm, deadline,
|
1731
|
-
optional_payload);
|
1732
|
-
return queue_call_request(server, cq_idx, rc);
|
1552
|
+
return server->core_server->RequestRegisteredCall(
|
1553
|
+
rm, call, deadline, request_metadata, optional_payload, cq_bound_to_call,
|
1554
|
+
cq_for_notification, tag_new);
|
1733
1555
|
}
|