aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ncteisen <ncteisen@gmail.com>2018-03-01 19:57:24 -0800
committerGravatar ncteisen <ncteisen@gmail.com>2018-03-01 19:57:24 -0800
commit75cf85c9cea06899e2b633b16abbe40cbb9ca3c2 (patch)
treec67c06024bd2bbd7147f77b882576367f98ebe35
parentac86f043735ea75a5ad79283ef50042d7448f04f (diff)
parentc372f19bf4935c08665ffda929b831a98dea99c4 (diff)
Merge branch 'master' of https://github.com/grpc/grpc into channel-tracing
-rw-r--r--.github/CODEOWNERS1
-rw-r--r--BUILD125
-rw-r--r--CMakeLists.txt588
-rw-r--r--Makefile663
-rw-r--r--README.md2
-rw-r--r--WORKSPACE3
-rw-r--r--bazel/grpc_build_system.bzl23
-rw-r--r--bazel/grpc_deps.bzl62
-rw-r--r--build.yaml177
-rw-r--r--cmake/benchmark.cmake5
-rw-r--r--cmake/cares.cmake1
-rw-r--r--cmake/gflags.cmake5
-rw-r--r--cmake/ssl.cmake4
-rw-r--r--cmake/zlib.cmake6
-rw-r--r--config.m49
-rw-r--r--config.w329
-rw-r--r--doc/cpp/pending_api_cleanups.md2
-rw-r--r--doc/environment_variables.md2
-rw-r--r--etc/roots.pem965
-rw-r--r--examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm6
-rw-r--r--gRPC-C++.podspec297
-rw-r--r--gRPC-Core.podspec49
-rw-r--r--gRPC-ProtoRPC.podspec2
-rw-r--r--gRPC-RxLibrary.podspec2
-rw-r--r--gRPC.podspec2
-rw-r--r--grpc.def7
-rw-r--r--grpc.gemspec81
-rw-r--r--grpc.gyp50
-rw-r--r--include/grpc++/alarm.h71
-rw-r--r--include/grpc++/channel.h62
-rw-r--r--include/grpc++/client_context.h21
-rw-r--r--include/grpc++/completion_queue.h8
-rw-r--r--include/grpc++/create_channel.h42
-rw-r--r--include/grpc++/create_channel_posix.h36
-rw-r--r--include/grpc++/ext/health_check_service_server_builder_option.h31
-rw-r--r--include/grpc++/ext/proto_server_reflection_plugin.h38
-rw-r--r--include/grpc++/generic/async_generic_service.h62
-rw-r--r--include/grpc++/generic/generic_stub.h55
-rw-r--r--include/grpc++/grpc++.h50
-rw-r--r--include/grpc++/health_check_service_interface.h38
-rw-r--r--include/grpc++/impl/call.h8
-rw-r--r--include/grpc++/impl/channel_argument_option.h21
-rw-r--r--include/grpc++/impl/client_unary_call.h8
-rw-r--r--include/grpc++/impl/codegen/async_stream.h1052
-rw-r--r--include/grpc++/impl/codegen/async_unary_call.h293
-rw-r--r--include/grpc++/impl/codegen/byte_buffer.h141
-rw-r--r--include/grpc++/impl/codegen/call.h693
-rw-r--r--include/grpc++/impl/codegen/call_hook.h23
-rw-r--r--include/grpc++/impl/codegen/channel_interface.h105
-rw-r--r--include/grpc++/impl/codegen/client_context.h424
-rw-r--r--include/grpc++/impl/codegen/client_unary_call.h74
-rw-r--r--include/grpc++/impl/codegen/completion_queue.h367
-rw-r--r--include/grpc++/impl/codegen/completion_queue_tag.h23
-rw-r--r--include/grpc++/impl/codegen/config.h25
-rw-r--r--include/grpc++/impl/codegen/config_protobuf.h79
-rw-r--r--include/grpc++/impl/codegen/core_codegen.h101
-rw-r--r--include/grpc++/impl/codegen/core_codegen_interface.h124
-rw-r--r--include/grpc++/impl/codegen/create_auth_context.h17
-rw-r--r--include/grpc++/impl/codegen/grpc_library.h47
-rw-r--r--include/grpc++/impl/codegen/metadata_map.h42
-rw-r--r--include/grpc++/impl/codegen/method_handler_impl.h286
-rw-r--r--include/grpc++/impl/codegen/proto_utils.h252
-rw-r--r--include/grpc++/impl/codegen/rpc_method.h45
-rw-r--r--include/grpc++/impl/codegen/rpc_service_method.h62
-rw-r--r--include/grpc++/impl/codegen/security/auth_context.h79
-rw-r--r--include/grpc++/impl/codegen/serialization_traits.h46
-rw-r--r--include/grpc++/impl/codegen/server_context.h293
-rw-r--r--include/grpc++/impl/codegen/server_interface.h258
-rw-r--r--include/grpc++/impl/codegen/service_type.h147
-rw-r--r--include/grpc++/impl/codegen/slice.h112
-rw-r--r--include/grpc++/impl/codegen/status.h63
-rw-r--r--include/grpc++/impl/codegen/status_code_enum.h126
-rw-r--r--include/grpc++/impl/codegen/string_ref.h130
-rw-r--r--include/grpc++/impl/codegen/stub_options.h13
-rw-r--r--include/grpc++/impl/codegen/sync_stream.h918
-rw-r--r--include/grpc++/impl/codegen/time.h73
-rw-r--r--include/grpc++/impl/grpc_library.h45
-rw-r--r--include/grpc++/impl/method_handler_impl.h8
-rw-r--r--include/grpc++/impl/rpc_method.h8
-rw-r--r--include/grpc++/impl/rpc_service_method.h8
-rw-r--r--include/grpc++/impl/serialization_traits.h8
-rw-r--r--include/grpc++/impl/server_builder_option.h27
-rw-r--r--include/grpc++/impl/server_builder_plugin.h49
-rw-r--r--include/grpc++/impl/server_initializer.h39
-rw-r--r--include/grpc++/impl/service_type.h8
-rw-r--r--include/grpc++/impl/sync_cxx11.h8
-rw-r--r--include/grpc++/impl/sync_no_cxx11.h8
-rw-r--r--include/grpc++/resource_quota.h42
-rw-r--r--include/grpc++/security/auth_context.h8
-rw-r--r--include/grpc++/security/auth_metadata_processor.h45
-rw-r--r--include/grpc++/security/credentials.h208
-rw-r--r--include/grpc++/security/server_credentials.h75
-rw-r--r--include/grpc++/server.h211
-rw-r--r--include/grpc++/server_builder.h262
-rw-r--r--include/grpc++/server_context.h8
-rw-r--r--include/grpc++/server_posix.h26
-rw-r--r--include/grpc++/support/async_stream.h8
-rw-r--r--include/grpc++/support/async_unary_call.h8
-rw-r--r--include/grpc++/support/byte_buffer.h15
-rw-r--r--include/grpc++/support/channel_arguments.h126
-rw-r--r--include/grpc++/support/config.h8
-rw-r--r--include/grpc++/support/error_details.h30
-rw-r--r--include/grpc++/support/slice.h10
-rw-r--r--include/grpc++/support/status.h8
-rw-r--r--include/grpc++/support/status_code_enum.h8
-rw-r--r--include/grpc++/support/string_ref.h8
-rw-r--r--include/grpc++/support/stub_options.h8
-rw-r--r--include/grpc++/support/sync_stream.h8
-rw-r--r--include/grpc++/support/time.h8
-rw-r--r--include/grpc++/test/mock_stream.h132
-rw-r--r--include/grpc++/test/server_context_test_spouse.h49
-rw-r--r--include/grpc/byte_buffer.h2
-rw-r--r--include/grpc/byte_buffer_reader.h2
-rw-r--r--include/grpc/census.h2
-rw-r--r--include/grpc/fork.h2
-rw-r--r--include/grpc/grpc.h17
-rw-r--r--include/grpc/grpc_cronet.h2
-rw-r--r--include/grpc/grpc_posix.h3
-rw-r--r--include/grpc/grpc_security.h10
-rw-r--r--include/grpc/impl/codegen/byte_buffer.h2
-rw-r--r--include/grpc/impl/codegen/grpc_types.h20
-rw-r--r--include/grpc/impl/codegen/sync.h1
-rw-r--r--include/grpc/impl/codegen/sync_custom.h2
-rw-r--r--include/grpc/impl/codegen/sync_generic.h2
-rw-r--r--include/grpc/impl/codegen/sync_posix.h2
-rw-r--r--include/grpc/impl/codegen/sync_windows.h2
-rw-r--r--include/grpc/module.modulemap2
-rw-r--r--include/grpc/slice.h2
-rw-r--r--include/grpc/slice_buffer.h2
-rw-r--r--include/grpc/status.h2
-rw-r--r--include/grpc/support/alloc.h4
-rw-r--r--include/grpc/support/atm.h2
-rw-r--r--include/grpc/support/atm_gcc_atomic.h2
-rw-r--r--include/grpc/support/atm_gcc_sync.h2
-rw-r--r--include/grpc/support/atm_windows.h2
-rw-r--r--include/grpc/support/log.h4
-rw-r--r--include/grpc/support/sync.h2
-rw-r--r--include/grpc/support/sync_custom.h2
-rw-r--r--include/grpc/support/sync_generic.h2
-rw-r--r--include/grpc/support/sync_posix.h2
-rw-r--r--include/grpc/support/sync_windows.h2
-rw-r--r--include/grpc/support/thd_id.h44
-rw-r--r--include/grpc/support/time.h2
-rw-r--r--include/grpcpp/alarm.h87
-rw-r--r--include/grpcpp/channel.h78
-rw-r--r--include/grpcpp/client_context.h39
-rw-r--r--include/grpcpp/completion_queue.h24
-rw-r--r--include/grpcpp/create_channel.h58
-rw-r--r--include/grpcpp/create_channel_posix.h52
-rw-r--r--include/grpcpp/ext/health_check_service_server_builder_option.h47
-rw-r--r--include/grpcpp/ext/proto_server_reflection_plugin.h54
-rw-r--r--include/grpcpp/generic/async_generic_service.h78
-rw-r--r--include/grpcpp/generic/generic_stub.h71
-rw-r--r--include/grpcpp/grpcpp.h68
-rw-r--r--include/grpcpp/health_check_service_interface.h54
-rw-r--r--include/grpcpp/impl/README.md (renamed from include/grpc++/impl/README.md)0
-rw-r--r--include/grpcpp/impl/call.h24
-rw-r--r--include/grpcpp/impl/channel_argument_option.h (renamed from src/core/lib/security/transport/lb_targets_info.h)25
-rw-r--r--include/grpcpp/impl/client_unary_call.h24
-rw-r--r--include/grpcpp/impl/codegen/async_stream.h1068
-rw-r--r--include/grpcpp/impl/codegen/async_unary_call.h309
-rw-r--r--include/grpcpp/impl/codegen/byte_buffer.h157
-rw-r--r--include/grpcpp/impl/codegen/call.h709
-rw-r--r--include/grpcpp/impl/codegen/call_hook.h39
-rw-r--r--include/grpcpp/impl/codegen/channel_interface.h121
-rw-r--r--include/grpcpp/impl/codegen/client_context.h442
-rw-r--r--include/grpcpp/impl/codegen/client_unary_call.h90
-rw-r--r--include/grpcpp/impl/codegen/completion_queue.h383
-rw-r--r--include/grpcpp/impl/codegen/completion_queue_tag.h39
-rw-r--r--include/grpcpp/impl/codegen/config.h41
-rw-r--r--include/grpcpp/impl/codegen/config_protobuf.h95
-rw-r--r--include/grpcpp/impl/codegen/core_codegen.h117
-rw-r--r--include/grpcpp/impl/codegen/core_codegen_interface.h142
-rw-r--r--include/grpcpp/impl/codegen/create_auth_context.h33
-rw-r--r--include/grpcpp/impl/codegen/grpc_library.h64
-rw-r--r--include/grpcpp/impl/codegen/metadata_map.h58
-rw-r--r--include/grpcpp/impl/codegen/method_handler_impl.h302
-rw-r--r--include/grpcpp/impl/codegen/proto_utils.h268
-rw-r--r--include/grpcpp/impl/codegen/rpc_method.h61
-rw-r--r--include/grpcpp/impl/codegen/rpc_service_method.h78
-rw-r--r--include/grpcpp/impl/codegen/security/auth_context.h95
-rw-r--r--include/grpcpp/impl/codegen/serialization_traits.h62
-rw-r--r--include/grpcpp/impl/codegen/server_context.h309
-rw-r--r--include/grpcpp/impl/codegen/server_interface.h274
-rw-r--r--include/grpcpp/impl/codegen/service_type.h163
-rw-r--r--include/grpcpp/impl/codegen/slice.h128
-rw-r--r--include/grpcpp/impl/codegen/status.h79
-rw-r--r--include/grpcpp/impl/codegen/status_code_enum.h142
-rw-r--r--include/grpcpp/impl/codegen/string_ref.h146
-rw-r--r--include/grpcpp/impl/codegen/stub_options.h29
-rw-r--r--include/grpcpp/impl/codegen/sync_stream.h934
-rw-r--r--include/grpcpp/impl/codegen/time.h89
-rw-r--r--include/grpcpp/impl/grpc_library.h61
-rw-r--r--include/grpcpp/impl/method_handler_impl.h24
-rw-r--r--include/grpcpp/impl/rpc_method.h24
-rw-r--r--include/grpcpp/impl/rpc_service_method.h (renamed from src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h)13
-rw-r--r--include/grpcpp/impl/serialization_traits.h24
-rw-r--r--include/grpcpp/impl/server_builder_option.h43
-rw-r--r--include/grpcpp/impl/server_builder_plugin.h65
-rw-r--r--include/grpcpp/impl/server_initializer.h55
-rw-r--r--include/grpcpp/impl/service_type.h24
-rw-r--r--include/grpcpp/impl/sync_cxx11.h (renamed from src/core/lib/gpr/thd_internal.h)14
-rw-r--r--include/grpcpp/impl/sync_no_cxx11.h24
-rw-r--r--include/grpcpp/resource_quota.h58
-rw-r--r--include/grpcpp/security/auth_context.h24
-rw-r--r--include/grpcpp/security/auth_metadata_processor.h61
-rw-r--r--include/grpcpp/security/credentials.h224
-rw-r--r--include/grpcpp/security/server_credentials.h91
-rw-r--r--include/grpcpp/server.h227
-rw-r--r--include/grpcpp/server_builder.h278
-rw-r--r--include/grpcpp/server_context.h24
-rw-r--r--include/grpcpp/server_posix.h42
-rw-r--r--include/grpcpp/support/async_stream.h24
-rw-r--r--include/grpcpp/support/async_unary_call.h24
-rw-r--r--include/grpcpp/support/byte_buffer.h31
-rw-r--r--include/grpcpp/support/channel_arguments.h142
-rw-r--r--include/grpcpp/support/config.h24
-rw-r--r--include/grpcpp/support/error_details.h46
-rw-r--r--include/grpcpp/support/slice.h26
-rw-r--r--include/grpcpp/support/status.h24
-rw-r--r--include/grpcpp/support/status_code_enum.h24
-rw-r--r--include/grpcpp/support/string_ref.h24
-rw-r--r--include/grpcpp/support/stub_options.h24
-rw-r--r--include/grpcpp/support/sync_stream.h24
-rw-r--r--include/grpcpp/support/time.h24
-rw-r--r--include/grpcpp/test/mock_stream.h148
-rw-r--r--include/grpcpp/test/server_context_test_spouse.h65
-rw-r--r--package.xml85
-rwxr-xr-xsrc/boringssl/gen_build_yaml.py4
-rw-r--r--src/compiler/config.h2
-rw-r--r--src/compiler/cpp_generator.cc38
-rw-r--r--src/compiler/csharp_generator.cc15
-rw-r--r--src/compiler/objective_c_generator.cc104
-rw-r--r--src/compiler/objective_c_generator.h10
-rw-r--r--src/compiler/objective_c_generator_helpers.h40
-rw-r--r--src/compiler/objective_c_plugin.cc145
-rw-r--r--src/core/ext/census/grpc_context.cc2
-rw-r--r--src/core/ext/filters/client_channel/backup_poller.cc21
-rw-r--r--src/core/ext/filters/client_channel/backup_poller.h4
-rw-r--r--src/core/ext/filters/client_channel/channel_connectivity.cc2
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc2319
-rw-r--r--src/core/ext/filters/client_channel/client_channel.h2
-rw-r--r--src/core/ext/filters/client_channel/client_channel_factory.cc2
-rw-r--r--src/core/ext/filters/client_channel/client_channel_factory.h2
-rw-r--r--src/core/ext/filters/client_channel/client_channel_plugin.cc4
-rw-r--r--src/core/ext/filters/client_channel/connector.cc2
-rw-r--r--src/core/ext/filters/client_channel/connector.h2
-rw-r--r--src/core/ext/filters/client_channel/http_connect_handshaker.cc13
-rw-r--r--src/core/ext/filters/client_channel/http_proxy.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.cc125
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h333
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc2990
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc52
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h26
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc132
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc525
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc580
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc30
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h18
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.cc16
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.h52
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.cc93
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.h39
-rw-r--r--src/core/ext/filters/client_channel/method_params.cc178
-rw-r--r--src/core/ext/filters/client_channel/method_params.h74
-rw-r--r--src/core/ext/filters/client_channel/parse_address.cc2
-rw-r--r--src/core/ext/filters/client_channel/parse_address.h2
-rw-r--r--src/core/ext/filters/client_channel/proxy_mapper.cc2
-rw-r--r--src/core/ext/filters/client_channel/proxy_mapper.h2
-rw-r--r--src/core/ext/filters/client_channel/proxy_mapper_registry.cc2
-rw-r--r--src/core/ext/filters/client_channel/proxy_mapper_registry.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver.cc2
-rw-r--r--src/core/ext/filters/client_channel/resolver.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc9
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc1
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc1
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc1
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc3
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc3
-rw-r--r--src/core/ext/filters/client_channel/resolver_factory.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver_registry.cc2
-rw-r--r--src/core/ext/filters/client_channel/resolver_registry.h2
-rw-r--r--src/core/ext/filters/client_channel/retry_throttle.cc6
-rw-r--r--src/core/ext/filters/client_channel/retry_throttle.h2
-rw-r--r--src/core/ext/filters/client_channel/status_util.cc100
-rw-r--r--src/core/ext/filters/client_channel/status_util.h58
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc23
-rw-r--r--src/core/ext/filters/client_channel/subchannel.h11
-rw-r--r--src/core/ext/filters/client_channel/subchannel_index.cc2
-rw-r--r--src/core/ext/filters/client_channel/subchannel_index.h2
-rw-r--r--src/core/ext/filters/client_channel/uri_parser.cc3
-rw-r--r--src/core/ext/filters/client_channel/uri_parser.h2
-rw-r--r--src/core/ext/filters/deadline/deadline_filter.cc2
-rw-r--r--src/core/ext/filters/deadline/deadline_filter.h2
-rw-r--r--src/core/ext/filters/http/client/http_client_filter.cc4
-rw-r--r--src/core/ext/filters/http/client/http_client_filter.h2
-rw-r--r--src/core/ext/filters/http/http_filters_plugin.cc2
-rw-r--r--src/core/ext/filters/http/message_compress/message_compress_filter.cc2
-rw-r--r--src/core/ext/filters/http/message_compress/message_compress_filter.h2
-rw-r--r--src/core/ext/filters/http/server/http_server_filter.cc16
-rw-r--r--src/core/ext/filters/http/server/http_server_filter.h2
-rw-r--r--src/core/ext/filters/load_reporting/server_load_reporting_filter.cc2
-rw-r--r--src/core/ext/filters/load_reporting/server_load_reporting_filter.h2
-rw-r--r--src/core/ext/filters/load_reporting/server_load_reporting_plugin.h2
-rw-r--r--src/core/ext/filters/max_age/max_age_filter.cc5
-rw-r--r--src/core/ext/filters/max_age/max_age_filter.h2
-rw-r--r--src/core/ext/filters/message_size/message_size_filter.cc95
-rw-r--r--src/core/ext/filters/message_size/message_size_filter.h2
-rw-r--r--src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc2
-rw-r--r--src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h2
-rw-r--r--src/core/ext/filters/workarounds/workaround_utils.cc2
-rw-r--r--src/core/ext/filters/workarounds/workaround_utils.h2
-rw-r--r--src/core/ext/transport/chttp2/alpn/alpn.cc4
-rw-r--r--src/core/ext/transport/chttp2/alpn/alpn.h2
-rw-r--r--src/core/ext/transport/chttp2/client/chttp2_connector.cc2
-rw-r--r--src/core/ext/transport/chttp2/client/chttp2_connector.h2
-rw-r--r--src/core/ext/transport/chttp2/client/insecure/channel_create.cc2
-rw-r--r--src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc3
-rw-r--r--src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc47
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.cc2
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.h2
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc2
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc3
-rw-r--r--src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_decoder.cc30
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_decoder.h5
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_encoder.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/bin_encoder.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_plugin.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc22
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/flow_control.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/flow_control.h1
-rw-r--r--src/core/ext/transport/chttp2/transport/frame.h3
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_data.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_data.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_goaway.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_goaway.h3
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_ping.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_ping.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_rst_stream.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_rst_stream.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_settings.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_settings.h3
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_window_update.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/frame_window_update.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_encoder.h3
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.cc3
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_parser.h3
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/hpack_table.h3
-rw-r--r--src/core/ext/transport/chttp2/transport/http2_settings.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/http2_settings.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/huffsyms.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/incoming_metadata.cc5
-rw-r--r--src/core/ext/transport/chttp2/transport/incoming_metadata.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h2
-rw-r--r--src/core/ext/transport/chttp2/transport/parsing.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/stream_lists.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/stream_map.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/varint.cc2
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.cc2
-rw-r--r--src/core/ext/transport/cronet/transport/cronet_api_dummy.cc2
-rw-r--r--src/core/ext/transport/cronet/transport/cronet_transport.cc63
-rw-r--r--src/core/ext/transport/cronet/transport/cronet_transport.h2
-rw-r--r--src/core/ext/transport/inproc/inproc_plugin.cc2
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.cc22
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.h2
-rw-r--r--src/core/lib/avl/avl.cc2
-rw-r--r--src/core/lib/avl/avl.h2
-rw-r--r--src/core/lib/backoff/backoff.cc2
-rw-r--r--src/core/lib/backoff/backoff.h2
-rw-r--r--src/core/lib/channel/channel_args.cc9
-rw-r--r--src/core/lib/channel/channel_args.h7
-rw-r--r--src/core/lib/channel/channel_stack.cc4
-rw-r--r--src/core/lib/channel/channel_stack.h2
-rw-r--r--src/core/lib/channel/channel_stack_builder.cc2
-rw-r--r--src/core/lib/channel/channel_stack_builder.h2
-rw-r--r--src/core/lib/channel/connected_channel.cc2
-rw-r--r--src/core/lib/channel/connected_channel.h2
-rw-r--r--src/core/lib/channel/handshaker.cc2
-rw-r--r--src/core/lib/channel/handshaker.h2
-rw-r--r--src/core/lib/channel/handshaker_factory.cc2
-rw-r--r--src/core/lib/channel/handshaker_factory.h2
-rw-r--r--src/core/lib/channel/handshaker_registry.cc2
-rw-r--r--src/core/lib/channel/handshaker_registry.h2
-rw-r--r--src/core/lib/compression/algorithm_metadata.h2
-rw-r--r--src/core/lib/compression/compression.cc2
-rw-r--r--src/core/lib/compression/compression_internal.cc2
-rw-r--r--src/core/lib/compression/compression_internal.h2
-rw-r--r--src/core/lib/compression/message_compress.cc2
-rw-r--r--src/core/lib/compression/message_compress.h2
-rw-r--r--src/core/lib/compression/stream_compression.cc2
-rw-r--r--src/core/lib/compression/stream_compression.h2
-rw-r--r--src/core/lib/compression/stream_compression_gzip.cc2
-rw-r--r--src/core/lib/compression/stream_compression_gzip.h2
-rw-r--r--src/core/lib/compression/stream_compression_identity.cc2
-rw-r--r--src/core/lib/compression/stream_compression_identity.h2
-rw-r--r--src/core/lib/debug/stats.cc2
-rw-r--r--src/core/lib/debug/stats.h2
-rw-r--r--src/core/lib/debug/stats_data.cc4
-rw-r--r--src/core/lib/debug/stats_data.h2
-rw-r--r--src/core/lib/debug/trace.cc2
-rw-r--r--src/core/lib/debug/trace.h3
-rw-r--r--src/core/lib/gpr/alloc.cc3
-rw-r--r--src/core/lib/gpr/arena.cc47
-rw-r--r--src/core/lib/gpr/arena.h2
-rw-r--r--src/core/lib/gpr/atm.cc2
-rw-r--r--src/core/lib/gpr/cpu_linux.cc2
-rw-r--r--src/core/lib/gpr/env.h2
-rw-r--r--src/core/lib/gpr/fork.cc2
-rw-r--r--src/core/lib/gpr/host_port.cc2
-rw-r--r--src/core/lib/gpr/log.cc3
-rw-r--r--src/core/lib/gpr/mpscq.cc3
-rw-r--r--src/core/lib/gpr/mpscq.h2
-rw-r--r--src/core/lib/gpr/murmur_hash.cc2
-rw-r--r--src/core/lib/gpr/spinlock.h2
-rw-r--r--src/core/lib/gpr/string.cc3
-rw-r--r--src/core/lib/gpr/string.h4
-rw-r--r--src/core/lib/gpr/sync.cc2
-rw-r--r--src/core/lib/gpr/thd.cc8
-rw-r--r--src/core/lib/gpr/thd.h (renamed from include/grpc/support/thd.h)47
-rw-r--r--src/core/lib/gpr/thd_posix.cc4
-rw-r--r--src/core/lib/gpr/thd_windows.cc4
-rw-r--r--src/core/lib/gpr/time.cc2
-rw-r--r--src/core/lib/gpr/time_posix.cc1
-rw-r--r--src/core/lib/gpr/time_precise.cc2
-rw-r--r--src/core/lib/gpr/time_precise.h2
-rw-r--r--src/core/lib/gpr/tls_gcc.h2
-rw-r--r--src/core/lib/gpr/tls_msvc.h2
-rw-r--r--src/core/lib/gpr/tls_pthread.h2
-rw-r--r--src/core/lib/gpr/tmpfile.h2
-rw-r--r--src/core/lib/gprpp/atomic_with_atm.h2
-rw-r--r--src/core/lib/gprpp/atomic_with_std.h2
-rw-r--r--src/core/lib/gprpp/inlined_vector.h2
-rw-r--r--src/core/lib/gprpp/manual_constructor.h2
-rw-r--r--src/core/lib/gprpp/memory.h15
-rw-r--r--src/core/lib/gprpp/orphanable.h3
-rw-r--r--src/core/lib/gprpp/ref_counted.h4
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h3
-rw-r--r--src/core/lib/http/format_request.cc2
-rw-r--r--src/core/lib/http/format_request.h2
-rw-r--r--src/core/lib/http/httpcli.cc2
-rw-r--r--src/core/lib/http/httpcli.h2
-rw-r--r--src/core/lib/http/httpcli_security_connector.cc2
-rw-r--r--src/core/lib/http/parser.cc2
-rw-r--r--src/core/lib/http/parser.h3
-rw-r--r--src/core/lib/iomgr/call_combiner.cc2
-rw-r--r--src/core/lib/iomgr/call_combiner.h2
-rw-r--r--src/core/lib/iomgr/combiner.cc2
-rw-r--r--src/core/lib/iomgr/combiner.h2
-rw-r--r--src/core/lib/iomgr/endpoint.cc2
-rw-r--r--src/core/lib/iomgr/endpoint.h2
-rw-r--r--src/core/lib/iomgr/endpoint_pair.h2
-rw-r--r--src/core/lib/iomgr/endpoint_pair_posix.cc2
-rw-r--r--src/core/lib/iomgr/endpoint_pair_uv.cc2
-rw-r--r--src/core/lib/iomgr/endpoint_pair_windows.cc2
-rw-r--r--src/core/lib/iomgr/error.h2
-rw-r--r--src/core/lib/iomgr/error_internal.h2
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc2
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.h2
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc23
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.h2
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.cc2
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.h2
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.cc4
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.h2
-rw-r--r--src/core/lib/iomgr/ev_posix.cc2
-rw-r--r--src/core/lib/iomgr/ev_posix.h2
-rw-r--r--src/core/lib/iomgr/ev_windows.cc2
-rw-r--r--src/core/lib/iomgr/exec_ctx.cc4
-rw-r--r--src/core/lib/iomgr/exec_ctx.h2
-rw-r--r--src/core/lib/iomgr/executor.cc4
-rw-r--r--src/core/lib/iomgr/executor.h2
-rw-r--r--src/core/lib/iomgr/fork_posix.cc5
-rw-r--r--src/core/lib/iomgr/fork_windows.cc2
-rw-r--r--src/core/lib/iomgr/gethostname_fallback.cc2
-rw-r--r--src/core/lib/iomgr/gethostname_host_name_max.cc2
-rw-r--r--src/core/lib/iomgr/gethostname_sysconf.cc2
-rw-r--r--src/core/lib/iomgr/iocp_windows.cc4
-rw-r--r--src/core/lib/iomgr/iocp_windows.h2
-rw-r--r--src/core/lib/iomgr/iomgr.cc2
-rw-r--r--src/core/lib/iomgr/iomgr.h2
-rw-r--r--src/core/lib/iomgr/iomgr_internal.h2
-rw-r--r--src/core/lib/iomgr/iomgr_posix.cc2
-rw-r--r--src/core/lib/iomgr/iomgr_posix.h2
-rw-r--r--src/core/lib/iomgr/iomgr_uv.cc4
-rw-r--r--src/core/lib/iomgr/iomgr_uv.h4
-rw-r--r--src/core/lib/iomgr/iomgr_windows.cc2
-rw-r--r--src/core/lib/iomgr/is_epollexclusive_available.cc8
-rw-r--r--src/core/lib/iomgr/is_epollexclusive_available.h2
-rw-r--r--src/core/lib/iomgr/load_file.cc2
-rw-r--r--src/core/lib/iomgr/load_file.h2
-rw-r--r--src/core/lib/iomgr/lockfree_event.cc2
-rw-r--r--src/core/lib/iomgr/lockfree_event.h2
-rw-r--r--src/core/lib/iomgr/nameser.h2
-rw-r--r--src/core/lib/iomgr/network_status_tracker.cc4
-rw-r--r--src/core/lib/iomgr/network_status_tracker.h2
-rw-r--r--src/core/lib/iomgr/polling_entity.cc2
-rw-r--r--src/core/lib/iomgr/polling_entity.h2
-rw-r--r--src/core/lib/iomgr/pollset.h1
-rw-r--r--src/core/lib/iomgr/pollset_set.h2
-rw-r--r--src/core/lib/iomgr/pollset_set_uv.cc2
-rw-r--r--src/core/lib/iomgr/pollset_set_windows.cc2
-rw-r--r--src/core/lib/iomgr/pollset_set_windows.h2
-rw-r--r--src/core/lib/iomgr/pollset_uv.cc2
-rw-r--r--src/core/lib/iomgr/pollset_windows.cc4
-rw-r--r--src/core/lib/iomgr/pollset_windows.h2
-rw-r--r--src/core/lib/iomgr/resolve_address.h2
-rw-r--r--src/core/lib/iomgr/resolve_address_posix.cc4
-rw-r--r--src/core/lib/iomgr/resolve_address_uv.cc2
-rw-r--r--src/core/lib/iomgr/resolve_address_windows.cc4
-rw-r--r--src/core/lib/iomgr/resource_quota.cc2
-rw-r--r--src/core/lib/iomgr/resource_quota.h2
-rw-r--r--src/core/lib/iomgr/sockaddr.h2
-rw-r--r--src/core/lib/iomgr/sockaddr_posix.h2
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.cc3
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.h2
-rw-r--r--src/core/lib/iomgr/sockaddr_windows.h2
-rw-r--r--src/core/lib/iomgr/socket_factory_posix.cc2
-rw-r--r--src/core/lib/iomgr/socket_factory_posix.h2
-rw-r--r--src/core/lib/iomgr/socket_mutator.cc2
-rw-r--r--src/core/lib/iomgr/socket_mutator.h2
-rw-r--r--src/core/lib/iomgr/socket_utils.h2
-rw-r--r--src/core/lib/iomgr/socket_utils_common_posix.cc3
-rw-r--r--src/core/lib/iomgr/socket_utils_linux.cc2
-rw-r--r--src/core/lib/iomgr/socket_utils_posix.cc2
-rw-r--r--src/core/lib/iomgr/socket_utils_posix.h2
-rw-r--r--src/core/lib/iomgr/socket_utils_uv.cc2
-rw-r--r--src/core/lib/iomgr/socket_utils_windows.cc2
-rw-r--r--src/core/lib/iomgr/socket_windows.cc2
-rw-r--r--src/core/lib/iomgr/socket_windows.h1
-rw-r--r--src/core/lib/iomgr/sys_epoll_wrapper.h2
-rw-r--r--src/core/lib/iomgr/tcp_client.h2
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.h2
-rw-r--r--src/core/lib/iomgr/tcp_client_uv.cc2
-rw-r--r--src/core/lib/iomgr/tcp_client_windows.cc2
-rw-r--r--src/core/lib/iomgr/tcp_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_posix.h2
-rw-r--r--src/core/lib/iomgr/tcp_server.h2
-rw-r--r--src/core/lib/iomgr/tcp_server_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix.h2
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_common.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_uv.cc2
-rw-r--r--src/core/lib/iomgr/tcp_server_windows.cc2
-rw-r--r--src/core/lib/iomgr/tcp_uv.cc2
-rw-r--r--src/core/lib/iomgr/tcp_uv.h2
-rw-r--r--src/core/lib/iomgr/tcp_windows.cc2
-rw-r--r--src/core/lib/iomgr/tcp_windows.h2
-rw-r--r--src/core/lib/iomgr/time_averaged_stats.cc2
-rw-r--r--src/core/lib/iomgr/timer.h3
-rw-r--r--src/core/lib/iomgr/timer_generic.cc2
-rw-r--r--src/core/lib/iomgr/timer_generic.h2
-rw-r--r--src/core/lib/iomgr/timer_heap.cc2
-rw-r--r--src/core/lib/iomgr/timer_heap.h2
-rw-r--r--src/core/lib/iomgr/timer_manager.cc5
-rw-r--r--src/core/lib/iomgr/timer_manager.h2
-rw-r--r--src/core/lib/iomgr/timer_uv.cc2
-rw-r--r--src/core/lib/iomgr/timer_uv.h2
-rw-r--r--src/core/lib/iomgr/udp_server.cc2
-rw-r--r--src/core/lib/iomgr/udp_server.h2
-rw-r--r--src/core/lib/iomgr/unix_sockets_posix.cc2
-rw-r--r--src/core/lib/iomgr/unix_sockets_posix.h2
-rw-r--r--src/core/lib/iomgr/unix_sockets_posix_noop.cc2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_cv.cc4
-rw-r--r--src/core/lib/iomgr/wakeup_fd_cv.h2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_eventfd.cc2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_nospecial.cc2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_pipe.cc2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_pipe.h2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_posix.cc2
-rw-r--r--src/core/lib/iomgr/wakeup_fd_posix.h2
-rw-r--r--src/core/lib/json/json.cc2
-rw-r--r--src/core/lib/json/json.h3
-rw-r--r--src/core/lib/json/json_reader.cc4
-rw-r--r--src/core/lib/json/json_reader.h1
-rw-r--r--src/core/lib/json/json_string.cc2
-rw-r--r--src/core/lib/json/json_writer.cc4
-rw-r--r--src/core/lib/json/json_writer.h2
-rw-r--r--src/core/lib/profiling/basic_timers.cc2
-rw-r--r--src/core/lib/security/context/security_context.cc2
-rw-r--r--src/core/lib/security/context/security_context.h2
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.h2
-rw-r--r--src/core/lib/security/credentials/credentials.cc2
-rw-r--r--src/core/lib/security/credentials/credentials.h4
-rw-r--r--src/core/lib/security/credentials/credentials_metadata.cc2
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.cc11
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.h5
-rw-r--r--src/core/lib/security/credentials/google_default/credentials_generic.cc2
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/iam/iam_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/iam/iam_credentials.h2
-rw-r--r--src/core/lib/security/credentials/jwt/json_token.cc2
-rw-r--r--src/core/lib/security/credentials/jwt/json_token.h2
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.h2
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.cc2
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_verifier.h2
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.h2
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.h2
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.cc2
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.h2
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc (renamed from src/core/lib/security/transport/security_connector.cc)17
-rw-r--r--src/core/lib/security/security_connector/security_connector.h (renamed from src/core/lib/security/transport/security_connector.h)8
-rw-r--r--src/core/lib/security/transport/auth_filters.h2
-rw-r--r--src/core/lib/security/transport/client_auth_filter.cc4
-rw-r--r--src/core/lib/security/transport/lb_targets_info.cc59
-rw-r--r--src/core/lib/security/transport/secure_endpoint.cc2
-rw-r--r--src/core/lib/security/transport/secure_endpoint.h2
-rw-r--r--src/core/lib/security/transport/security_handshaker.cc2
-rw-r--r--src/core/lib/security/transport/security_handshaker.h4
-rw-r--r--src/core/lib/security/transport/server_auth_filter.cc2
-rw-r--r--src/core/lib/security/transport/target_authority_table.cc75
-rw-r--r--src/core/lib/security/transport/target_authority_table.h40
-rw-r--r--src/core/lib/security/transport/tsi_error.cc2
-rw-r--r--src/core/lib/security/transport/tsi_error.h2
-rw-r--r--src/core/lib/security/util/json_util.cc2
-rw-r--r--src/core/lib/security/util/json_util.h2
-rw-r--r--src/core/lib/slice/b64.cc2
-rw-r--r--src/core/lib/slice/b64.h2
-rw-r--r--src/core/lib/slice/percent_encoding.cc2
-rw-r--r--src/core/lib/slice/percent_encoding.h2
-rw-r--r--src/core/lib/slice/slice.cc2
-rw-r--r--src/core/lib/slice/slice_buffer.cc3
-rw-r--r--src/core/lib/slice/slice_hash_table.cc145
-rw-r--r--src/core/lib/slice/slice_hash_table.h223
-rw-r--r--src/core/lib/slice/slice_intern.cc2
-rw-r--r--src/core/lib/slice/slice_internal.h2
-rw-r--r--src/core/lib/slice/slice_string_helpers.cc2
-rw-r--r--src/core/lib/slice/slice_string_helpers.h3
-rw-r--r--src/core/lib/slice/slice_traits.h2
-rw-r--r--src/core/lib/slice/slice_weak_hash_table.h105
-rw-r--r--src/core/lib/surface/api_trace.cc4
-rw-r--r--src/core/lib/surface/api_trace.h2
-rw-r--r--src/core/lib/surface/byte_buffer.cc2
-rw-r--r--src/core/lib/surface/byte_buffer_reader.cc2
-rw-r--r--src/core/lib/surface/call.cc32
-rw-r--r--src/core/lib/surface/call.h2
-rw-r--r--src/core/lib/surface/call_details.cc2
-rw-r--r--src/core/lib/surface/call_log_batch.cc2
-rw-r--r--src/core/lib/surface/call_test_only.h2
-rw-r--r--src/core/lib/surface/channel.cc2
-rw-r--r--src/core/lib/surface/channel.h2
-rw-r--r--src/core/lib/surface/channel_init.cc2
-rw-r--r--src/core/lib/surface/channel_init.h2
-rw-r--r--src/core/lib/surface/channel_ping.cc2
-rw-r--r--src/core/lib/surface/channel_stack_type.cc5
-rw-r--r--src/core/lib/surface/channel_stack_type.h2
-rw-r--r--src/core/lib/surface/completion_queue.h2
-rw-r--r--src/core/lib/surface/completion_queue_factory.cc4
-rw-r--r--src/core/lib/surface/completion_queue_factory.h2
-rw-r--r--src/core/lib/surface/event_string.cc2
-rw-r--r--src/core/lib/surface/event_string.h2
-rw-r--r--src/core/lib/surface/init.cc2
-rw-r--r--src/core/lib/surface/init_secure.cc2
-rw-r--r--src/core/lib/surface/init_unsecure.cc2
-rw-r--r--src/core/lib/surface/lame_client.cc2
-rw-r--r--src/core/lib/surface/lame_client.h2
-rw-r--r--src/core/lib/surface/metadata_array.cc2
-rw-r--r--src/core/lib/surface/server.cc2
-rw-r--r--src/core/lib/surface/server.h2
-rw-r--r--src/core/lib/surface/validate_metadata.cc3
-rw-r--r--src/core/lib/surface/validate_metadata.h2
-rw-r--r--src/core/lib/surface/version.cc4
-rw-r--r--src/core/lib/transport/bdp_estimator.cc2
-rw-r--r--src/core/lib/transport/byte_stream.cc13
-rw-r--r--src/core/lib/transport/byte_stream.h4
-rw-r--r--src/core/lib/transport/connectivity_state.cc2
-rw-r--r--src/core/lib/transport/connectivity_state.h2
-rw-r--r--src/core/lib/transport/error_utils.cc2
-rw-r--r--src/core/lib/transport/error_utils.h2
-rw-r--r--src/core/lib/transport/metadata.cc2
-rw-r--r--src/core/lib/transport/metadata.h2
-rw-r--r--src/core/lib/transport/metadata_batch.cc26
-rw-r--r--src/core/lib/transport/metadata_batch.h12
-rw-r--r--src/core/lib/transport/pid_controller.cc2
-rw-r--r--src/core/lib/transport/pid_controller.h2
-rw-r--r--src/core/lib/transport/service_config.cc196
-rw-r--r--src/core/lib/transport/service_config.h258
-rw-r--r--src/core/lib/transport/static_metadata.cc604
-rw-r--r--src/core/lib/transport/static_metadata.h178
-rw-r--r--src/core/lib/transport/status_conversion.cc2
-rw-r--r--src/core/lib/transport/status_conversion.h2
-rw-r--r--src/core/lib/transport/status_metadata.cc54
-rw-r--r--src/core/lib/transport/status_metadata.h30
-rw-r--r--src/core/lib/transport/timeout_encoding.cc3
-rw-r--r--src/core/lib/transport/timeout_encoding.h2
-rw-r--r--src/core/lib/transport/transport.cc2
-rw-r--r--src/core/lib/transport/transport.h29
-rw-r--r--src/core/lib/transport/transport_impl.h2
-rw-r--r--src/core/plugin_registry/grpc_cronet_plugin_registry.cc2
-rw-r--r--src/core/plugin_registry/grpc_plugin_registry.cc2
-rw-r--r--src/core/plugin_registry/grpc_unsecure_plugin_registry.cc2
-rw-r--r--src/core/tsi/alts_transport_security.cc2
-rw-r--r--src/core/tsi/alts_transport_security.h5
-rw-r--r--src/core/tsi/fake_transport_security.cc3
-rw-r--r--src/core/tsi/fake_transport_security.h2
-rw-r--r--src/core/tsi/ssl_transport_security.cc6
-rw-r--r--src/core/tsi/ssl_transport_security.h2
-rw-r--r--src/core/tsi/ssl_types.h2
-rw-r--r--src/core/tsi/transport_security.cc2
-rw-r--r--src/core/tsi/transport_security.h2
-rw-r--r--src/core/tsi/transport_security_adapter.cc2
-rw-r--r--src/core/tsi/transport_security_adapter.h2
-rw-r--r--src/core/tsi/transport_security_grpc.cc2
-rw-r--r--src/core/tsi/transport_security_grpc.h2
-rw-r--r--src/core/tsi/transport_security_interface.h2
-rw-r--r--src/cpp/client/channel_cc.cc26
-rw-r--r--src/cpp/client/client_context.cc10
-rw-r--r--src/cpp/client/create_channel.cc8
-rw-r--r--src/cpp/client/create_channel_internal.cc2
-rw-r--r--src/cpp/client/create_channel_internal.h2
-rw-r--r--src/cpp/client/create_channel_posix.cc6
-rw-r--r--src/cpp/client/credentials_cc.cc4
-rw-r--r--src/cpp/client/cronet_credentials.cc6
-rw-r--r--src/cpp/client/generic_stub.cc4
-rw-r--r--src/cpp/client/insecure_credentials.cc8
-rw-r--r--src/cpp/client/secure_credentials.cc6
-rw-r--r--src/cpp/client/secure_credentials.h4
-rw-r--r--src/cpp/codegen/codegen_init.cc4
-rw-r--r--src/cpp/common/alarm.cc8
-rw-r--r--src/cpp/common/auth_property_iterator.cc2
-rw-r--r--src/cpp/common/channel_arguments.cc6
-rw-r--r--src/cpp/common/channel_filter.cc2
-rw-r--r--src/cpp/common/channel_filter.h2
-rw-r--r--src/cpp/common/completion_queue_cc.cc6
-rw-r--r--src/cpp/common/core_codegen.cc4
-rw-r--r--src/cpp/common/insecure_create_auth_context.cc2
-rw-r--r--src/cpp/common/resource_quota_cc.cc2
-rw-r--r--src/cpp/common/rpc_method.cc2
-rw-r--r--src/cpp/common/secure_auth_context.h2
-rw-r--r--src/cpp/common/secure_channel_arguments.cc2
-rw-r--r--src/cpp/common/secure_create_auth_context.cc2
-rw-r--r--src/cpp/common/version_cc.cc4
-rw-r--r--src/cpp/ext/proto_server_reflection.cc2
-rw-r--r--src/cpp/ext/proto_server_reflection.h2
-rw-r--r--src/cpp/ext/proto_server_reflection_plugin.cc8
-rw-r--r--src/cpp/server/async_generic_service.cc4
-rw-r--r--src/cpp/server/channel_argument_option.cc2
-rw-r--r--src/cpp/server/dynamic_thread_pool.h2
-rw-r--r--src/cpp/server/health/default_health_check_service.cc2
-rw-r--r--src/cpp/server/health/default_health_check_service.h6
-rw-r--r--src/cpp/server/health/health_check_service.cc2
-rw-r--r--src/cpp/server/health/health_check_service_server_builder_option.cc2
-rw-r--r--src/cpp/server/insecure_server_credentials.cc2
-rw-r--r--src/cpp/server/secure_server_credentials.cc4
-rw-r--r--src/cpp/server/secure_server_credentials.h2
-rw-r--r--src/cpp/server/server_builder.cc8
-rw-r--r--src/cpp/server/server_cc.cc26
-rw-r--r--src/cpp/server/server_context.cc8
-rw-r--r--src/cpp/server/server_credentials.cc2
-rw-r--r--src/cpp/server/server_posix.cc2
-rw-r--r--src/cpp/thread_manager/thread_manager.h2
-rw-r--r--src/cpp/util/byte_buffer_cc.cc4
-rw-r--r--src/cpp/util/error_details.cc2
-rw-r--r--src/cpp/util/slice_cc.cc2
-rw-r--r--src/cpp/util/status.cc2
-rw-r--r--src/cpp/util/string_ref.cc2
-rw-r--r--src/cpp/util/time_cc.cc4
-rw-r--r--src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs228
-rw-r--r--src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs126
-rw-r--r--src/csharp/Grpc.Core.Tests/MockServiceHelper.cs13
-rw-r--r--src/csharp/Grpc.Core/ClientBase.cs52
-rw-r--r--src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs144
-rw-r--r--src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs88
-rw-r--r--src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs65
-rw-r--r--src/csharp/Grpc.Core/Interceptors/InterceptingCallInvoker.cs96
-rw-r--r--src/csharp/Grpc.Core/Interceptors/Interceptor.cs406
-rw-r--r--src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs82
-rw-r--r--src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs119
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCallHandler.cs35
-rw-r--r--src/csharp/Grpc.Core/ServerServiceDefinition.cs5
-rwxr-xr-xsrc/csharp/Grpc.Core/Version.csproj.include2
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs4
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs13
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs7
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Control.cs142
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs9
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs31
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestGrpc.cs39
-rw-r--r--src/csharp/Grpc.Reflection/ReflectionGrpc.cs5
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat2
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.sh4
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c4
-rw-r--r--src/csharp/global.json2
-rw-r--r--src/csharp/tests.json4
-rw-r--r--src/objective-c/!ProtoCompiler-gRPCPlugin.podspec2
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+MobileLog.h30
-rw-r--r--src/objective-c/GRPCClient/GRPCCall+MobileLog.m33
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m136
-rw-r--r--src/objective-c/GRPCClient/private/GRPCChannel.m25
-rw-r--r--src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h58
-rw-r--r--src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m199
-rw-r--r--src/objective-c/GRPCClient/private/GRPCHost.m31
-rw-r--r--src/objective-c/GRPCClient/private/version.h2
-rw-r--r--src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm3
-rw-r--r--src/objective-c/tests/version.h2
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/version.h2
-rw-r--r--src/python/grpcio/grpc/__init__.py3
-rw-r--r--src/python/grpcio/grpc/_grpcio_metadata.py2
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py8
-rw-r--r--src/python/grpcio/grpc_version.py2
-rw-r--r--src/python/grpcio_health_checking/grpc_version.py2
-rw-r--r--src/python/grpcio_reflection/grpc_version.py2
-rw-r--r--src/python/grpcio_testing/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/grpc_version.py2
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c14
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h23
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/tools/version.rb2
-rw-r--r--summerofcode/ideas.md4
-rw-r--r--templates/Makefile.template5
-rw-r--r--templates/gRPC-C++.podspec.template39
-rw-r--r--templates/src/core/lib/surface/version.cc.template2
-rw-r--r--templates/src/core/plugin_registry.template2
-rw-r--r--templates/src/cpp/common/version_cc.cc.template2
-rw-r--r--templates/tools/dockerfile/test/sanity/Dockerfile.template10
-rw-r--r--test/core/bad_client/bad_client.cc2
-rwxr-xr-xtest/core/bad_ssl/generate_tests.bzl7
-rw-r--r--test/core/client_channel/BUILD11
-rw-r--r--test/core/client_channel/status_util_test.cc49
-rw-r--r--test/core/end2end/BUILD91
-rw-r--r--test/core/end2end/bad_server_response_test.cc2
-rw-r--r--test/core/end2end/dualstack_socket_test.cc2
-rw-r--r--test/core/end2end/end2end_nosec_tests.cc120
-rwxr-xr-xtest/core/end2end/end2end_test.sh4
-rw-r--r--test/core/end2end/end2end_tests.cc120
-rw-r--r--test/core/end2end/fixtures/h2_census.cc2
-rw-r--r--test/core/end2end/fixtures/h2_compress.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full+pipe.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full+trace.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full+workarounds.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full.cc2
-rw-r--r--test/core/end2end/fixtures/h2_http_proxy.cc7
-rw-r--r--test/core/end2end/fixtures/h2_load_reporting.cc2
-rw-r--r--test/core/end2end/fixtures/h2_proxy.cc14
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.cc2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.cc2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.cc2
-rw-r--r--test/core/end2end/fixtures/h2_uds.cc2
-rw-r--r--test/core/end2end/fixtures/http_proxy_fixture.cc7
-rw-r--r--test/core/end2end/fixtures/inproc.cc2
-rw-r--r--test/core/end2end/fixtures/proxy.cc2
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.cc27
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696bin0 -> 92 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680bin0 -> 104 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080bin0 -> 57 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336bin0 -> 43 bytes
-rw-r--r--test/core/end2end/fuzzers/hpack.dictionary8
-rwxr-xr-xtest/core/end2end/gen_build_yaml.py116
-rwxr-xr-xtest/core/end2end/generate_tests.bzl84
-rw-r--r--test/core/end2end/tests/bad_ping.cc2
-rw-r--r--test/core/end2end/tests/connectivity.cc2
-rw-r--r--test/core/end2end/tests/ping.cc2
-rw-r--r--test/core/end2end/tests/retry.cc325
-rw-r--r--test/core/end2end/tests/retry_cancellation.cc277
-rw-r--r--test/core/end2end/tests/retry_disabled.cc262
-rw-r--r--test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc266
-rw-r--r--test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc279
-rw-r--r--test/core/end2end/tests/retry_non_retriable_status.cc257
-rw-r--r--test/core/end2end/tests/retry_recv_initial_metadata.cc268
-rw-r--r--test/core/end2end/tests/retry_recv_message.cc261
-rw-r--r--test/core/end2end/tests/retry_server_pushback_delay.cc318
-rw-r--r--test/core/end2end/tests/retry_server_pushback_disabled.cc306
-rw-r--r--test/core/end2end/tests/retry_streaming.cc424
-rw-r--r--test/core/end2end/tests/retry_streaming_after_commit.cc354
-rw-r--r--test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc400
-rw-r--r--test/core/end2end/tests/retry_throttled.cc264
-rw-r--r--test/core/end2end/tests/retry_too_many_attempts.cc299
-rw-r--r--test/core/gpr/BUILD10
-rw-r--r--test/core/gpr/arena_test.cc2
-rw-r--r--test/core/gpr/cpu_test.cc3
-rw-r--r--test/core/gpr/mpscq_test.cc2
-rw-r--r--test/core/gpr/spinlock_test.cc3
-rw-r--r--test/core/gpr/sync_test.cc3
-rw-r--r--test/core/gpr/thd_test.cc4
-rw-r--r--test/core/gpr/time_test.cc3
-rw-r--r--test/core/gpr/tls_test.cc2
-rw-r--r--test/core/gprpp/manual_constructor_test.cc3
-rw-r--r--test/core/handshake/client_ssl.cc3
-rw-r--r--test/core/handshake/readahead_handshaker_server_ssl.cc3
-rw-r--r--test/core/handshake/server_ssl.cc3
-rw-r--r--test/core/handshake/server_ssl_common.cc3
-rw-r--r--test/core/handshake/server_ssl_common.h3
-rw-r--r--test/core/iomgr/BUILD13
-rw-r--r--test/core/iomgr/combiner_test.cc2
-rw-r--r--test/core/iomgr/error_test.cc2
-rw-r--r--test/core/iomgr/ev_epollsig_linux_test.cc2
-rw-r--r--test/core/iomgr/resolve_address_posix_test.cc2
-rw-r--r--test/core/iomgr/wakeup_fd_cv_test.cc2
-rw-r--r--test/core/network_benchmarks/low_level_ping_pong.cc2
-rw-r--r--test/core/security/BUILD27
-rw-r--r--test/core/security/security_connector_test.cc2
-rw-r--r--test/core/security/ssl_server_fuzzer.cc2
-rw-r--r--test/core/slice/BUILD43
-rw-r--r--test/core/slice/slice_hash_table_test.cc248
-rw-r--r--test/core/slice/slice_weak_hash_table_test.cc105
-rw-r--r--test/core/statistics/rpc_stats_test.cc3
-rw-r--r--test/core/surface/BUILD25
-rw-r--r--test/core/surface/byte_buffer_reader_test.cc2
-rw-r--r--test/core/surface/completion_queue_threading_test.cc2
-rw-r--r--test/core/surface/concurrent_connectivity_test.cc2
-rw-r--r--test/core/surface/num_external_connectivity_watchers_test.cc2
-rw-r--r--test/core/surface/public_headers_must_be_c89.c9
-rw-r--r--test/core/surface/secure_channel_create_test.cc2
-rw-r--r--test/core/surface/sequential_connectivity_test.cc2
-rw-r--r--test/core/transport/BUILD12
-rw-r--r--test/core/transport/chttp2/bin_decoder_test.cc30
-rw-r--r--test/core/transport/status_metadata_test.cc61
-rw-r--r--test/core/tsi/fake_transport_security_test.cc2
-rw-r--r--test/core/tsi/ssl_transport_security_test.cc15
-rw-r--r--test/core/tsi/transport_security_test_lib.cc3
-rw-r--r--test/core/util/fuzzer_corpus_test.cc7
-rw-r--r--test/core/util/grpc_fuzzer.bzl1
-rw-r--r--test/cpp/client/client_channel_stress_test.cc2
-rw-r--r--test/cpp/cocoapods/generic/generic.mm2
-rw-r--r--test/cpp/codegen/compiler_test_golden18
-rw-r--r--test/cpp/codegen/compiler_test_mock_golden4
-rw-r--r--test/cpp/end2end/BUILD21
-rw-r--r--test/cpp/end2end/OWNERS5
-rw-r--r--test/cpp/end2end/async_end2end_test.cc2
-rw-r--r--test/cpp/end2end/client_crash_test.cc2
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc2
-rw-r--r--test/cpp/end2end/end2end_test.cc2
-rw-r--r--test/cpp/end2end/filter_end2end_test.cc2
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc2
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc243
-rw-r--r--test/cpp/end2end/mock_test.cc2
-rw-r--r--test/cpp/end2end/server_crash_test.cc2
-rw-r--r--test/cpp/end2end/server_early_return_test.cc2
-rw-r--r--test/cpp/end2end/streaming_throughput_test.cc2
-rw-r--r--test/cpp/end2end/thread_stress_test.cc2
-rw-r--r--test/cpp/grpclb/BUILD39
-rw-r--r--test/cpp/grpclb/grpclb_test.cc799
-rw-r--r--test/cpp/test/BUILD39
-rw-r--r--test/cpp/thread_manager/BUILD40
-rw-r--r--third_party/BUILD5
-rw-r--r--third_party/constantly.BUILD7
-rw-r--r--third_party/incremental.BUILD10
-rw-r--r--third_party/twisted.BUILD15
-rw-r--r--third_party/yaml.BUILD10
-rw-r--r--third_party/zope_interface.BUILD13
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py8
-rwxr-xr-xtools/distrib/check_include_guards.py4
-rw-r--r--tools/distrib/python/grpcio_tools/grpc_version.py2
-rw-r--r--tools/dockerfile/test/bazel/Dockerfile10
-rw-r--r--tools/dockerfile/test/sanity/Dockerfile10
-rw-r--r--tools/doxygen/Doxyfile.c++83
-rw-r--r--tools/doxygen/Doxyfile.c++.internal86
-rw-r--r--tools/doxygen/Doxyfile.core2
-rw-r--r--tools/doxygen/Doxyfile.core.internal21
-rwxr-xr-xtools/gce/create_interop_worker.sh8
-rwxr-xr-xtools/gce/create_linux_kokoro_performance_worker.sh8
-rwxr-xr-xtools/gce/create_linux_performance_worker.sh8
-rwxr-xr-xtools/gce/create_linux_worker.sh8
-rwxr-xr-xtools/gce/create_windows_debug_worker.sh10
-rwxr-xr-xtools/gce/linux_kokoro_performance_worker_init.sh15
-rwxr-xr-xtools/gce/linux_performance_worker_init.sh13
-rwxr-xr-xtools/gce/linux_worker_init.sh5
-rw-r--r--tools/internal_ci/linux/grpc_asan_on_foundry.sh18
-rwxr-xr-xtools/internal_ci/linux/grpc_bazel_on_foundry_base.sh57
-rw-r--r--tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh43
-rw-r--r--tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh44
-rw-r--r--tools/internal_ci/linux/grpc_msan_on_foundry.sh64
-rw-r--r--tools/internal_ci/linux/grpc_tsan_on_foundry.sh47
-rw-r--r--tools/internal_ci/linux/grpc_ubsan_on_foundry.sh60
-rw-r--r--tools/interop_matrix/client_matrix.py29
-rwxr-xr-xtools/run_tests/artifacts/build_artifact_python.sh28
-rwxr-xr-xtools/run_tests/dockerize/docker_run.sh5
-rwxr-xr-xtools/run_tests/dockerize/docker_run_tests.sh9
-rw-r--r--tools/run_tests/generated/sources_and_headers.json412
-rw-r--r--tools/run_tests/generated/tests.json7391
-rwxr-xr-xtools/run_tests/run_tests_matrix.py6
-rwxr-xr-xtools/run_tests/sanity/check_bazel_workspace.py37
-rwxr-xr-xtools/run_tests/sanity/check_deprecated_grpc++.py191
-rwxr-xr-xtools/run_tests/sanity/check_port_platform.py64
-rwxr-xr-xtools/run_tests/sanity/check_shellcheck.sh1
-rw-r--r--tools/run_tests/sanity/sanity_tests.yaml2
995 files changed, 36473 insertions, 15839 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9c0e9dd867..fb6f98cc82 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -5,6 +5,5 @@
/bazel/** @nicolasnoble @dgquintas @a11r @vjpai
/cmake/** @jtattermusch @nicolasnoble @matt-kwong
/src/core/ext/filters/client_channel/** @markdroth @dgquintas @a11r
-/test/cpp/end2end/** @vjpai @yang-g @y-zeng
/tools/dockerfile/** @jtattermusch @matt-kwong @nicolasnoble
/tools/run_tests/performance/** @ncteisen @matt-kwong @jtattermusch
diff --git a/BUILD b/BUILD
index 67f168031a..ff9fd38952 100644
--- a/BUILD
+++ b/BUILD
@@ -53,12 +53,22 @@ config_setting(
values = {"define": "GRPC_PORT_ISOLATED_RUNTIME=1"},
)
+config_setting(
+ name = "windows",
+ values = {"cpu": "x64_windows"},
+)
+
+config_setting(
+ name = "windows_msvc",
+ values = {"cpu": "x64_windows_msvc"},
+)
+
# This should be updated along with build.yaml
-g_stands_for = "glamorous"
+g_stands_for = "gorgeous"
core_version = "6.0.0-dev"
-version = "1.10.0-dev"
+version = "1.11.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@@ -76,7 +86,7 @@ GPR_PUBLIC_HDRS = [
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_windows.h",
- "include/grpc/support/thd.h",
+ "include/grpc/support/thd_id.h",
"include/grpc/support/time.h",
]
@@ -195,6 +205,53 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
+ "include/grpcpp/alarm.h",
+ "include/grpcpp/channel.h",
+ "include/grpcpp/client_context.h",
+ "include/grpcpp/completion_queue.h",
+ "include/grpcpp/create_channel.h",
+ "include/grpcpp/create_channel_posix.h",
+ "include/grpcpp/ext/health_check_service_server_builder_option.h",
+ "include/grpcpp/generic/async_generic_service.h",
+ "include/grpcpp/generic/generic_stub.h",
+ "include/grpcpp/grpcpp.h",
+ "include/grpcpp/health_check_service_interface.h",
+ "include/grpcpp/impl/call.h",
+ "include/grpcpp/impl/channel_argument_option.h",
+ "include/grpcpp/impl/client_unary_call.h",
+ "include/grpcpp/impl/codegen/core_codegen.h",
+ "include/grpcpp/impl/grpc_library.h",
+ "include/grpcpp/impl/method_handler_impl.h",
+ "include/grpcpp/impl/rpc_method.h",
+ "include/grpcpp/impl/rpc_service_method.h",
+ "include/grpcpp/impl/serialization_traits.h",
+ "include/grpcpp/impl/server_builder_option.h",
+ "include/grpcpp/impl/server_builder_plugin.h",
+ "include/grpcpp/impl/server_initializer.h",
+ "include/grpcpp/impl/service_type.h",
+ "include/grpcpp/impl/sync_cxx11.h",
+ "include/grpcpp/impl/sync_no_cxx11.h",
+ "include/grpcpp/resource_quota.h",
+ "include/grpcpp/security/auth_context.h",
+ "include/grpcpp/security/auth_metadata_processor.h",
+ "include/grpcpp/security/credentials.h",
+ "include/grpcpp/security/server_credentials.h",
+ "include/grpcpp/server.h",
+ "include/grpcpp/server_builder.h",
+ "include/grpcpp/server_context.h",
+ "include/grpcpp/server_posix.h",
+ "include/grpcpp/support/async_stream.h",
+ "include/grpcpp/support/async_unary_call.h",
+ "include/grpcpp/support/byte_buffer.h",
+ "include/grpcpp/support/channel_arguments.h",
+ "include/grpcpp/support/config.h",
+ "include/grpcpp/support/slice.h",
+ "include/grpcpp/support/status.h",
+ "include/grpcpp/support/status_code_enum.h",
+ "include/grpcpp/support/string_ref.h",
+ "include/grpcpp/support/stub_options.h",
+ "include/grpcpp/support/sync_stream.h",
+ "include/grpcpp/support/time.h",
]
grpc_cc_library(
@@ -317,6 +374,7 @@ grpc_cc_library(
],
hdrs = [
"include/grpc++/support/error_details.h",
+ "include/grpcpp/support/error_details.h",
],
language = "c++",
standalone = True,
@@ -494,7 +552,7 @@ grpc_cc_library(
"src/core/lib/gpr/spinlock.h",
"src/core/lib/gpr/string.h",
"src/core/lib/gpr/string_windows.h",
- "src/core/lib/gpr/thd_internal.h",
+ "src/core/lib/gpr/thd.h",
"src/core/lib/gpr/time_precise.h",
"src/core/lib/gpr/tls.h",
"src/core/lib/gpr/tls_gcc.h",
@@ -723,7 +781,6 @@ grpc_cc_library(
"src/core/lib/slice/percent_encoding.cc",
"src/core/lib/slice/slice.cc",
"src/core/lib/slice/slice_buffer.cc",
- "src/core/lib/slice/slice_hash_table.cc",
"src/core/lib/slice/slice_intern.cc",
"src/core/lib/slice/slice_string_helpers.cc",
"src/core/lib/surface/api_trace.cc",
@@ -753,6 +810,7 @@ grpc_cc_library(
"src/core/lib/transport/service_config.cc",
"src/core/lib/transport/static_metadata.cc",
"src/core/lib/transport/status_conversion.cc",
+ "src/core/lib/transport/status_metadata.cc",
"src/core/lib/transport/timeout_encoding.cc",
"src/core/lib/transport/transport.cc",
"src/core/lib/transport/transport_op_string.cc",
@@ -853,6 +911,7 @@ grpc_cc_library(
"src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/slice/slice_weak_hash_table.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
"src/core/lib/surface/call_test_only.h",
@@ -877,6 +936,7 @@ grpc_cc_library(
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
+ "src/core/lib/transport/status_metadata.h",
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h",
@@ -891,9 +951,9 @@ grpc_cc_library(
"gpr_base",
"grpc_codegen",
"grpc_trace",
- ":ref_counted",
- ":ref_counted_ptr",
- ":debug_location",
+ "ref_counted",
+ "ref_counted_ptr",
+ "inlined_vector",
],
)
@@ -948,12 +1008,14 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.cc",
"src/core/ext/filters/client_channel/lb_policy_factory.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
+ "src/core/ext/filters/client_channel/method_params.cc",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
"src/core/ext/filters/client_channel/proxy_mapper_registry.cc",
"src/core/ext/filters/client_channel/resolver.cc",
"src/core/ext/filters/client_channel/resolver_registry.cc",
"src/core/ext/filters/client_channel/retry_throttle.cc",
+ "src/core/ext/filters/client_channel/status_util.cc",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_index.cc",
"src/core/ext/filters/client_channel/uri_parser.cc",
@@ -968,6 +1030,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
+ "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
@@ -975,6 +1038,7 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/status_util.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h",
"src/core/ext/filters/client_channel/uri_parser.h",
@@ -1097,7 +1161,6 @@ grpc_cc_library(
],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
- "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -1126,7 +1189,6 @@ grpc_cc_library(
],
hdrs = [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
- "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -1277,12 +1339,12 @@ grpc_cc_library(
"src/core/lib/security/credentials/oauth2/oauth2_credentials.cc",
"src/core/lib/security/credentials/plugin/plugin_credentials.cc",
"src/core/lib/security/credentials/ssl/ssl_credentials.cc",
+ "src/core/lib/security/security_connector/security_connector.cc",
"src/core/lib/security/transport/client_auth_filter.cc",
- "src/core/lib/security/transport/lb_targets_info.cc",
"src/core/lib/security/transport/secure_endpoint.cc",
- "src/core/lib/security/transport/security_connector.cc",
"src/core/lib/security/transport/security_handshaker.cc",
"src/core/lib/security/transport/server_auth_filter.cc",
+ "src/core/lib/security/transport/target_authority_table.cc",
"src/core/lib/security/transport/tsi_error.cc",
"src/core/lib/security/util/json_util.cc",
"src/core/lib/surface/init_secure.cc",
@@ -1300,11 +1362,11 @@ grpc_cc_library(
"src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
+ "src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
- "src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/secure_endpoint.h",
- "src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/transport/security_handshaker.h",
+ "src/core/lib/security/transport/target_authority_table.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/json_util.h",
],
@@ -1616,6 +1678,36 @@ grpc_cc_library(
"include/grpc++/impl/codegen/stub_options.h",
"include/grpc++/impl/codegen/sync_stream.h",
"include/grpc++/impl/codegen/time.h",
+ "include/grpcpp/impl/codegen/async_stream.h",
+ "include/grpcpp/impl/codegen/async_unary_call.h",
+ "include/grpcpp/impl/codegen/byte_buffer.h",
+ "include/grpcpp/impl/codegen/call.h",
+ "include/grpcpp/impl/codegen/call_hook.h",
+ "include/grpcpp/impl/codegen/channel_interface.h",
+ "include/grpcpp/impl/codegen/client_context.h",
+ "include/grpcpp/impl/codegen/client_unary_call.h",
+ "include/grpcpp/impl/codegen/completion_queue.h",
+ "include/grpcpp/impl/codegen/completion_queue_tag.h",
+ "include/grpcpp/impl/codegen/config.h",
+ "include/grpcpp/impl/codegen/core_codegen_interface.h",
+ "include/grpcpp/impl/codegen/create_auth_context.h",
+ "include/grpcpp/impl/codegen/grpc_library.h",
+ "include/grpcpp/impl/codegen/metadata_map.h",
+ "include/grpcpp/impl/codegen/method_handler_impl.h",
+ "include/grpcpp/impl/codegen/rpc_method.h",
+ "include/grpcpp/impl/codegen/rpc_service_method.h",
+ "include/grpcpp/impl/codegen/security/auth_context.h",
+ "include/grpcpp/impl/codegen/serialization_traits.h",
+ "include/grpcpp/impl/codegen/server_context.h",
+ "include/grpcpp/impl/codegen/server_interface.h",
+ "include/grpcpp/impl/codegen/service_type.h",
+ "include/grpcpp/impl/codegen/slice.h",
+ "include/grpcpp/impl/codegen/status.h",
+ "include/grpcpp/impl/codegen/status_code_enum.h",
+ "include/grpcpp/impl/codegen/string_ref.h",
+ "include/grpcpp/impl/codegen/stub_options.h",
+ "include/grpcpp/impl/codegen/sync_stream.h",
+ "include/grpcpp/impl/codegen/time.h",
],
deps = [
"grpc_codegen",
@@ -1638,6 +1730,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = [
"include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpcpp/impl/codegen/proto_utils.h",
],
deps = [
"grpc++_codegen_base",
@@ -1653,6 +1746,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = [
"include/grpc++/impl/codegen/config_protobuf.h",
+ "include/grpcpp/impl/codegen/config_protobuf.h",
],
)
@@ -1668,6 +1762,7 @@ grpc_cc_library(
language = "c++",
public_hdrs = [
"include/grpc++/ext/proto_server_reflection_plugin.h",
+ "include/grpcpp/ext/proto_server_reflection_plugin.h",
],
deps = [
":grpc++",
@@ -1681,6 +1776,8 @@ grpc_cc_library(
public_hdrs = [
"include/grpc++/test/mock_stream.h",
"include/grpc++/test/server_context_test_spouse.h",
+ "include/grpcpp/test/mock_stream.h",
+ "include/grpcpp/test/server_context_test_spouse.h",
],
deps = [
":grpc++",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c35bfde8f6..c21774dbac 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
-set(PACKAGE_VERSION "1.10.0-dev")
+set(PACKAGE_VERSION "1.11.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -345,7 +345,6 @@ add_dependencies(buildtests_c sequential_connectivity_test)
add_dependencies(buildtests_c server_chttp2_test)
add_dependencies(buildtests_c server_test)
add_dependencies(buildtests_c slice_buffer_test)
-add_dependencies(buildtests_c slice_hash_table_test)
add_dependencies(buildtests_c slice_string_helpers_test)
add_dependencies(buildtests_c slice_test)
add_dependencies(buildtests_c sockaddr_resolver_test)
@@ -539,7 +538,6 @@ add_dependencies(buildtests_cxx grpc_cli)
add_dependencies(buildtests_cxx grpc_tool_test)
add_dependencies(buildtests_cxx grpclb_api_test)
add_dependencies(buildtests_cxx grpclb_end2end_test)
-add_dependencies(buildtests_cxx grpclb_test)
add_dependencies(buildtests_cxx h2_ssl_cert_test)
add_dependencies(buildtests_cxx health_service_end2end_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -596,8 +594,12 @@ add_dependencies(buildtests_cxx server_crash_test_client)
add_dependencies(buildtests_cxx server_early_return_test)
add_dependencies(buildtests_cxx server_request_call_test)
add_dependencies(buildtests_cxx shutdown_test)
+add_dependencies(buildtests_cxx slice_hash_table_test)
+add_dependencies(buildtests_cxx slice_weak_hash_table_test)
add_dependencies(buildtests_cxx stats_test)
+add_dependencies(buildtests_cxx status_metadata_test)
add_dependencies(buildtests_cxx status_test)
+add_dependencies(buildtests_cxx status_util_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx streaming_throughput_test)
endif()
@@ -712,7 +714,7 @@ foreach(_hdr
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
include/grpc/support/sync_windows.h
- include/grpc/support/thd.h
+ include/grpc/support/thd_id.h
include/grpc/support/time.h
include/grpc/impl/codegen/atm.h
include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -885,7 +887,6 @@ add_library(grpc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@@ -916,6 +917,7 @@ add_library(grpc
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
+ src/core/lib/transport/status_metadata.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
@@ -963,12 +965,12 @@ add_library(grpc
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
src/core/lib/security/credentials/plugin/plugin_credentials.cc
src/core/lib/security/credentials/ssl/ssl_credentials.cc
+ src/core/lib/security/security_connector/security_connector.cc
src/core/lib/security/transport/client_auth_filter.cc
- src/core/lib/security/transport/lb_targets_info.cc
src/core/lib/security/transport/secure_endpoint.cc
- src/core/lib/security/transport/security_connector.cc
src/core/lib/security/transport/security_handshaker.cc
src/core/lib/security/transport/server_auth_filter.cc
+ src/core/lib/security/transport/target_authority_table.cc
src/core/lib/security/transport/tsi_error.cc
src/core/lib/security/util/json_util.cc
src/core/lib/surface/init_secure.cc
@@ -991,12 +993,14 @@ add_library(grpc
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/status_util.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
@@ -1227,7 +1231,6 @@ add_library(grpc_cronet
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@@ -1258,6 +1261,7 @@ add_library(grpc_cronet
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
+ src/core/lib/transport/status_metadata.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
@@ -1304,12 +1308,14 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/status_util.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
@@ -1329,12 +1335,12 @@ add_library(grpc_cronet
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
src/core/lib/security/credentials/plugin/plugin_credentials.cc
src/core/lib/security/credentials/ssl/ssl_credentials.cc
+ src/core/lib/security/security_connector/security_connector.cc
src/core/lib/security/transport/client_auth_filter.cc
- src/core/lib/security/transport/lb_targets_info.cc
src/core/lib/security/transport/secure_endpoint.cc
- src/core/lib/security/transport/security_connector.cc
src/core/lib/security/transport/security_handshaker.cc
src/core/lib/security/transport/server_auth_filter.cc
+ src/core/lib/security/transport/target_authority_table.cc
src/core/lib/security/transport/tsi_error.cc
src/core/lib/security/util/json_util.cc
src/core/lib/surface/init_secure.cc
@@ -1556,7 +1562,6 @@ add_library(grpc_test_util
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@@ -1587,6 +1592,7 @@ add_library(grpc_test_util
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
+ src/core/lib/transport/status_metadata.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
@@ -1602,12 +1608,14 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/status_util.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
@@ -1687,7 +1695,7 @@ foreach(_hdr
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
include/grpc/support/sync_windows.h
- include/grpc/support/thd.h
+ include/grpc/support/thd_id.h
include/grpc/support/time.h
include/grpc/impl/codegen/atm.h
include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -1846,7 +1854,6 @@ add_library(grpc_test_util_unsecure
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@@ -1877,6 +1884,7 @@ add_library(grpc_test_util_unsecure
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
+ src/core/lib/transport/status_metadata.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
@@ -1892,12 +1900,14 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/status_util.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
@@ -1977,7 +1987,7 @@ foreach(_hdr
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
include/grpc/support/sync_windows.h
- include/grpc/support/thd.h
+ include/grpc/support/thd_id.h
include/grpc/support/time.h
include/grpc/impl/codegen/atm.h
include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -2115,7 +2125,6 @@ add_library(grpc_unsecure
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@@ -2146,6 +2155,7 @@ add_library(grpc_unsecure
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
+ src/core/lib/transport/status_metadata.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
@@ -2194,12 +2204,14 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/status_util.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
@@ -2523,6 +2535,51 @@ foreach(_hdr
include/grpc++/support/stub_options.h
include/grpc++/support/sync_stream.h
include/grpc++/support/time.h
+ include/grpcpp/alarm.h
+ include/grpcpp/channel.h
+ include/grpcpp/client_context.h
+ include/grpcpp/completion_queue.h
+ include/grpcpp/create_channel.h
+ include/grpcpp/create_channel_posix.h
+ include/grpcpp/ext/health_check_service_server_builder_option.h
+ include/grpcpp/generic/async_generic_service.h
+ include/grpcpp/generic/generic_stub.h
+ include/grpcpp/grpcpp.h
+ include/grpcpp/health_check_service_interface.h
+ include/grpcpp/impl/call.h
+ include/grpcpp/impl/channel_argument_option.h
+ include/grpcpp/impl/client_unary_call.h
+ include/grpcpp/impl/codegen/core_codegen.h
+ include/grpcpp/impl/grpc_library.h
+ include/grpcpp/impl/method_handler_impl.h
+ include/grpcpp/impl/rpc_method.h
+ include/grpcpp/impl/rpc_service_method.h
+ include/grpcpp/impl/serialization_traits.h
+ include/grpcpp/impl/server_builder_option.h
+ include/grpcpp/impl/server_builder_plugin.h
+ include/grpcpp/impl/server_initializer.h
+ include/grpcpp/impl/service_type.h
+ include/grpcpp/resource_quota.h
+ include/grpcpp/security/auth_context.h
+ include/grpcpp/security/auth_metadata_processor.h
+ include/grpcpp/security/credentials.h
+ include/grpcpp/security/server_credentials.h
+ include/grpcpp/server.h
+ include/grpcpp/server_builder.h
+ include/grpcpp/server_context.h
+ include/grpcpp/server_posix.h
+ include/grpcpp/support/async_stream.h
+ include/grpcpp/support/async_unary_call.h
+ include/grpcpp/support/byte_buffer.h
+ include/grpcpp/support/channel_arguments.h
+ include/grpcpp/support/config.h
+ include/grpcpp/support/slice.h
+ include/grpcpp/support/status.h
+ include/grpcpp/support/status_code_enum.h
+ include/grpcpp/support/string_ref.h
+ include/grpcpp/support/stub_options.h
+ include/grpcpp/support/sync_stream.h
+ include/grpcpp/support/time.h
include/grpc/support/alloc.h
include/grpc/support/atm.h
include/grpc/support/atm_gcc_atomic.h
@@ -2538,7 +2595,7 @@ foreach(_hdr
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
include/grpc/support/sync_windows.h
- include/grpc/support/thd.h
+ include/grpc/support/thd_id.h
include/grpc/support/time.h
include/grpc/impl/codegen/atm.h
include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -2603,8 +2660,40 @@ foreach(_hdr
include/grpc++/impl/codegen/stub_options.h
include/grpc++/impl/codegen/sync_stream.h
include/grpc++/impl/codegen/time.h
+ include/grpcpp/impl/codegen/async_stream.h
+ include/grpcpp/impl/codegen/async_unary_call.h
+ include/grpcpp/impl/codegen/byte_buffer.h
+ include/grpcpp/impl/codegen/call.h
+ include/grpcpp/impl/codegen/call_hook.h
+ include/grpcpp/impl/codegen/channel_interface.h
+ include/grpcpp/impl/codegen/client_context.h
+ include/grpcpp/impl/codegen/client_unary_call.h
+ include/grpcpp/impl/codegen/completion_queue.h
+ include/grpcpp/impl/codegen/completion_queue_tag.h
+ include/grpcpp/impl/codegen/config.h
+ include/grpcpp/impl/codegen/core_codegen_interface.h
+ include/grpcpp/impl/codegen/create_auth_context.h
+ include/grpcpp/impl/codegen/grpc_library.h
+ include/grpcpp/impl/codegen/metadata_map.h
+ include/grpcpp/impl/codegen/method_handler_impl.h
+ include/grpcpp/impl/codegen/rpc_method.h
+ include/grpcpp/impl/codegen/rpc_service_method.h
+ include/grpcpp/impl/codegen/security/auth_context.h
+ include/grpcpp/impl/codegen/serialization_traits.h
+ include/grpcpp/impl/codegen/server_context.h
+ include/grpcpp/impl/codegen/server_interface.h
+ include/grpcpp/impl/codegen/service_type.h
+ include/grpcpp/impl/codegen/slice.h
+ include/grpcpp/impl/codegen/status.h
+ include/grpcpp/impl/codegen/status_code_enum.h
+ include/grpcpp/impl/codegen/string_ref.h
+ include/grpcpp/impl/codegen/stub_options.h
+ include/grpcpp/impl/codegen/sync_stream.h
+ include/grpcpp/impl/codegen/time.h
include/grpc++/impl/codegen/proto_utils.h
+ include/grpcpp/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h
+ include/grpcpp/impl/codegen/config_protobuf.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -2839,7 +2928,6 @@ add_library(grpc++_cronet
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_buffer.cc
- src/core/lib/slice/slice_hash_table.cc
src/core/lib/slice/slice_intern.cc
src/core/lib/slice/slice_string_helpers.cc
src/core/lib/surface/api_trace.cc
@@ -2870,6 +2958,7 @@ add_library(grpc++_cronet
src/core/lib/transport/service_config.cc
src/core/lib/transport/static_metadata.cc
src/core/lib/transport/status_conversion.cc
+ src/core/lib/transport/status_metadata.cc
src/core/lib/transport/timeout_encoding.cc
src/core/lib/transport/transport.cc
src/core/lib/transport/transport_op_string.cc
@@ -2890,12 +2979,14 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
+ src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/status_util.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/client_channel/uri_parser.cc
@@ -2989,6 +3080,51 @@ foreach(_hdr
include/grpc++/support/stub_options.h
include/grpc++/support/sync_stream.h
include/grpc++/support/time.h
+ include/grpcpp/alarm.h
+ include/grpcpp/channel.h
+ include/grpcpp/client_context.h
+ include/grpcpp/completion_queue.h
+ include/grpcpp/create_channel.h
+ include/grpcpp/create_channel_posix.h
+ include/grpcpp/ext/health_check_service_server_builder_option.h
+ include/grpcpp/generic/async_generic_service.h
+ include/grpcpp/generic/generic_stub.h
+ include/grpcpp/grpcpp.h
+ include/grpcpp/health_check_service_interface.h
+ include/grpcpp/impl/call.h
+ include/grpcpp/impl/channel_argument_option.h
+ include/grpcpp/impl/client_unary_call.h
+ include/grpcpp/impl/codegen/core_codegen.h
+ include/grpcpp/impl/grpc_library.h
+ include/grpcpp/impl/method_handler_impl.h
+ include/grpcpp/impl/rpc_method.h
+ include/grpcpp/impl/rpc_service_method.h
+ include/grpcpp/impl/serialization_traits.h
+ include/grpcpp/impl/server_builder_option.h
+ include/grpcpp/impl/server_builder_plugin.h
+ include/grpcpp/impl/server_initializer.h
+ include/grpcpp/impl/service_type.h
+ include/grpcpp/resource_quota.h
+ include/grpcpp/security/auth_context.h
+ include/grpcpp/security/auth_metadata_processor.h
+ include/grpcpp/security/credentials.h
+ include/grpcpp/security/server_credentials.h
+ include/grpcpp/server.h
+ include/grpcpp/server_builder.h
+ include/grpcpp/server_context.h
+ include/grpcpp/server_posix.h
+ include/grpcpp/support/async_stream.h
+ include/grpcpp/support/async_unary_call.h
+ include/grpcpp/support/byte_buffer.h
+ include/grpcpp/support/channel_arguments.h
+ include/grpcpp/support/config.h
+ include/grpcpp/support/slice.h
+ include/grpcpp/support/status.h
+ include/grpcpp/support/status_code_enum.h
+ include/grpcpp/support/string_ref.h
+ include/grpcpp/support/stub_options.h
+ include/grpcpp/support/sync_stream.h
+ include/grpcpp/support/time.h
include/grpc/support/alloc.h
include/grpc/support/atm.h
include/grpc/support/atm_gcc_atomic.h
@@ -3004,7 +3140,7 @@ foreach(_hdr
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
include/grpc/support/sync_windows.h
- include/grpc/support/thd.h
+ include/grpc/support/thd_id.h
include/grpc/support/time.h
include/grpc/impl/codegen/atm.h
include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -3069,6 +3205,36 @@ foreach(_hdr
include/grpc++/impl/codegen/stub_options.h
include/grpc++/impl/codegen/sync_stream.h
include/grpc++/impl/codegen/time.h
+ include/grpcpp/impl/codegen/async_stream.h
+ include/grpcpp/impl/codegen/async_unary_call.h
+ include/grpcpp/impl/codegen/byte_buffer.h
+ include/grpcpp/impl/codegen/call.h
+ include/grpcpp/impl/codegen/call_hook.h
+ include/grpcpp/impl/codegen/channel_interface.h
+ include/grpcpp/impl/codegen/client_context.h
+ include/grpcpp/impl/codegen/client_unary_call.h
+ include/grpcpp/impl/codegen/completion_queue.h
+ include/grpcpp/impl/codegen/completion_queue_tag.h
+ include/grpcpp/impl/codegen/config.h
+ include/grpcpp/impl/codegen/core_codegen_interface.h
+ include/grpcpp/impl/codegen/create_auth_context.h
+ include/grpcpp/impl/codegen/grpc_library.h
+ include/grpcpp/impl/codegen/metadata_map.h
+ include/grpcpp/impl/codegen/method_handler_impl.h
+ include/grpcpp/impl/codegen/rpc_method.h
+ include/grpcpp/impl/codegen/rpc_service_method.h
+ include/grpcpp/impl/codegen/security/auth_context.h
+ include/grpcpp/impl/codegen/serialization_traits.h
+ include/grpcpp/impl/codegen/server_context.h
+ include/grpcpp/impl/codegen/server_interface.h
+ include/grpcpp/impl/codegen/service_type.h
+ include/grpcpp/impl/codegen/slice.h
+ include/grpcpp/impl/codegen/status.h
+ include/grpcpp/impl/codegen/status_code_enum.h
+ include/grpcpp/impl/codegen/string_ref.h
+ include/grpcpp/impl/codegen/stub_options.h
+ include/grpcpp/impl/codegen/sync_stream.h
+ include/grpcpp/impl/codegen/time.h
include/grpc/census.h
)
string(REPLACE "include/" "" _path ${_hdr})
@@ -3132,6 +3298,7 @@ target_link_libraries(grpc++_error_details
foreach(_hdr
include/grpc++/support/error_details.h
+ include/grpcpp/support/error_details.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3199,6 +3366,7 @@ target_link_libraries(grpc++_proto_reflection_desc_db
foreach(_hdr
include/grpc++/impl/codegen/config_protobuf.h
+ include/grpcpp/impl/codegen/config_protobuf.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3254,6 +3422,7 @@ target_link_libraries(grpc++_reflection
foreach(_hdr
include/grpc++/ext/proto_server_reflection_plugin.h
+ include/grpcpp/ext/proto_server_reflection_plugin.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3420,6 +3589,36 @@ foreach(_hdr
include/grpc++/impl/codegen/stub_options.h
include/grpc++/impl/codegen/sync_stream.h
include/grpc++/impl/codegen/time.h
+ include/grpcpp/impl/codegen/async_stream.h
+ include/grpcpp/impl/codegen/async_unary_call.h
+ include/grpcpp/impl/codegen/byte_buffer.h
+ include/grpcpp/impl/codegen/call.h
+ include/grpcpp/impl/codegen/call_hook.h
+ include/grpcpp/impl/codegen/channel_interface.h
+ include/grpcpp/impl/codegen/client_context.h
+ include/grpcpp/impl/codegen/client_unary_call.h
+ include/grpcpp/impl/codegen/completion_queue.h
+ include/grpcpp/impl/codegen/completion_queue_tag.h
+ include/grpcpp/impl/codegen/config.h
+ include/grpcpp/impl/codegen/core_codegen_interface.h
+ include/grpcpp/impl/codegen/create_auth_context.h
+ include/grpcpp/impl/codegen/grpc_library.h
+ include/grpcpp/impl/codegen/metadata_map.h
+ include/grpcpp/impl/codegen/method_handler_impl.h
+ include/grpcpp/impl/codegen/rpc_method.h
+ include/grpcpp/impl/codegen/rpc_service_method.h
+ include/grpcpp/impl/codegen/security/auth_context.h
+ include/grpcpp/impl/codegen/serialization_traits.h
+ include/grpcpp/impl/codegen/server_context.h
+ include/grpcpp/impl/codegen/server_interface.h
+ include/grpcpp/impl/codegen/service_type.h
+ include/grpcpp/impl/codegen/slice.h
+ include/grpcpp/impl/codegen/status.h
+ include/grpcpp/impl/codegen/status_code_enum.h
+ include/grpcpp/impl/codegen/string_ref.h
+ include/grpcpp/impl/codegen/stub_options.h
+ include/grpcpp/impl/codegen/sync_stream.h
+ include/grpcpp/impl/codegen/time.h
include/grpc/impl/codegen/byte_buffer.h
include/grpc/impl/codegen/byte_buffer_reader.h
include/grpc/impl/codegen/compression_types.h
@@ -3442,7 +3641,9 @@ foreach(_hdr
include/grpc/impl/codegen/sync_posix.h
include/grpc/impl/codegen/sync_windows.h
include/grpc++/impl/codegen/proto_utils.h
+ include/grpcpp/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h
+ include/grpcpp/impl/codegen/config_protobuf.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3558,6 +3759,36 @@ foreach(_hdr
include/grpc++/impl/codegen/stub_options.h
include/grpc++/impl/codegen/sync_stream.h
include/grpc++/impl/codegen/time.h
+ include/grpcpp/impl/codegen/async_stream.h
+ include/grpcpp/impl/codegen/async_unary_call.h
+ include/grpcpp/impl/codegen/byte_buffer.h
+ include/grpcpp/impl/codegen/call.h
+ include/grpcpp/impl/codegen/call_hook.h
+ include/grpcpp/impl/codegen/channel_interface.h
+ include/grpcpp/impl/codegen/client_context.h
+ include/grpcpp/impl/codegen/client_unary_call.h
+ include/grpcpp/impl/codegen/completion_queue.h
+ include/grpcpp/impl/codegen/completion_queue_tag.h
+ include/grpcpp/impl/codegen/config.h
+ include/grpcpp/impl/codegen/core_codegen_interface.h
+ include/grpcpp/impl/codegen/create_auth_context.h
+ include/grpcpp/impl/codegen/grpc_library.h
+ include/grpcpp/impl/codegen/metadata_map.h
+ include/grpcpp/impl/codegen/method_handler_impl.h
+ include/grpcpp/impl/codegen/rpc_method.h
+ include/grpcpp/impl/codegen/rpc_service_method.h
+ include/grpcpp/impl/codegen/security/auth_context.h
+ include/grpcpp/impl/codegen/serialization_traits.h
+ include/grpcpp/impl/codegen/server_context.h
+ include/grpcpp/impl/codegen/server_interface.h
+ include/grpcpp/impl/codegen/service_type.h
+ include/grpcpp/impl/codegen/slice.h
+ include/grpcpp/impl/codegen/status.h
+ include/grpcpp/impl/codegen/status_code_enum.h
+ include/grpcpp/impl/codegen/string_ref.h
+ include/grpcpp/impl/codegen/stub_options.h
+ include/grpcpp/impl/codegen/sync_stream.h
+ include/grpcpp/impl/codegen/time.h
include/grpc/impl/codegen/byte_buffer.h
include/grpc/impl/codegen/byte_buffer_reader.h
include/grpc/impl/codegen/compression_types.h
@@ -3580,7 +3811,9 @@ foreach(_hdr
include/grpc/impl/codegen/sync_posix.h
include/grpc/impl/codegen/sync_windows.h
include/grpc++/impl/codegen/proto_utils.h
+ include/grpcpp/impl/codegen/proto_utils.h
include/grpc++/impl/codegen/config_protobuf.h
+ include/grpcpp/impl/codegen/config_protobuf.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3710,6 +3943,51 @@ foreach(_hdr
include/grpc++/support/stub_options.h
include/grpc++/support/sync_stream.h
include/grpc++/support/time.h
+ include/grpcpp/alarm.h
+ include/grpcpp/channel.h
+ include/grpcpp/client_context.h
+ include/grpcpp/completion_queue.h
+ include/grpcpp/create_channel.h
+ include/grpcpp/create_channel_posix.h
+ include/grpcpp/ext/health_check_service_server_builder_option.h
+ include/grpcpp/generic/async_generic_service.h
+ include/grpcpp/generic/generic_stub.h
+ include/grpcpp/grpcpp.h
+ include/grpcpp/health_check_service_interface.h
+ include/grpcpp/impl/call.h
+ include/grpcpp/impl/channel_argument_option.h
+ include/grpcpp/impl/client_unary_call.h
+ include/grpcpp/impl/codegen/core_codegen.h
+ include/grpcpp/impl/grpc_library.h
+ include/grpcpp/impl/method_handler_impl.h
+ include/grpcpp/impl/rpc_method.h
+ include/grpcpp/impl/rpc_service_method.h
+ include/grpcpp/impl/serialization_traits.h
+ include/grpcpp/impl/server_builder_option.h
+ include/grpcpp/impl/server_builder_plugin.h
+ include/grpcpp/impl/server_initializer.h
+ include/grpcpp/impl/service_type.h
+ include/grpcpp/resource_quota.h
+ include/grpcpp/security/auth_context.h
+ include/grpcpp/security/auth_metadata_processor.h
+ include/grpcpp/security/credentials.h
+ include/grpcpp/security/server_credentials.h
+ include/grpcpp/server.h
+ include/grpcpp/server_builder.h
+ include/grpcpp/server_context.h
+ include/grpcpp/server_posix.h
+ include/grpcpp/support/async_stream.h
+ include/grpcpp/support/async_unary_call.h
+ include/grpcpp/support/byte_buffer.h
+ include/grpcpp/support/channel_arguments.h
+ include/grpcpp/support/config.h
+ include/grpcpp/support/slice.h
+ include/grpcpp/support/status.h
+ include/grpcpp/support/status_code_enum.h
+ include/grpcpp/support/string_ref.h
+ include/grpcpp/support/stub_options.h
+ include/grpcpp/support/sync_stream.h
+ include/grpcpp/support/time.h
include/grpc/support/alloc.h
include/grpc/support/atm.h
include/grpc/support/atm_gcc_atomic.h
@@ -3725,7 +4003,7 @@ foreach(_hdr
include/grpc/support/sync_generic.h
include/grpc/support/sync_posix.h
include/grpc/support/sync_windows.h
- include/grpc/support/thd.h
+ include/grpc/support/thd_id.h
include/grpc/support/time.h
include/grpc/impl/codegen/atm.h
include/grpc/impl/codegen/atm_gcc_atomic.h
@@ -3790,6 +4068,36 @@ foreach(_hdr
include/grpc++/impl/codegen/stub_options.h
include/grpc++/impl/codegen/sync_stream.h
include/grpc++/impl/codegen/time.h
+ include/grpcpp/impl/codegen/async_stream.h
+ include/grpcpp/impl/codegen/async_unary_call.h
+ include/grpcpp/impl/codegen/byte_buffer.h
+ include/grpcpp/impl/codegen/call.h
+ include/grpcpp/impl/codegen/call_hook.h
+ include/grpcpp/impl/codegen/channel_interface.h
+ include/grpcpp/impl/codegen/client_context.h
+ include/grpcpp/impl/codegen/client_unary_call.h
+ include/grpcpp/impl/codegen/completion_queue.h
+ include/grpcpp/impl/codegen/completion_queue_tag.h
+ include/grpcpp/impl/codegen/config.h
+ include/grpcpp/impl/codegen/core_codegen_interface.h
+ include/grpcpp/impl/codegen/create_auth_context.h
+ include/grpcpp/impl/codegen/grpc_library.h
+ include/grpcpp/impl/codegen/metadata_map.h
+ include/grpcpp/impl/codegen/method_handler_impl.h
+ include/grpcpp/impl/codegen/rpc_method.h
+ include/grpcpp/impl/codegen/rpc_service_method.h
+ include/grpcpp/impl/codegen/security/auth_context.h
+ include/grpcpp/impl/codegen/serialization_traits.h
+ include/grpcpp/impl/codegen/server_context.h
+ include/grpcpp/impl/codegen/server_interface.h
+ include/grpcpp/impl/codegen/service_type.h
+ include/grpcpp/impl/codegen/slice.h
+ include/grpcpp/impl/codegen/status.h
+ include/grpcpp/impl/codegen/status_code_enum.h
+ include/grpcpp/impl/codegen/string_ref.h
+ include/grpcpp/impl/codegen/stub_options.h
+ include/grpcpp/impl/codegen/sync_stream.h
+ include/grpcpp/impl/codegen/time.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3908,6 +4216,7 @@ target_link_libraries(grpc_cli_libs
foreach(_hdr
include/grpc++/impl/codegen/config_protobuf.h
+ include/grpcpp/impl/codegen/config_protobuf.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -3960,6 +4269,7 @@ target_link_libraries(grpc_plugin_support
foreach(_hdr
include/grpc++/impl/codegen/config_protobuf.h
+ include/grpcpp/impl/codegen/config_protobuf.h
)
string(REPLACE "include/" "" _path ${_hdr})
get_filename_component(_path ${_path} PATH)
@@ -4588,6 +4898,21 @@ add_library(end2end_tests
test/core/end2end/tests/request_with_flags.cc
test/core/end2end/tests/request_with_payload.cc
test/core/end2end/tests/resource_quota_server.cc
+ test/core/end2end/tests/retry.cc
+ test/core/end2end/tests/retry_cancellation.cc
+ test/core/end2end/tests/retry_disabled.cc
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
+ test/core/end2end/tests/retry_non_retriable_status.cc
+ test/core/end2end/tests/retry_recv_initial_metadata.cc
+ test/core/end2end/tests/retry_recv_message.cc
+ test/core/end2end/tests/retry_server_pushback_delay.cc
+ test/core/end2end/tests/retry_server_pushback_disabled.cc
+ test/core/end2end/tests/retry_streaming.cc
+ test/core/end2end/tests/retry_streaming_after_commit.cc
+ test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
+ test/core/end2end/tests/retry_throttled.cc
+ test/core/end2end/tests/retry_too_many_attempts.cc
test/core/end2end/tests/server_finishes_request.cc
test/core/end2end/tests/shutdown_finishes_calls.cc
test/core/end2end/tests/shutdown_finishes_tags.cc
@@ -4688,6 +5013,21 @@ add_library(end2end_nosec_tests
test/core/end2end/tests/request_with_flags.cc
test/core/end2end/tests/request_with_payload.cc
test/core/end2end/tests/resource_quota_server.cc
+ test/core/end2end/tests/retry.cc
+ test/core/end2end/tests/retry_cancellation.cc
+ test/core/end2end/tests/retry_disabled.cc
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
+ test/core/end2end/tests/retry_non_retriable_status.cc
+ test/core/end2end/tests/retry_recv_initial_metadata.cc
+ test/core/end2end/tests/retry_recv_message.cc
+ test/core/end2end/tests/retry_server_pushback_delay.cc
+ test/core/end2end/tests/retry_server_pushback_disabled.cc
+ test/core/end2end/tests/retry_streaming.cc
+ test/core/end2end/tests/retry_streaming_after_commit.cc
+ test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
+ test/core/end2end/tests/retry_throttled.cc
+ test/core/end2end/tests/retry_too_many_attempts.cc
test/core/end2end/tests/server_finishes_request.cc
test/core/end2end/tests/shutdown_finishes_calls.cc
test/core/end2end/tests/shutdown_finishes_tags.cc
@@ -7627,33 +7967,6 @@ target_link_libraries(slice_buffer_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-add_executable(slice_hash_table_test
- test/core/slice/slice_hash_table_test.cc
-)
-
-
-target_include_directories(slice_hash_table_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
- PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
- PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
- PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
- PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
- PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
-)
-
-target_link_libraries(slice_hash_table_test
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc_test_util
- grpc
- gpr_test_util
- gpr
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
add_executable(slice_string_helpers_test
test/core/slice/slice_string_helpers_test.cc
)
@@ -10377,51 +10690,6 @@ target_link_libraries(grpclb_end2end_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-add_executable(grpclb_test
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.pb.h
- ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lb/v1/load_balancer.grpc.pb.h
- test/cpp/grpclb/grpclb_test.cc
- third_party/googletest/googletest/src/gtest-all.cc
- third_party/googletest/googlemock/src/gmock-all.cc
-)
-
-protobuf_generate_grpc_cpp(
- src/proto/grpc/lb/v1/load_balancer.proto
-)
-
-target_include_directories(grpclb_test
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
- PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
- PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
- PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
- PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
- PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
- PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
- PRIVATE third_party/googletest/googletest/include
- PRIVATE third_party/googletest/googletest
- PRIVATE third_party/googletest/googlemock/include
- PRIVATE third_party/googletest/googlemock
- PRIVATE ${_gRPC_PROTO_GENS_DIR}
-)
-
-target_link_libraries(grpclb_test
- ${_gRPC_PROTOBUF_LIBRARIES}
- ${_gRPC_ALLTARGETS_LIBRARIES}
- grpc++_test_util
- grpc_test_util
- grpc++
- grpc
- gpr_test_util
- gpr
- ${_gRPC_GFLAGS_LIBRARIES}
-)
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
add_executable(h2_ssl_cert_test
test/core/end2end/h2_ssl_cert_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -11896,6 +12164,78 @@ target_link_libraries(shutdown_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(slice_hash_table_test
+ test/core/slice/slice_hash_table_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(slice_hash_table_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(slice_hash_table_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
+add_executable(slice_weak_hash_table_test
+ test/core/slice/slice_weak_hash_table_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(slice_weak_hash_table_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(slice_weak_hash_table_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(stats_test
test/core/debug/stats_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -11933,6 +12273,39 @@ target_link_libraries(stats_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(status_metadata_test
+ test/core/transport/status_metadata_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(status_metadata_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(status_metadata_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(status_test
test/cpp/util/status_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -11969,6 +12342,39 @@ target_link_libraries(status_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+
+add_executable(status_util_test
+ test/core/client_channel/status_util_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(status_util_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(status_util_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(streaming_throughput_test
diff --git a/Makefile b/Makefile
index 1f0498231d..2f34a995f7 100644
--- a/Makefile
+++ b/Makefile
@@ -419,8 +419,8 @@ Q = @
endif
CORE_VERSION = 6.0.0-dev
-CPP_VERSION = 1.10.0-dev
-CSHARP_VERSION = 1.10.0-dev
+CPP_VERSION = 1.11.0-dev
+CSHARP_VERSION = 1.11.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -1068,7 +1068,6 @@ server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test
server_fuzzer: $(BINDIR)/$(CONFIG)/server_fuzzer
server_test: $(BINDIR)/$(CONFIG)/server_test
slice_buffer_test: $(BINDIR)/$(CONFIG)/slice_buffer_test
-slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
slice_string_helpers_test: $(BINDIR)/$(CONFIG)/slice_string_helpers_test
slice_test: $(BINDIR)/$(CONFIG)/slice_test
sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
@@ -1146,7 +1145,6 @@ grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
grpclb_end2end_test: $(BINDIR)/$(CONFIG)/grpclb_end2end_test
-grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
h2_ssl_cert_test: $(BINDIR)/$(CONFIG)/h2_ssl_cert_test
health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test
http2_client: $(BINDIR)/$(CONFIG)/http2_client
@@ -1183,8 +1181,12 @@ server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client
server_early_return_test: $(BINDIR)/$(CONFIG)/server_early_return_test
server_request_call_test: $(BINDIR)/$(CONFIG)/server_request_call_test
shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test
+slice_hash_table_test: $(BINDIR)/$(CONFIG)/slice_hash_table_test
+slice_weak_hash_table_test: $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test
stats_test: $(BINDIR)/$(CONFIG)/stats_test
+status_metadata_test: $(BINDIR)/$(CONFIG)/status_metadata_test
status_test: $(BINDIR)/$(CONFIG)/status_test
+status_util_test: $(BINDIR)/$(CONFIG)/status_util_test
streaming_throughput_test: $(BINDIR)/$(CONFIG)/streaming_throughput_test
stress_test: $(BINDIR)/$(CONFIG)/stress_test
thread_manager_test: $(BINDIR)/$(CONFIG)/thread_manager_test
@@ -1472,7 +1474,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/server_chttp2_test \
$(BINDIR)/$(CONFIG)/server_test \
$(BINDIR)/$(CONFIG)/slice_buffer_test \
- $(BINDIR)/$(CONFIG)/slice_hash_table_test \
$(BINDIR)/$(CONFIG)/slice_string_helpers_test \
$(BINDIR)/$(CONFIG)/slice_test \
$(BINDIR)/$(CONFIG)/sockaddr_resolver_test \
@@ -1606,7 +1607,6 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \
$(BINDIR)/$(CONFIG)/grpclb_end2end_test \
- $(BINDIR)/$(CONFIG)/grpclb_test \
$(BINDIR)/$(CONFIG)/h2_ssl_cert_test \
$(BINDIR)/$(CONFIG)/health_service_end2end_test \
$(BINDIR)/$(CONFIG)/http2_client \
@@ -1643,8 +1643,12 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
+ $(BINDIR)/$(CONFIG)/slice_hash_table_test \
+ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \
$(BINDIR)/$(CONFIG)/stats_test \
+ $(BINDIR)/$(CONFIG)/status_metadata_test \
$(BINDIR)/$(CONFIG)/status_test \
+ $(BINDIR)/$(CONFIG)/status_util_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
@@ -1751,7 +1755,6 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/grpc_tool_test \
$(BINDIR)/$(CONFIG)/grpclb_api_test \
$(BINDIR)/$(CONFIG)/grpclb_end2end_test \
- $(BINDIR)/$(CONFIG)/grpclb_test \
$(BINDIR)/$(CONFIG)/h2_ssl_cert_test \
$(BINDIR)/$(CONFIG)/health_service_end2end_test \
$(BINDIR)/$(CONFIG)/http2_client \
@@ -1788,8 +1791,12 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/server_early_return_test \
$(BINDIR)/$(CONFIG)/server_request_call_test \
$(BINDIR)/$(CONFIG)/shutdown_test \
+ $(BINDIR)/$(CONFIG)/slice_hash_table_test \
+ $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test \
$(BINDIR)/$(CONFIG)/stats_test \
+ $(BINDIR)/$(CONFIG)/status_metadata_test \
$(BINDIR)/$(CONFIG)/status_test \
+ $(BINDIR)/$(CONFIG)/status_util_test \
$(BINDIR)/$(CONFIG)/streaming_throughput_test \
$(BINDIR)/$(CONFIG)/stress_test \
$(BINDIR)/$(CONFIG)/thread_manager_test \
@@ -2001,8 +2008,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/server_test || ( echo test server_test failed ; exit 1 )
$(E) "[RUN] Testing slice_buffer_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_buffer_test || ( echo test slice_buffer_test failed ; exit 1 )
- $(E) "[RUN] Testing slice_hash_table_test"
- $(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
$(E) "[RUN] Testing slice_string_helpers_test"
$(Q) $(BINDIR)/$(CONFIG)/slice_string_helpers_test || ( echo test slice_string_helpers_test failed ; exit 1 )
$(E) "[RUN] Testing slice_test"
@@ -2167,8 +2172,6 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
$(E) "[RUN] Testing grpclb_end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/grpclb_end2end_test || ( echo test grpclb_end2end_test failed ; exit 1 )
- $(E) "[RUN] Testing grpclb_test"
- $(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 )
$(E) "[RUN] Testing h2_ssl_cert_test"
$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_cert_test || ( echo test h2_ssl_cert_test failed ; exit 1 )
$(E) "[RUN] Testing health_service_end2end_test"
@@ -2217,10 +2220,18 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/server_request_call_test || ( echo test server_request_call_test failed ; exit 1 )
$(E) "[RUN] Testing shutdown_test"
$(Q) $(BINDIR)/$(CONFIG)/shutdown_test || ( echo test shutdown_test failed ; exit 1 )
+ $(E) "[RUN] Testing slice_hash_table_test"
+ $(Q) $(BINDIR)/$(CONFIG)/slice_hash_table_test || ( echo test slice_hash_table_test failed ; exit 1 )
+ $(E) "[RUN] Testing slice_weak_hash_table_test"
+ $(Q) $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test || ( echo test slice_weak_hash_table_test failed ; exit 1 )
$(E) "[RUN] Testing stats_test"
$(Q) $(BINDIR)/$(CONFIG)/stats_test || ( echo test stats_test failed ; exit 1 )
+ $(E) "[RUN] Testing status_metadata_test"
+ $(Q) $(BINDIR)/$(CONFIG)/status_metadata_test || ( echo test status_metadata_test failed ; exit 1 )
$(E) "[RUN] Testing status_test"
$(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 )
+ $(E) "[RUN] Testing status_util_test"
+ $(Q) $(BINDIR)/$(CONFIG)/status_util_test || ( echo test status_util_test failed ; exit 1 )
$(E) "[RUN] Testing streaming_throughput_test"
$(Q) $(BINDIR)/$(CONFIG)/streaming_throughput_test || ( echo test streaming_throughput_test failed ; exit 1 )
$(E) "[RUN] Testing thread_manager_test"
@@ -2856,6 +2867,11 @@ install-plugins: $(PROTOC_PLUGINS)
$(Q) $(INSTALL) -d $(prefix)/bin
$(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin
+install-grpc-cli: grpc_cli
+ $(E) "[INSTALL] Installing grpc cli"
+ $(Q) $(INSTALL) -d $(prefix)/bin
+ $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cli $(prefix)/bin/grpc_cli
+
install-pkg-config_c: pc_c pc_c_unsecure
$(E) "[INSTALL] Installing C pkg-config files"
$(Q) $(INSTALL) -d $(prefix)/lib/pkgconfig
@@ -2939,7 +2955,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
- include/grpc/support/thd.h \
+ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -3121,7 +3137,6 @@ LIBGRPC_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -3152,6 +3167,7 @@ LIBGRPC_SRC = \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -3199,12 +3215,12 @@ LIBGRPC_SRC = \
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
+ src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
- src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/secure_endpoint.cc \
- src/core/lib/security/transport/security_connector.cc \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/server_auth_filter.cc \
+ src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
@@ -3227,12 +3243,14 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -3465,7 +3483,6 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -3496,6 +3513,7 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -3542,12 +3560,14 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -3567,12 +3587,12 @@ LIBGRPC_CRONET_SRC = \
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
+ src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
- src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/secure_endpoint.cc \
- src/core/lib/security/transport/security_connector.cc \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/server_auth_filter.cc \
+ src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
@@ -3795,7 +3815,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -3826,6 +3845,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -3841,12 +3861,14 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -3895,7 +3917,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
- include/grpc/support/thd.h \
+ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -4078,7 +4100,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -4109,6 +4130,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -4124,12 +4146,14 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -4178,7 +4202,7 @@ PUBLIC_HEADERS_C += \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
- include/grpc/support/thd.h \
+ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -4327,7 +4351,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -4358,6 +4381,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -4406,12 +4430,14 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -4688,6 +4714,51 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
+ include/grpcpp/alarm.h \
+ include/grpcpp/channel.h \
+ include/grpcpp/client_context.h \
+ include/grpcpp/completion_queue.h \
+ include/grpcpp/create_channel.h \
+ include/grpcpp/create_channel_posix.h \
+ include/grpcpp/ext/health_check_service_server_builder_option.h \
+ include/grpcpp/generic/async_generic_service.h \
+ include/grpcpp/generic/generic_stub.h \
+ include/grpcpp/grpcpp.h \
+ include/grpcpp/health_check_service_interface.h \
+ include/grpcpp/impl/call.h \
+ include/grpcpp/impl/channel_argument_option.h \
+ include/grpcpp/impl/client_unary_call.h \
+ include/grpcpp/impl/codegen/core_codegen.h \
+ include/grpcpp/impl/grpc_library.h \
+ include/grpcpp/impl/method_handler_impl.h \
+ include/grpcpp/impl/rpc_method.h \
+ include/grpcpp/impl/rpc_service_method.h \
+ include/grpcpp/impl/serialization_traits.h \
+ include/grpcpp/impl/server_builder_option.h \
+ include/grpcpp/impl/server_builder_plugin.h \
+ include/grpcpp/impl/server_initializer.h \
+ include/grpcpp/impl/service_type.h \
+ include/grpcpp/resource_quota.h \
+ include/grpcpp/security/auth_context.h \
+ include/grpcpp/security/auth_metadata_processor.h \
+ include/grpcpp/security/credentials.h \
+ include/grpcpp/security/server_credentials.h \
+ include/grpcpp/server.h \
+ include/grpcpp/server_builder.h \
+ include/grpcpp/server_context.h \
+ include/grpcpp/server_posix.h \
+ include/grpcpp/support/async_stream.h \
+ include/grpcpp/support/async_unary_call.h \
+ include/grpcpp/support/byte_buffer.h \
+ include/grpcpp/support/channel_arguments.h \
+ include/grpcpp/support/config.h \
+ include/grpcpp/support/slice.h \
+ include/grpcpp/support/status.h \
+ include/grpcpp/support/status_code_enum.h \
+ include/grpcpp/support/string_ref.h \
+ include/grpcpp/support/stub_options.h \
+ include/grpcpp/support/sync_stream.h \
+ include/grpcpp/support/time.h \
include/grpc/support/alloc.h \
include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \
@@ -4703,7 +4774,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
- include/grpc/support/thd.h \
+ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -4768,8 +4839,40 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/stub_options.h \
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
+ include/grpcpp/impl/codegen/async_stream.h \
+ include/grpcpp/impl/codegen/async_unary_call.h \
+ include/grpcpp/impl/codegen/byte_buffer.h \
+ include/grpcpp/impl/codegen/call.h \
+ include/grpcpp/impl/codegen/call_hook.h \
+ include/grpcpp/impl/codegen/channel_interface.h \
+ include/grpcpp/impl/codegen/client_context.h \
+ include/grpcpp/impl/codegen/client_unary_call.h \
+ include/grpcpp/impl/codegen/completion_queue.h \
+ include/grpcpp/impl/codegen/completion_queue_tag.h \
+ include/grpcpp/impl/codegen/config.h \
+ include/grpcpp/impl/codegen/core_codegen_interface.h \
+ include/grpcpp/impl/codegen/create_auth_context.h \
+ include/grpcpp/impl/codegen/grpc_library.h \
+ include/grpcpp/impl/codegen/metadata_map.h \
+ include/grpcpp/impl/codegen/method_handler_impl.h \
+ include/grpcpp/impl/codegen/rpc_method.h \
+ include/grpcpp/impl/codegen/rpc_service_method.h \
+ include/grpcpp/impl/codegen/security/auth_context.h \
+ include/grpcpp/impl/codegen/serialization_traits.h \
+ include/grpcpp/impl/codegen/server_context.h \
+ include/grpcpp/impl/codegen/server_interface.h \
+ include/grpcpp/impl/codegen/service_type.h \
+ include/grpcpp/impl/codegen/slice.h \
+ include/grpcpp/impl/codegen/status.h \
+ include/grpcpp/impl/codegen/status_code_enum.h \
+ include/grpcpp/impl/codegen/string_ref.h \
+ include/grpcpp/impl/codegen/stub_options.h \
+ include/grpcpp/impl/codegen/sync_stream.h \
+ include/grpcpp/impl/codegen/time.h \
include/grpc++/impl/codegen/proto_utils.h \
+ include/grpcpp/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
+ include/grpcpp/impl/codegen/config_protobuf.h \
LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
@@ -5052,7 +5155,6 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -5083,6 +5185,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -5103,12 +5206,14 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -5167,6 +5272,51 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
+ include/grpcpp/alarm.h \
+ include/grpcpp/channel.h \
+ include/grpcpp/client_context.h \
+ include/grpcpp/completion_queue.h \
+ include/grpcpp/create_channel.h \
+ include/grpcpp/create_channel_posix.h \
+ include/grpcpp/ext/health_check_service_server_builder_option.h \
+ include/grpcpp/generic/async_generic_service.h \
+ include/grpcpp/generic/generic_stub.h \
+ include/grpcpp/grpcpp.h \
+ include/grpcpp/health_check_service_interface.h \
+ include/grpcpp/impl/call.h \
+ include/grpcpp/impl/channel_argument_option.h \
+ include/grpcpp/impl/client_unary_call.h \
+ include/grpcpp/impl/codegen/core_codegen.h \
+ include/grpcpp/impl/grpc_library.h \
+ include/grpcpp/impl/method_handler_impl.h \
+ include/grpcpp/impl/rpc_method.h \
+ include/grpcpp/impl/rpc_service_method.h \
+ include/grpcpp/impl/serialization_traits.h \
+ include/grpcpp/impl/server_builder_option.h \
+ include/grpcpp/impl/server_builder_plugin.h \
+ include/grpcpp/impl/server_initializer.h \
+ include/grpcpp/impl/service_type.h \
+ include/grpcpp/resource_quota.h \
+ include/grpcpp/security/auth_context.h \
+ include/grpcpp/security/auth_metadata_processor.h \
+ include/grpcpp/security/credentials.h \
+ include/grpcpp/security/server_credentials.h \
+ include/grpcpp/server.h \
+ include/grpcpp/server_builder.h \
+ include/grpcpp/server_context.h \
+ include/grpcpp/server_posix.h \
+ include/grpcpp/support/async_stream.h \
+ include/grpcpp/support/async_unary_call.h \
+ include/grpcpp/support/byte_buffer.h \
+ include/grpcpp/support/channel_arguments.h \
+ include/grpcpp/support/config.h \
+ include/grpcpp/support/slice.h \
+ include/grpcpp/support/status.h \
+ include/grpcpp/support/status_code_enum.h \
+ include/grpcpp/support/string_ref.h \
+ include/grpcpp/support/stub_options.h \
+ include/grpcpp/support/sync_stream.h \
+ include/grpcpp/support/time.h \
include/grpc/support/alloc.h \
include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \
@@ -5182,7 +5332,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
- include/grpc/support/thd.h \
+ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -5247,6 +5397,36 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/stub_options.h \
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
+ include/grpcpp/impl/codegen/async_stream.h \
+ include/grpcpp/impl/codegen/async_unary_call.h \
+ include/grpcpp/impl/codegen/byte_buffer.h \
+ include/grpcpp/impl/codegen/call.h \
+ include/grpcpp/impl/codegen/call_hook.h \
+ include/grpcpp/impl/codegen/channel_interface.h \
+ include/grpcpp/impl/codegen/client_context.h \
+ include/grpcpp/impl/codegen/client_unary_call.h \
+ include/grpcpp/impl/codegen/completion_queue.h \
+ include/grpcpp/impl/codegen/completion_queue_tag.h \
+ include/grpcpp/impl/codegen/config.h \
+ include/grpcpp/impl/codegen/core_codegen_interface.h \
+ include/grpcpp/impl/codegen/create_auth_context.h \
+ include/grpcpp/impl/codegen/grpc_library.h \
+ include/grpcpp/impl/codegen/metadata_map.h \
+ include/grpcpp/impl/codegen/method_handler_impl.h \
+ include/grpcpp/impl/codegen/rpc_method.h \
+ include/grpcpp/impl/codegen/rpc_service_method.h \
+ include/grpcpp/impl/codegen/security/auth_context.h \
+ include/grpcpp/impl/codegen/serialization_traits.h \
+ include/grpcpp/impl/codegen/server_context.h \
+ include/grpcpp/impl/codegen/server_interface.h \
+ include/grpcpp/impl/codegen/service_type.h \
+ include/grpcpp/impl/codegen/slice.h \
+ include/grpcpp/impl/codegen/status.h \
+ include/grpcpp/impl/codegen/status_code_enum.h \
+ include/grpcpp/impl/codegen/string_ref.h \
+ include/grpcpp/impl/codegen/stub_options.h \
+ include/grpcpp/impl/codegen/sync_stream.h \
+ include/grpcpp/impl/codegen/time.h \
include/grpc/census.h \
LIBGRPC++_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CRONET_SRC))))
@@ -5318,6 +5498,7 @@ LIBGRPC++_ERROR_DETAILS_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpc++/support/error_details.h \
+ include/grpcpp/support/error_details.h \
LIBGRPC++_ERROR_DETAILS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_ERROR_DETAILS_SRC))))
@@ -5389,6 +5570,7 @@ LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/config_protobuf.h \
+ include/grpcpp/impl/codegen/config_protobuf.h \
LIBGRPC++_PROTO_REFLECTION_DESC_DB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_PROTO_REFLECTION_DESC_DB_SRC))))
@@ -5442,6 +5624,7 @@ LIBGRPC++_REFLECTION_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpc++/ext/proto_server_reflection_plugin.h \
+ include/grpcpp/ext/proto_server_reflection_plugin.h \
LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
@@ -5601,6 +5784,36 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/stub_options.h \
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
+ include/grpcpp/impl/codegen/async_stream.h \
+ include/grpcpp/impl/codegen/async_unary_call.h \
+ include/grpcpp/impl/codegen/byte_buffer.h \
+ include/grpcpp/impl/codegen/call.h \
+ include/grpcpp/impl/codegen/call_hook.h \
+ include/grpcpp/impl/codegen/channel_interface.h \
+ include/grpcpp/impl/codegen/client_context.h \
+ include/grpcpp/impl/codegen/client_unary_call.h \
+ include/grpcpp/impl/codegen/completion_queue.h \
+ include/grpcpp/impl/codegen/completion_queue_tag.h \
+ include/grpcpp/impl/codegen/config.h \
+ include/grpcpp/impl/codegen/core_codegen_interface.h \
+ include/grpcpp/impl/codegen/create_auth_context.h \
+ include/grpcpp/impl/codegen/grpc_library.h \
+ include/grpcpp/impl/codegen/metadata_map.h \
+ include/grpcpp/impl/codegen/method_handler_impl.h \
+ include/grpcpp/impl/codegen/rpc_method.h \
+ include/grpcpp/impl/codegen/rpc_service_method.h \
+ include/grpcpp/impl/codegen/security/auth_context.h \
+ include/grpcpp/impl/codegen/serialization_traits.h \
+ include/grpcpp/impl/codegen/server_context.h \
+ include/grpcpp/impl/codegen/server_interface.h \
+ include/grpcpp/impl/codegen/service_type.h \
+ include/grpcpp/impl/codegen/slice.h \
+ include/grpcpp/impl/codegen/status.h \
+ include/grpcpp/impl/codegen/status_code_enum.h \
+ include/grpcpp/impl/codegen/string_ref.h \
+ include/grpcpp/impl/codegen/stub_options.h \
+ include/grpcpp/impl/codegen/sync_stream.h \
+ include/grpcpp/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
@@ -5623,7 +5836,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc++/impl/codegen/proto_utils.h \
+ include/grpcpp/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
+ include/grpcpp/impl/codegen/config_protobuf.h \
LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
@@ -5718,6 +5933,36 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/stub_options.h \
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
+ include/grpcpp/impl/codegen/async_stream.h \
+ include/grpcpp/impl/codegen/async_unary_call.h \
+ include/grpcpp/impl/codegen/byte_buffer.h \
+ include/grpcpp/impl/codegen/call.h \
+ include/grpcpp/impl/codegen/call_hook.h \
+ include/grpcpp/impl/codegen/channel_interface.h \
+ include/grpcpp/impl/codegen/client_context.h \
+ include/grpcpp/impl/codegen/client_unary_call.h \
+ include/grpcpp/impl/codegen/completion_queue.h \
+ include/grpcpp/impl/codegen/completion_queue_tag.h \
+ include/grpcpp/impl/codegen/config.h \
+ include/grpcpp/impl/codegen/core_codegen_interface.h \
+ include/grpcpp/impl/codegen/create_auth_context.h \
+ include/grpcpp/impl/codegen/grpc_library.h \
+ include/grpcpp/impl/codegen/metadata_map.h \
+ include/grpcpp/impl/codegen/method_handler_impl.h \
+ include/grpcpp/impl/codegen/rpc_method.h \
+ include/grpcpp/impl/codegen/rpc_service_method.h \
+ include/grpcpp/impl/codegen/security/auth_context.h \
+ include/grpcpp/impl/codegen/serialization_traits.h \
+ include/grpcpp/impl/codegen/server_context.h \
+ include/grpcpp/impl/codegen/server_interface.h \
+ include/grpcpp/impl/codegen/service_type.h \
+ include/grpcpp/impl/codegen/slice.h \
+ include/grpcpp/impl/codegen/status.h \
+ include/grpcpp/impl/codegen/status_code_enum.h \
+ include/grpcpp/impl/codegen/string_ref.h \
+ include/grpcpp/impl/codegen/stub_options.h \
+ include/grpcpp/impl/codegen/sync_stream.h \
+ include/grpcpp/impl/codegen/time.h \
include/grpc/impl/codegen/byte_buffer.h \
include/grpc/impl/codegen/byte_buffer_reader.h \
include/grpc/impl/codegen/compression_types.h \
@@ -5740,7 +5985,9 @@ PUBLIC_HEADERS_CXX += \
include/grpc/impl/codegen/sync_posix.h \
include/grpc/impl/codegen/sync_windows.h \
include/grpc++/impl/codegen/proto_utils.h \
+ include/grpcpp/impl/codegen/proto_utils.h \
include/grpc++/impl/codegen/config_protobuf.h \
+ include/grpcpp/impl/codegen/config_protobuf.h \
LIBGRPC++_TEST_UTIL_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_UNSECURE_SRC))))
@@ -5877,6 +6124,51 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/stub_options.h \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
+ include/grpcpp/alarm.h \
+ include/grpcpp/channel.h \
+ include/grpcpp/client_context.h \
+ include/grpcpp/completion_queue.h \
+ include/grpcpp/create_channel.h \
+ include/grpcpp/create_channel_posix.h \
+ include/grpcpp/ext/health_check_service_server_builder_option.h \
+ include/grpcpp/generic/async_generic_service.h \
+ include/grpcpp/generic/generic_stub.h \
+ include/grpcpp/grpcpp.h \
+ include/grpcpp/health_check_service_interface.h \
+ include/grpcpp/impl/call.h \
+ include/grpcpp/impl/channel_argument_option.h \
+ include/grpcpp/impl/client_unary_call.h \
+ include/grpcpp/impl/codegen/core_codegen.h \
+ include/grpcpp/impl/grpc_library.h \
+ include/grpcpp/impl/method_handler_impl.h \
+ include/grpcpp/impl/rpc_method.h \
+ include/grpcpp/impl/rpc_service_method.h \
+ include/grpcpp/impl/serialization_traits.h \
+ include/grpcpp/impl/server_builder_option.h \
+ include/grpcpp/impl/server_builder_plugin.h \
+ include/grpcpp/impl/server_initializer.h \
+ include/grpcpp/impl/service_type.h \
+ include/grpcpp/resource_quota.h \
+ include/grpcpp/security/auth_context.h \
+ include/grpcpp/security/auth_metadata_processor.h \
+ include/grpcpp/security/credentials.h \
+ include/grpcpp/security/server_credentials.h \
+ include/grpcpp/server.h \
+ include/grpcpp/server_builder.h \
+ include/grpcpp/server_context.h \
+ include/grpcpp/server_posix.h \
+ include/grpcpp/support/async_stream.h \
+ include/grpcpp/support/async_unary_call.h \
+ include/grpcpp/support/byte_buffer.h \
+ include/grpcpp/support/channel_arguments.h \
+ include/grpcpp/support/config.h \
+ include/grpcpp/support/slice.h \
+ include/grpcpp/support/status.h \
+ include/grpcpp/support/status_code_enum.h \
+ include/grpcpp/support/string_ref.h \
+ include/grpcpp/support/stub_options.h \
+ include/grpcpp/support/sync_stream.h \
+ include/grpcpp/support/time.h \
include/grpc/support/alloc.h \
include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \
@@ -5892,7 +6184,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
- include/grpc/support/thd.h \
+ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/impl/codegen/atm.h \
include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -5957,6 +6249,36 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/stub_options.h \
include/grpc++/impl/codegen/sync_stream.h \
include/grpc++/impl/codegen/time.h \
+ include/grpcpp/impl/codegen/async_stream.h \
+ include/grpcpp/impl/codegen/async_unary_call.h \
+ include/grpcpp/impl/codegen/byte_buffer.h \
+ include/grpcpp/impl/codegen/call.h \
+ include/grpcpp/impl/codegen/call_hook.h \
+ include/grpcpp/impl/codegen/channel_interface.h \
+ include/grpcpp/impl/codegen/client_context.h \
+ include/grpcpp/impl/codegen/client_unary_call.h \
+ include/grpcpp/impl/codegen/completion_queue.h \
+ include/grpcpp/impl/codegen/completion_queue_tag.h \
+ include/grpcpp/impl/codegen/config.h \
+ include/grpcpp/impl/codegen/core_codegen_interface.h \
+ include/grpcpp/impl/codegen/create_auth_context.h \
+ include/grpcpp/impl/codegen/grpc_library.h \
+ include/grpcpp/impl/codegen/metadata_map.h \
+ include/grpcpp/impl/codegen/method_handler_impl.h \
+ include/grpcpp/impl/codegen/rpc_method.h \
+ include/grpcpp/impl/codegen/rpc_service_method.h \
+ include/grpcpp/impl/codegen/security/auth_context.h \
+ include/grpcpp/impl/codegen/serialization_traits.h \
+ include/grpcpp/impl/codegen/server_context.h \
+ include/grpcpp/impl/codegen/server_interface.h \
+ include/grpcpp/impl/codegen/service_type.h \
+ include/grpcpp/impl/codegen/slice.h \
+ include/grpcpp/impl/codegen/status.h \
+ include/grpcpp/impl/codegen/status_code_enum.h \
+ include/grpcpp/impl/codegen/string_ref.h \
+ include/grpcpp/impl/codegen/stub_options.h \
+ include/grpcpp/impl/codegen/sync_stream.h \
+ include/grpcpp/impl/codegen/time.h \
LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
@@ -6067,6 +6389,7 @@ LIBGRPC_CLI_LIBS_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/config_protobuf.h \
+ include/grpcpp/impl/codegen/config_protobuf.h \
LIBGRPC_CLI_LIBS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CLI_LIBS_SRC))))
@@ -6128,6 +6451,7 @@ LIBGRPC_PLUGIN_SUPPORT_SRC = \
PUBLIC_HEADERS_CXX += \
include/grpc++/impl/codegen/config_protobuf.h \
+ include/grpcpp/impl/codegen/config_protobuf.h \
LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
@@ -9125,6 +9449,21 @@ LIBEND2END_TESTS_SRC = \
test/core/end2end/tests/request_with_flags.cc \
test/core/end2end/tests/request_with_payload.cc \
test/core/end2end/tests/resource_quota_server.cc \
+ test/core/end2end/tests/retry.cc \
+ test/core/end2end/tests/retry_cancellation.cc \
+ test/core/end2end/tests/retry_disabled.cc \
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc \
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc \
+ test/core/end2end/tests/retry_non_retriable_status.cc \
+ test/core/end2end/tests/retry_recv_initial_metadata.cc \
+ test/core/end2end/tests/retry_recv_message.cc \
+ test/core/end2end/tests/retry_server_pushback_delay.cc \
+ test/core/end2end/tests/retry_server_pushback_disabled.cc \
+ test/core/end2end/tests/retry_streaming.cc \
+ test/core/end2end/tests/retry_streaming_after_commit.cc \
+ test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc \
+ test/core/end2end/tests/retry_throttled.cc \
+ test/core/end2end/tests/retry_too_many_attempts.cc \
test/core/end2end/tests/server_finishes_request.cc \
test/core/end2end/tests/shutdown_finishes_calls.cc \
test/core/end2end/tests/shutdown_finishes_tags.cc \
@@ -9224,6 +9563,21 @@ LIBEND2END_NOSEC_TESTS_SRC = \
test/core/end2end/tests/request_with_flags.cc \
test/core/end2end/tests/request_with_payload.cc \
test/core/end2end/tests/resource_quota_server.cc \
+ test/core/end2end/tests/retry.cc \
+ test/core/end2end/tests/retry_cancellation.cc \
+ test/core/end2end/tests/retry_disabled.cc \
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc \
+ test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc \
+ test/core/end2end/tests/retry_non_retriable_status.cc \
+ test/core/end2end/tests/retry_recv_initial_metadata.cc \
+ test/core/end2end/tests/retry_recv_message.cc \
+ test/core/end2end/tests/retry_server_pushback_delay.cc \
+ test/core/end2end/tests/retry_server_pushback_disabled.cc \
+ test/core/end2end/tests/retry_streaming.cc \
+ test/core/end2end/tests/retry_streaming_after_commit.cc \
+ test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc \
+ test/core/end2end/tests/retry_throttled.cc \
+ test/core/end2end/tests/retry_too_many_attempts.cc \
test/core/end2end/tests/server_finishes_request.cc \
test/core/end2end/tests/shutdown_finishes_calls.cc \
test/core/end2end/tests/shutdown_finishes_tags.cc \
@@ -13060,38 +13414,6 @@ endif
endif
-SLICE_HASH_TABLE_TEST_SRC = \
- test/core/slice/slice_hash_table_test.cc \
-
-SLICE_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_HASH_TABLE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/slice_hash_table_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
- $(E) "[LD] Linking $@"
- $(Q) mkdir -p `dirname $@`
- $(Q) $(LD) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
SLICE_STRING_HELPERS_TEST_SRC = \
test/core/slice/slice_string_helpers_test.cc \
@@ -16113,53 +16435,6 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/end2end/grpclb_end2end_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
-GRPCLB_TEST_SRC = \
- $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
- test/cpp/grpclb/grpclb_test.cc \
-
-GRPCLB_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/grpclb_test: openssl_dep_error
-
-else
-
-
-
-
-ifeq ($(NO_PROTOBUF),true)
-
-# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
-
-$(BINDIR)/$(CONFIG)/grpclb_test: protobuf_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/grpclb_test: $(PROTOBUF_DEP) $(GRPCLB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
- $(E) "[LD] Linking $@"
- $(Q) mkdir -p `dirname $@`
- $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_test
-
-endif
-
-endif
-
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_grpclb_test: $(GRPCLB_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(GRPCLB_TEST_OBJS:.o=.dep)
-endif
-endif
-$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
-
-
H2_SSL_CERT_TEST_SRC = \
test/core/end2end/h2_ssl_cert_test.cc \
@@ -17711,6 +17986,92 @@ endif
endif
+SLICE_HASH_TABLE_TEST_SRC = \
+ test/core/slice/slice_hash_table_test.cc \
+
+SLICE_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_HASH_TABLE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/slice_hash_table_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/slice_hash_table_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/slice_hash_table_test: $(PROTOBUF_DEP) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(SLICE_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_hash_table_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/slice/slice_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_slice_hash_table_test: $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SLICE_HASH_TABLE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+SLICE_WEAK_HASH_TABLE_TEST_SRC = \
+ test/core/slice/slice_weak_hash_table_test.cc \
+
+SLICE_WEAK_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SLICE_WEAK_HASH_TABLE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/slice_weak_hash_table_test: $(PROTOBUF_DEP) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(SLICE_WEAK_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/slice_weak_hash_table_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/slice/slice_weak_hash_table_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_slice_weak_hash_table_test: $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(SLICE_WEAK_HASH_TABLE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
STATS_TEST_SRC = \
test/core/debug/stats_test.cc \
@@ -17754,6 +18115,49 @@ endif
endif
+STATUS_METADATA_TEST_SRC = \
+ test/core/transport/status_metadata_test.cc \
+
+STATUS_METADATA_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STATUS_METADATA_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/status_metadata_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/status_metadata_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/status_metadata_test: $(PROTOBUF_DEP) $(STATUS_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(STATUS_METADATA_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/status_metadata_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/status_metadata_test.o: $(LIBDIR)/$(CONFIG)/libgrpc.a
+
+deps_status_metadata_test: $(STATUS_METADATA_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(STATUS_METADATA_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
STATUS_TEST_SRC = \
test/cpp/util/status_test.cc \
@@ -17797,6 +18201,49 @@ endif
endif
+STATUS_UTIL_TEST_SRC = \
+ test/core/client_channel/status_util_test.cc \
+
+STATUS_UTIL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STATUS_UTIL_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/status_util_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/status_util_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/status_util_test: $(PROTOBUF_DEP) $(STATUS_UTIL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(STATUS_UTIL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/status_util_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/client_channel/status_util_test.o: $(LIBDIR)/$(CONFIG)/libgrpc.a
+
+deps_status_util_test: $(STATUS_UTIL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(STATUS_UTIL_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
STREAMING_THROUGHPUT_TEST_SRC = \
test/cpp/end2end/streaming_throughput_test.cc \
@@ -22020,12 +22467,12 @@ src/core/lib/security/credentials/jwt/jwt_verifier.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP)
src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP)
+src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP)
-src/core/lib/security/transport/lb_targets_info.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP)
-src/core/lib/security/transport/security_connector.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/security_handshaker.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/server_auth_filter.cc: $(OPENSSL_DEP)
+src/core/lib/security/transport/target_authority_table.cc: $(OPENSSL_DEP)
src/core/lib/security/transport/tsi_error.cc: $(OPENSSL_DEP)
src/core/lib/security/util/json_util.cc: $(OPENSSL_DEP)
src/core/lib/surface/init_secure.cc: $(OPENSSL_DEP)
diff --git a/README.md b/README.md
index fc72c7c1ba..e045e331f2 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,3 @@
-[![Build Status](https://grpc-testing.appspot.com/job/gRPC_master/badge/icon)](https://grpc-testing.appspot.com/job/gRPC_master)
-
[gRPC - An RPC library and framework](http://github.com/grpc/grpc)
===================================
diff --git a/WORKSPACE b/WORKSPACE
index adce809162..8b68c0d2b1 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,4 +1,5 @@
workspace(name = "com_github_grpc_grpc")
-load("//bazel:grpc_deps.bzl", "grpc_deps")
+load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps")
grpc_deps()
+grpc_test_only_deps()
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index 3fbefc41e7..3813f57c10 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -26,6 +26,13 @@
# The set of pollers to test against if a test exercises polling
POLLERS = ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv']
+def if_not_windows(a):
+ return select({
+ "//:windows": [],
+ "//:windows_msvc": [],
+ "//conditions:default": a,
+ })
+
def _get_external_deps(external_deps):
ret = []
for dep in external_deps:
@@ -56,7 +63,7 @@ def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [],
alwayslink = 0):
copts = []
if language.upper() == "C":
- copts = ["-std=c99"]
+ copts = if_not_windows(["-std=c99"])
native.cc_library(
name = name,
srcs = srcs,
@@ -73,7 +80,7 @@ def grpc_cc_library(name, srcs = [], public_hdrs = [], hdrs = [],
copts = copts,
visibility = visibility,
testonly = testonly,
- linkopts = ["-pthread"],
+ linkopts = if_not_windows(["-pthread"]),
includes = [
"include"
],
@@ -104,7 +111,7 @@ def grpc_proto_library(name, srcs = [], deps = [], well_known_protos = False,
def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++"):
copts = []
if language.upper() == "C":
- copts = ["-std=c99"]
+ copts = if_not_windows(["-std=c99"])
args = {
'name': name,
'srcs': srcs,
@@ -112,7 +119,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
'data': data,
'deps': deps + _get_external_deps(external_deps),
'copts': copts,
- 'linkopts': ["-pthread"],
+ 'linkopts': if_not_windows(["-pthread"]),
}
if uses_polling:
native.cc_test(testonly=True, tags=['manual'], **args)
@@ -144,7 +151,7 @@ def grpc_cc_binary(name, srcs = [], deps = [], external_deps = [], args = [], da
linkshared = linkshared,
deps = deps + _get_external_deps(external_deps),
copts = copts,
- linkopts = ["-pthread"] + linkopts,
+ linkopts = if_not_windows(["-pthread"]) + linkopts,
)
def grpc_generate_one_off_targets():
@@ -165,8 +172,10 @@ def grpc_sh_binary(name, srcs, data = []):
def grpc_py_binary(name, srcs, data = [], deps = []):
if name == "test_dns_server":
- # TODO: allow running test_dns_server in oss bazel test suite
- deps = []
+ deps = _get_external_deps([
+ "twisted",
+ "yaml",
+ ])
native.py_binary(
name = name,
srcs = srcs,
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index 47d33085a2..a441c3ff3d 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -120,10 +120,64 @@ def grpc_deps():
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
native.http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
- strip_prefix = "bazel-toolchains-f3b09700fae5d7b6e659d7cefe0dcc6e8498504c",
+ strip_prefix = "bazel-toolchains-b850ccdf53fed1ccab7670f52d6b297d74348d1b",
urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/f3b09700fae5d7b6e659d7cefe0dcc6e8498504c.tar.gz",
- "https://github.com/bazelbuild/bazel-toolchains/archive/f3b09700fae5d7b6e659d7cefe0dcc6e8498504c.tar.gz",
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/b850ccdf53fed1ccab7670f52d6b297d74348d1b.tar.gz",
+ "https://github.com/bazelbuild/bazel-toolchains/archive/b850ccdf53fed1ccab7670f52d6b297d74348d1b.tar.gz",
],
- sha256 = "ed829b5eea8af1f405f4cc3d6ecfc3b1365bb7843171036030a31b5127002311",
+ sha256 = "d84d6b2fe88ef99963febf91ddce33503eed14c155ace922e2122271b483be64",
+ )
+
+# TODO: move some dependencies from "grpc_deps" here?
+def grpc_test_only_deps():
+ """Internal, not intended for use by packages that are consuming grpc.
+ Loads dependencies that are only needed to run grpc library's tests."""
+ native.bind(
+ name = "twisted",
+ actual = "@com_github_twisted_twisted//:twisted",
+ )
+
+ native.bind(
+ name = "yaml",
+ actual = "@com_github_yaml_pyyaml//:yaml",
+ )
+
+ if "com_github_twisted_twisted" not in native.existing_rules():
+ native.new_http_archive(
+ name = "com_github_twisted_twisted",
+ strip_prefix = "twisted-twisted-17.5.0",
+ url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip",
+ build_file = "@com_github_grpc_grpc//third_party:twisted.BUILD",
+ )
+
+ if "com_github_yaml_pyyaml" not in native.existing_rules():
+ native.new_http_archive(
+ name = "com_github_yaml_pyyaml",
+ strip_prefix = "pyyaml-3.12",
+ url = "https://github.com/yaml/pyyaml/archive/3.12.zip",
+ build_file = "@com_github_grpc_grpc//third_party:yaml.BUILD",
+ )
+
+ if "com_github_twisted_incremental" not in native.existing_rules():
+ native.new_http_archive(
+ name = "com_github_twisted_incremental",
+ strip_prefix = "incremental-incremental-17.5.0",
+ url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip",
+ build_file = "@com_github_grpc_grpc//third_party:incremental.BUILD",
+ )
+
+ if "com_github_zopefoundation_zope_interface" not in native.existing_rules():
+ native.new_http_archive(
+ name = "com_github_zopefoundation_zope_interface",
+ strip_prefix = "zope.interface-4.4.3",
+ url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip",
+ build_file = "@com_github_grpc_grpc//third_party:zope_interface.BUILD",
+ )
+
+ if "com_github_twisted_constantly" not in native.existing_rules():
+ native.new_http_archive(
+ name = "com_github_twisted_constantly",
+ strip_prefix = "constantly-15.1.0",
+ url = "https://github.com/twisted/constantly/archive/15.1.0.zip",
+ build_file = "@com_github_grpc_grpc//third_party:constantly.BUILD",
)
diff --git a/build.yaml b/build.yaml
index eb61e57f90..4ce1fd1c94 100644
--- a/build.yaml
+++ b/build.yaml
@@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 6.0.0-dev
- g_stands_for: glamorous
- version: 1.10.0-dev
+ g_stands_for: gorgeous
+ version: 1.11.0-dev
filegroups:
- name: census
public_headers:
@@ -92,7 +92,7 @@ filegroups:
- include/grpc/support/sync_generic.h
- include/grpc/support/sync_posix.h
- include/grpc/support/sync_windows.h
- - include/grpc/support/thd.h
+ - include/grpc/support/thd_id.h
- include/grpc/support/time.h
headers:
- src/core/lib/gpr/arena.h
@@ -104,7 +104,7 @@ filegroups:
- src/core/lib/gpr/spinlock.h
- src/core/lib/gpr/string.h
- src/core/lib/gpr/string_windows.h
- - src/core/lib/gpr/thd_internal.h
+ - src/core/lib/gpr/thd.h
- src/core/lib/gpr/time_precise.h
- src/core/lib/gpr/tls.h
- src/core/lib/gpr/tls_gcc.h
@@ -252,7 +252,6 @@ filegroups:
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_buffer.cc
- - src/core/lib/slice/slice_hash_table.cc
- src/core/lib/slice/slice_intern.cc
- src/core/lib/slice/slice_string_helpers.cc
- src/core/lib/surface/api_trace.cc
@@ -283,6 +282,7 @@ filegroups:
- src/core/lib/transport/service_config.cc
- src/core/lib/transport/static_metadata.cc
- src/core/lib/transport/status_conversion.cc
+ - src/core/lib/transport/status_metadata.cc
- src/core/lib/transport/timeout_encoding.cc
- src/core/lib/transport/transport.cc
- src/core/lib/transport/transport_op_string.cc
@@ -408,6 +408,7 @@ filegroups:
- src/core/lib/slice/slice_hash_table.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_string_helpers.h
+ - src/core/lib/slice/slice_weak_hash_table.h
- src/core/lib/surface/api_trace.h
- src/core/lib/surface/call.h
- src/core/lib/surface/call_test_only.h
@@ -432,6 +433,7 @@ filegroups:
- src/core/lib/transport/service_config.h
- src/core/lib/transport/static_metadata.h
- src/core/lib/transport/status_conversion.h
+ - src/core/lib/transport/status_metadata.h
- src/core/lib/transport/timeout_encoding.h
- src/core/lib/transport/transport.h
- src/core/lib/transport/transport_impl.h
@@ -451,6 +453,7 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.h
- src/core/ext/filters/client_channel/lb_policy_factory.h
- src/core/ext/filters/client_channel/lb_policy_registry.h
+ - src/core/ext/filters/client_channel/method_params.h
- src/core/ext/filters/client_channel/parse_address.h
- src/core/ext/filters/client_channel/proxy_mapper.h
- src/core/ext/filters/client_channel/proxy_mapper_registry.h
@@ -458,6 +461,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver_factory.h
- src/core/ext/filters/client_channel/resolver_registry.h
- src/core/ext/filters/client_channel/retry_throttle.h
+ - src/core/ext/filters/client_channel/status_util.h
- src/core/ext/filters/client_channel/subchannel.h
- src/core/ext/filters/client_channel/subchannel_index.h
- src/core/ext/filters/client_channel/uri_parser.h
@@ -473,12 +477,14 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
+ - src/core/ext/filters/client_channel/method_params.cc
- src/core/ext/filters/client_channel/parse_address.cc
- src/core/ext/filters/client_channel/proxy_mapper.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver_registry.cc
- src/core/ext/filters/client_channel/retry_throttle.cc
+ - src/core/ext/filters/client_channel/status_util.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_index.cc
- src/core/ext/filters/client_channel/uri_parser.cc
@@ -522,7 +528,6 @@ filegroups:
- name: grpc_lb_policy_grpclb
headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
- - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -543,7 +548,6 @@ filegroups:
- name: grpc_lb_policy_grpclb_secure
headers:
- src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
- - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
- src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -654,11 +658,11 @@ filegroups:
- src/core/lib/security/credentials/oauth2/oauth2_credentials.h
- src/core/lib/security/credentials/plugin/plugin_credentials.h
- src/core/lib/security/credentials/ssl/ssl_credentials.h
+ - src/core/lib/security/security_connector/security_connector.h
- src/core/lib/security/transport/auth_filters.h
- - src/core/lib/security/transport/lb_targets_info.h
- src/core/lib/security/transport/secure_endpoint.h
- - src/core/lib/security/transport/security_connector.h
- src/core/lib/security/transport/security_handshaker.h
+ - src/core/lib/security/transport/target_authority_table.h
- src/core/lib/security/transport/tsi_error.h
- src/core/lib/security/util/json_util.h
src:
@@ -677,12 +681,12 @@ filegroups:
- src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
- src/core/lib/security/credentials/plugin/plugin_credentials.cc
- src/core/lib/security/credentials/ssl/ssl_credentials.cc
+ - src/core/lib/security/security_connector/security_connector.cc
- src/core/lib/security/transport/client_auth_filter.cc
- - src/core/lib/security/transport/lb_targets_info.cc
- src/core/lib/security/transport/secure_endpoint.cc
- - src/core/lib/security/transport/security_connector.cc
- src/core/lib/security/transport/security_handshaker.cc
- src/core/lib/security/transport/server_auth_filter.cc
+ - src/core/lib/security/transport/target_authority_table.cc
- src/core/lib/security/transport/tsi_error.cc
- src/core/lib/security/util/json_util.cc
- src/core/lib/surface/init_secure.cc
@@ -1006,6 +1010,36 @@ filegroups:
- include/grpc++/impl/codegen/stub_options.h
- include/grpc++/impl/codegen/sync_stream.h
- include/grpc++/impl/codegen/time.h
+ - include/grpcpp/impl/codegen/async_stream.h
+ - include/grpcpp/impl/codegen/async_unary_call.h
+ - include/grpcpp/impl/codegen/byte_buffer.h
+ - include/grpcpp/impl/codegen/call.h
+ - include/grpcpp/impl/codegen/call_hook.h
+ - include/grpcpp/impl/codegen/channel_interface.h
+ - include/grpcpp/impl/codegen/client_context.h
+ - include/grpcpp/impl/codegen/client_unary_call.h
+ - include/grpcpp/impl/codegen/completion_queue.h
+ - include/grpcpp/impl/codegen/completion_queue_tag.h
+ - include/grpcpp/impl/codegen/config.h
+ - include/grpcpp/impl/codegen/core_codegen_interface.h
+ - include/grpcpp/impl/codegen/create_auth_context.h
+ - include/grpcpp/impl/codegen/grpc_library.h
+ - include/grpcpp/impl/codegen/metadata_map.h
+ - include/grpcpp/impl/codegen/method_handler_impl.h
+ - include/grpcpp/impl/codegen/rpc_method.h
+ - include/grpcpp/impl/codegen/rpc_service_method.h
+ - include/grpcpp/impl/codegen/security/auth_context.h
+ - include/grpcpp/impl/codegen/serialization_traits.h
+ - include/grpcpp/impl/codegen/server_context.h
+ - include/grpcpp/impl/codegen/server_interface.h
+ - include/grpcpp/impl/codegen/service_type.h
+ - include/grpcpp/impl/codegen/slice.h
+ - include/grpcpp/impl/codegen/status.h
+ - include/grpcpp/impl/codegen/status_code_enum.h
+ - include/grpcpp/impl/codegen/string_ref.h
+ - include/grpcpp/impl/codegen/stub_options.h
+ - include/grpcpp/impl/codegen/sync_stream.h
+ - include/grpcpp/impl/codegen/time.h
uses:
- grpc_codegen
- name: grpc++_codegen_base_src
@@ -1018,6 +1052,7 @@ filegroups:
language: c++
public_headers:
- include/grpc++/impl/codegen/proto_utils.h
+ - include/grpcpp/impl/codegen/proto_utils.h
uses:
- grpc++_codegen_base
- grpc++_config_proto
@@ -1069,6 +1104,51 @@ filegroups:
- include/grpc++/support/stub_options.h
- include/grpc++/support/sync_stream.h
- include/grpc++/support/time.h
+ - include/grpcpp/alarm.h
+ - include/grpcpp/channel.h
+ - include/grpcpp/client_context.h
+ - include/grpcpp/completion_queue.h
+ - include/grpcpp/create_channel.h
+ - include/grpcpp/create_channel_posix.h
+ - include/grpcpp/ext/health_check_service_server_builder_option.h
+ - include/grpcpp/generic/async_generic_service.h
+ - include/grpcpp/generic/generic_stub.h
+ - include/grpcpp/grpcpp.h
+ - include/grpcpp/health_check_service_interface.h
+ - include/grpcpp/impl/call.h
+ - include/grpcpp/impl/channel_argument_option.h
+ - include/grpcpp/impl/client_unary_call.h
+ - include/grpcpp/impl/codegen/core_codegen.h
+ - include/grpcpp/impl/grpc_library.h
+ - include/grpcpp/impl/method_handler_impl.h
+ - include/grpcpp/impl/rpc_method.h
+ - include/grpcpp/impl/rpc_service_method.h
+ - include/grpcpp/impl/serialization_traits.h
+ - include/grpcpp/impl/server_builder_option.h
+ - include/grpcpp/impl/server_builder_plugin.h
+ - include/grpcpp/impl/server_initializer.h
+ - include/grpcpp/impl/service_type.h
+ - include/grpcpp/resource_quota.h
+ - include/grpcpp/security/auth_context.h
+ - include/grpcpp/security/auth_metadata_processor.h
+ - include/grpcpp/security/credentials.h
+ - include/grpcpp/security/server_credentials.h
+ - include/grpcpp/server.h
+ - include/grpcpp/server_builder.h
+ - include/grpcpp/server_context.h
+ - include/grpcpp/server_posix.h
+ - include/grpcpp/support/async_stream.h
+ - include/grpcpp/support/async_unary_call.h
+ - include/grpcpp/support/byte_buffer.h
+ - include/grpcpp/support/channel_arguments.h
+ - include/grpcpp/support/config.h
+ - include/grpcpp/support/slice.h
+ - include/grpcpp/support/status.h
+ - include/grpcpp/support/status_code_enum.h
+ - include/grpcpp/support/string_ref.h
+ - include/grpcpp/support/stub_options.h
+ - include/grpcpp/support/sync_stream.h
+ - include/grpcpp/support/time.h
headers:
- src/cpp/client/create_channel_internal.h
- src/cpp/common/channel_filter.h
@@ -1122,6 +1202,7 @@ filegroups:
language: c++
public_headers:
- include/grpc++/impl/codegen/config_protobuf.h
+ - include/grpcpp/impl/codegen/config_protobuf.h
- name: grpc++_reflection_proto
language: c++
src:
@@ -1131,6 +1212,8 @@ filegroups:
public_headers:
- include/grpc++/test/mock_stream.h
- include/grpc++/test/server_context_test_spouse.h
+ - include/grpcpp/test/mock_stream.h
+ - include/grpcpp/test/server_context_test_spouse.h
deps:
- grpc++
- grpc
@@ -1318,6 +1401,7 @@ libs:
language: c++
headers:
- include/grpc++/impl/codegen/core_codegen.h
+ - include/grpcpp/impl/codegen/core_codegen.h
- src/cpp/client/secure_credentials.h
- src/cpp/common/secure_auth_context.h
- src/cpp/server/secure_server_credentials.h
@@ -1379,6 +1463,7 @@ libs:
language: c++
public_headers:
- include/grpc++/support/error_details.h
+ - include/grpcpp/support/error_details.h
src:
- src/proto/grpc/status/status.proto
- src/cpp/util/error_details.cc
@@ -1404,6 +1489,7 @@ libs:
language: c++
public_headers:
- include/grpc++/ext/proto_server_reflection_plugin.h
+ - include/grpcpp/ext/proto_server_reflection_plugin.h
headers:
- src/cpp/ext/proto_server_reflection.h
src:
@@ -3084,17 +3170,6 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
-- name: slice_hash_table_test
- build: test
- language: c
- src:
- - test/core/slice/slice_hash_table_test.cc
- deps:
- - grpc_test_util
- - grpc
- - gpr_test_util
- - gpr
- uses_polling: false
- name: slice_string_helpers_test
build: test
language: c
@@ -4207,20 +4282,6 @@ targets:
- grpc
- gpr_test_util
- gpr
-- name: grpclb_test
- gtest: false
- build: test
- language: c++
- src:
- - src/proto/grpc/lb/v1/load_balancer.proto
- - test/cpp/grpclb/grpclb_test.cc
- deps:
- - grpc++_test_util
- - grpc_test_util
- - grpc++
- - grpc
- - gpr_test_util
- - gpr
- name: h2_ssl_cert_test
gtest: true
build: test
@@ -4420,6 +4481,7 @@ targets:
language: c++
headers:
- include/grpc++/test/mock_stream.h
+ - include/grpcpp/test/mock_stream.h
src:
- test/cpp/end2end/mock_test.cc
deps:
@@ -4777,6 +4839,30 @@ targets:
- grpc
- gpr_test_util
- gpr
+- name: slice_hash_table_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/slice/slice_hash_table_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ uses_polling: false
+- name: slice_weak_hash_table_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/slice/slice_weak_hash_table_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ uses_polling: false
- name: stats_test
gtest: true
build: test
@@ -4793,6 +4879,15 @@ targets:
- tsan
timeout_seconds: 1200
uses_polling: false
+- name: status_metadata_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/transport/status_metadata_test.cc
+ deps:
+ - grpc
+ uses_polling: false
- name: status_test
build: test
language: c++
@@ -4805,6 +4900,16 @@ targets:
- gpr_test_util
- gpr
uses_polling: false
+- name: status_util_test
+ gtest: true
+ cpu_cost: 0.1
+ build: test
+ language: c++
+ src:
+ - test/core/client_channel/status_util_test.cc
+ deps:
+ - grpc
+ uses_polling: false
- name: streaming_throughput_test
gtest: true
build: test
diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake
index 753dc0696f..2b4c20f2db 100644
--- a/cmake/benchmark.cmake
+++ b/cmake/benchmark.cmake
@@ -26,11 +26,12 @@ if("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "module")
message(WARNING "gRPC_BENCHMARK_PROVIDER is \"module\" but BENCHMARK_ROOT_DIR is wrong")
endif()
elseif("${gRPC_BENCHMARK_PROVIDER}" STREQUAL "package")
- find_package(benchmark REQUIRED)
+ # Use "CONFIG" as there is no built-in cmake module for benchmark.
+ find_package(benchmark REQUIRED CONFIG)
if(TARGET benchmark::benchmark)
set(_gRPC_BENCHMARK_LIBRARIES benchmark::benchmark)
# extract the include dir from target's properties
get_target_property(_gRPC_BENCHMARK_INCLUDE_DIR benchmark::benchmark INTERFACE_INCLUDE_DIRECTORIES)
endif()
- set(_gRPC_FIND_BENCHMARK "if(NOT benchmark_FOUND)\n find_package(benchmark)\nendif()")
+ set(_gRPC_FIND_BENCHMARK "if(NOT benchmark_FOUND)\n find_package(benchmark CONFIG)\nendif()")
endif()
diff --git a/cmake/cares.cmake b/cmake/cares.cmake
index 53d7582f6f..3d4a0cae76 100644
--- a/cmake/cares.cmake
+++ b/cmake/cares.cmake
@@ -30,6 +30,7 @@ if("${gRPC_CARES_PROVIDER}" STREQUAL "module")
set(gRPC_INSTALL FALSE)
endif()
elseif("${gRPC_CARES_PROVIDER}" STREQUAL "package")
+ # Use "CONFIG" as there is no built-in cmake module for c-ares.
find_package(c-ares REQUIRED CONFIG)
if(TARGET c-ares::cares)
set(_gRPC_CARES_LIBRARIES c-ares::cares)
diff --git a/cmake/gflags.cmake b/cmake/gflags.cmake
index f86a141c1d..01e0a75b60 100644
--- a/cmake/gflags.cmake
+++ b/cmake/gflags.cmake
@@ -26,10 +26,11 @@ if("${gRPC_GFLAGS_PROVIDER}" STREQUAL "module")
message(WARNING "gRPC_GFLAGS_PROVIDER is \"module\" but GFLAGS_ROOT_DIR is wrong")
endif()
elseif("${gRPC_GFLAGS_PROVIDER}" STREQUAL "package")
- find_package(gflags REQUIRED)
+ # Use "CONFIG" as there is no built-in cmake module for gflags.
+ find_package(gflags REQUIRED CONFIG)
if(TARGET gflags::gflags)
set(_gRPC_GFLAGS_LIBRARIES gflags::gflags)
set(_gRPC_GFLAGS_INCLUDE_DIR ${GFLAGS_INCLUDE_DIR})
endif()
- set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n find_package(gflags)\nendif()")
+ set(_gRPC_FIND_GFLAGS "if(NOT gflags_FOUND)\n find_package(gflags CONFIG)\nendif()")
endif()
diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
index 53d8a1597e..83f642a675 100644
--- a/cmake/ssl.cmake
+++ b/cmake/ssl.cmake
@@ -31,6 +31,10 @@ if("${gRPC_SSL_PROVIDER}" STREQUAL "module")
set(gRPC_INSTALL FALSE)
endif()
elseif("${gRPC_SSL_PROVIDER}" STREQUAL "package")
+ # OpenSSL installation directory can be configured by setting OPENSSL_ROOT_DIR
+ # We expect to locate OpenSSL using the built-in cmake module as the openssl
+ # project itself does not provide installation support in its CMakeLists.txt
+ # See https://cmake.org/cmake/help/v3.6/module/FindOpenSSL.html
find_package(OpenSSL REQUIRED)
if(TARGET OpenSSL::SSL)
diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake
index e4c94f5213..ed7c9c216a 100644
--- a/cmake/zlib.cmake
+++ b/cmake/zlib.cmake
@@ -33,6 +33,12 @@ if("${gRPC_ZLIB_PROVIDER}" STREQUAL "module")
set(gRPC_INSTALL FALSE)
endif()
elseif("${gRPC_ZLIB_PROVIDER}" STREQUAL "package")
+ # zlib installation directory can be configured by setting ZLIB_ROOT
+ # We allow locating zlib using both "CONFIG" and "MODULE" as the expectation
+ # is that many Linux systems will have zlib installed via a distribution
+ # package ("MODULE"), while on Windows the user is likely to have installed
+ # zlib using cmake ("CONFIG").
+ # See https://cmake.org/cmake/help/v3.6/module/FindZLIB.html
find_package(ZLIB REQUIRED)
if(TARGET ZLIB::ZLIB)
diff --git a/config.m4 b/config.m4
index 33dbc4108b..9c28a80444 100644
--- a/config.m4
+++ b/config.m4
@@ -182,7 +182,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
- src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/surface/api_trace.cc \
@@ -213,6 +212,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/transport/service_config.cc \
src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/status_conversion.cc \
+ src/core/lib/transport/status_metadata.cc \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/transport.cc \
src/core/lib/transport/transport_op_string.cc \
@@ -260,12 +260,12 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \
src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
+ src/core/lib/security/security_connector/security_connector.cc \
src/core/lib/security/transport/client_auth_filter.cc \
- src/core/lib/security/transport/lb_targets_info.cc \
src/core/lib/security/transport/secure_endpoint.cc \
- src/core/lib/security/transport/security_connector.cc \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/server_auth_filter.cc \
+ src/core/lib/security/transport/target_authority_table.cc \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/util/json_util.cc \
src/core/lib/surface/init_secure.cc \
@@ -288,12 +288,14 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
+ src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/status_util.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/client_channel/uri_parser.cc \
@@ -643,6 +645,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/oauth2)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl)
+ PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/slice)
diff --git a/config.w32 b/config.w32
index af7c828241..e831151634 100644
--- a/config.w32
+++ b/config.w32
@@ -159,7 +159,6 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\slice\\percent_encoding.cc " +
"src\\core\\lib\\slice\\slice.cc " +
"src\\core\\lib\\slice\\slice_buffer.cc " +
- "src\\core\\lib\\slice\\slice_hash_table.cc " +
"src\\core\\lib\\slice\\slice_intern.cc " +
"src\\core\\lib\\slice\\slice_string_helpers.cc " +
"src\\core\\lib\\surface\\api_trace.cc " +
@@ -190,6 +189,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\transport\\service_config.cc " +
"src\\core\\lib\\transport\\static_metadata.cc " +
"src\\core\\lib\\transport\\status_conversion.cc " +
+ "src\\core\\lib\\transport\\status_metadata.cc " +
"src\\core\\lib\\transport\\timeout_encoding.cc " +
"src\\core\\lib\\transport\\transport.cc " +
"src\\core\\lib\\transport\\transport_op_string.cc " +
@@ -237,12 +237,12 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " +
"src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " +
"src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " +
+ "src\\core\\lib\\security\\security_connector\\security_connector.cc " +
"src\\core\\lib\\security\\transport\\client_auth_filter.cc " +
- "src\\core\\lib\\security\\transport\\lb_targets_info.cc " +
"src\\core\\lib\\security\\transport\\secure_endpoint.cc " +
- "src\\core\\lib\\security\\transport\\security_connector.cc " +
"src\\core\\lib\\security\\transport\\security_handshaker.cc " +
"src\\core\\lib\\security\\transport\\server_auth_filter.cc " +
+ "src\\core\\lib\\security\\transport\\target_authority_table.cc " +
"src\\core\\lib\\security\\transport\\tsi_error.cc " +
"src\\core\\lib\\security\\util\\json_util.cc " +
"src\\core\\lib\\surface\\init_secure.cc " +
@@ -265,12 +265,14 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\lb_policy.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
+ "src\\core\\ext\\filters\\client_channel\\method_params.cc " +
"src\\core\\ext\\filters\\client_channel\\parse_address.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
+ "src\\core\\ext\\filters\\client_channel\\status_util.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " +
"src\\core\\ext\\filters\\client_channel\\uri_parser.cc " +
@@ -656,6 +658,7 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\oauth2");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl");
+ FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice");
diff --git a/doc/cpp/pending_api_cleanups.md b/doc/cpp/pending_api_cleanups.md
index 517d503cb0..fa19b52002 100644
--- a/doc/cpp/pending_api_cleanups.md
+++ b/doc/cpp/pending_api_cleanups.md
@@ -15,3 +15,5 @@ number:
`include/grpc++/server_builder.h` (commit `6980362`)
- remove `ClientContext::set_fail_fast()` method from
`include/grpc++/impl/codegen/client_context.h` (commit `9477724`)
+- remove directory `include/grpc++` and all headers in it
+ (commit `eb06572`)
diff --git a/doc/environment_variables.md b/doc/environment_variables.md
index 5f0042e2eb..ed46a48e5e 100644
--- a/doc/environment_variables.md
+++ b/doc/environment_variables.md
@@ -18,7 +18,7 @@ some configuration as environment variables that can be set.
* GRPC_SSL_CIPHER_SUITES
A colon separated list of cipher suites to use with OpenSSL
Defaults to:
- ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-GCM-SHA384
+ ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384
* GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
PEM file to load SSL roots from
diff --git a/etc/roots.pem b/etc/roots.pem
index cd6a0c2489..15d819ba23 100644
--- a/etc/roots.pem
+++ b/etc/roots.pem
@@ -359,33 +359,6 @@ LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
398znM/jra6O1I7mT1GvFpLgXPYHDw==
-----END CERTIFICATE-----
-# Issuer: CN=Certum CA O=Unizeto Sp. z o.o.
-# Subject: CN=Certum CA O=Unizeto Sp. z o.o.
-# Label: "Certum Root CA"
-# Serial: 65568
-# MD5 Fingerprint: 2c:8f:9f:66:1d:18:90:b1:47:26:9d:8e:86:82:8c:a9
-# SHA1 Fingerprint: 62:52:dc:40:f7:11:43:a2:2f:de:9e:f7:34:8e:06:42:51:b1:81:18
-# SHA256 Fingerprint: d8:e0:fe:bc:1d:b2:e3:8d:00:94:0f:37:d2:7d:41:34:4d:99:3e:73:4b:99:d5:65:6d:97:78:d4:d8:14:36:24
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
-MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
-QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
-MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
-jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
-ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
-ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
-Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
-AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
-HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
-uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
-TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
-xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
-CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
-O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
-6GAqm4VKQPNriiTsBhYscw==
------END CERTIFICATE-----
-
# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
# Subject: CN=AAA Certificate Services O=Comodo CA Limited
# Label: "Comodo AAA Services root"
@@ -603,78 +576,6 @@ Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
-----END CERTIFICATE-----
-# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Label: "Camerfirma Chambers of Commerce Root"
-# Serial: 0
-# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84
-# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1
-# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
-b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
-MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
-ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
-IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
-AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
-unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
-BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
-7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
-0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
-roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
-A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
-aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
-26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
-BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
-EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
-BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
-aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
-AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
-p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
-1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
-XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
-eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
-tGWaIZDgqtCYvDi1czyL+Nw=
------END CERTIFICATE-----
-
-# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Label: "Camerfirma Global Chambersign Root"
-# Serial: 0
-# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19
-# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9
-# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed
------BEGIN CERTIFICATE-----
-MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
-YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
-MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
-NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
-A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
-A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
-Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
-QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
-eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
-B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
-z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
-AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
-ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
-TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
-MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
-VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
-VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
-bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
-AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
-bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
-ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
-VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
-ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
-AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
------END CERTIFICATE-----
-
# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
# Label: "XRamp Global CA Root"
@@ -772,58 +673,6 @@ VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
-# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Label: "StartCom Certification Authority"
-# Serial: 1
-# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16
-# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f
-# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea
------BEGIN CERTIFICATE-----
-MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
-FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
-ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
-LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
-BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
-Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
-dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
-cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
-YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
-dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
-bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
-YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
-TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
-9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
-jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
-FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
-ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
-ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
-EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
-L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
-yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
-O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
-um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
-NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
------END CERTIFICATE-----
-
# Issuer: O=Government Root Certification Authority
# Subject: O=Government Root Certification Authority
# Label: "Taiwan GRCA"
@@ -1013,38 +862,6 @@ JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
-# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
-# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
-# Label: "DST ACES CA X6"
-# Serial: 17771143917277623872238992636097467865
-# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8
-# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d
-# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40
------BEGIN CERTIFICATE-----
-MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
-ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
-MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
-VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
-FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
-ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
-gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
-fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
-ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
-ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
-MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
-c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
-dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
-aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
-hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
-QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
-h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
-nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
-rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
-9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
------END CERTIFICATE-----
-
# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
# Label: "SwissSign Gold CA - G2"
@@ -1373,35 +1190,6 @@ fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
-----END CERTIFICATE-----
-# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
-# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
-# Label: "Security Communication EV RootCA1"
-# Serial: 0
-# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3
-# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d
-# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37
------BEGIN CERTIFICATE-----
-MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
-MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
-IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
-bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
-RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
-zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
-bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
-MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
-VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
-OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
-tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
-q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
-EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
-Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
-VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
------END CERTIFICATE-----
-
# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
# Label: "OISTE WISeKey Global Root GA CA"
@@ -1565,44 +1353,6 @@ W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
-----END CERTIFICATE-----
-# Issuer: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
-# Subject: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
-# Label: "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3"
-# Serial: 17
-# MD5 Fingerprint: ed:41:f5:8c:50:c5:2b:9c:73:e6:ee:6c:eb:c2:a8:26
-# SHA1 Fingerprint: 1b:4b:39:61:26:27:6b:64:91:a2:68:6d:d7:02:43:21:2d:1f:1d:96
-# SHA256 Fingerprint: e4:c7:34:30:d7:a5:b5:09:25:df:43:37:0a:0d:21:6e:9a:79:b9:d6:db:83:73:a0:c6:9e:b1:cc:31:c7:c5:2a
------BEGIN CERTIFICATE-----
-MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
-MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
-bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
-VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
-YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
-dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
-ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
-Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
-GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
-aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
-QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
-xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
-aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
-IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
-gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
-O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
-fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
-lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
-hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
-AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
-NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
-wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
-7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
-gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
-oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
-yZyQ2uypQjyttgI=
------END CERTIFICATE-----
-
# Issuer: O=certSIGN OU=certSIGN ROOT CA
# Subject: O=certSIGN OU=certSIGN ROOT CA
# Label: "certSIGN ROOT CA"
@@ -1940,47 +1690,6 @@ pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
QSdJQO7e5iNEOdyhIta6A/I=
-----END CERTIFICATE-----
-# Issuer: CN=ACEDICOM Root O=EDICOM OU=PKI
-# Subject: CN=ACEDICOM Root O=EDICOM OU=PKI
-# Label: "ACEDICOM Root"
-# Serial: 7029493972724711941
-# MD5 Fingerprint: 42:81:a0:e2:1c:e3:55:10:de:55:89:42:65:96:22:e6
-# SHA1 Fingerprint: e0:b4:32:2e:b2:f6:a5:68:b6:54:53:84:48:18:4a:50:36:87:43:84
-# SHA256 Fingerprint: 03:95:0f:b4:9a:53:1f:3e:19:91:94:23:98:df:a9:e0:ea:32:d7:ba:1c:dd:9b:c8:5d:b5:7e:d9:40:0b:43:4a
------BEGIN CERTIFICATE-----
-MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE
-AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x
-CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW
-MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF
-RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
-AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7
-09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7
-XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P
-Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK
-t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb
-X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28
-MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU
-fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI
-2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH
-K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae
-ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP
-BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ
-MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw
-RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
-bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm
-fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3
-gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe
-I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i
-5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi
-ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn
-MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ
-o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6
-zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN
-GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt
-r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK
-Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==
------END CERTIFICATE-----
-
# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
# Label: "Microsec e-Szigno Root CA 2009"
@@ -2466,46 +2175,6 @@ VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
-----END CERTIFICATE-----
-# Issuer: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
-# Subject: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
-# Label: "Certinomis - Autorité Racine"
-# Serial: 1
-# MD5 Fingerprint: 7f:30:78:8c:03:e3:ca:c9:0a:e2:c9:ea:1e:aa:55:1a
-# SHA1 Fingerprint: 2e:14:da:ec:28:f0:fa:1e:8e:38:9a:4e:ab:eb:26:c0:0a:d3:83:c3
-# SHA256 Fingerprint: fc:bf:e2:88:62:06:f7:2b:27:59:3c:8b:07:02:97:e1:2d:76:9e:d1:0e:d7:93:07:05:a8:09:8e:ff:c1:4d:17
------BEGIN CERTIFICATE-----
-MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
-MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
-BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
-Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
-cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
-aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
-F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
-8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
-rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
-/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
-7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
-28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
-lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
-nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
-0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
-5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
-WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
-jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
-KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
-ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
-OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
-619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
-2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
-o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
-nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
-5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
-pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
-dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
-BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
------END CERTIFICATE-----
-
# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
# Label: "TWCA Root Certification Authority"
@@ -2706,96 +2375,6 @@ jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
ZetX2fNXlrtIzYE=
-----END CERTIFICATE-----
-# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Label: "StartCom Certification Authority"
-# Serial: 45
-# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16
-# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0
-# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11
------BEGIN CERTIFICATE-----
-MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
-F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
-ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
-ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
-aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
-YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
-c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
-d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
-CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
-wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
-Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
-0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
-pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
-CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
-P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
-1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
-KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
-JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
-8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
-fyWl8kgAwKQB2j8=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd.
-# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd.
-# Label: "StartCom Certification Authority G2"
-# Serial: 59
-# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64
-# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17
-# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95
------BEGIN CERTIFICATE-----
-MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
-OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
-A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
-JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
-vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
-D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
-Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
-RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
-HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
-nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
-0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
-UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
-Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
-TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
-BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
-2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
-UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
-6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
-9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
-HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
-wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
-XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
-IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
-hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
-so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
------END CERTIFICATE-----
-
# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
# Label: "Buypass Class 2 Root CA"
@@ -2937,39 +2516,6 @@ iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
-----END CERTIFICATE-----
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
-# Label: "TURKTRUST Certificate Services Provider Root 2007"
-# Serial: 1
-# MD5 Fingerprint: 2b:70:20:56:86:82:a0:18:c8:07:53:12:28:70:21:72
-# SHA1 Fingerprint: f1:7f:6f:b6:31:dc:99:e3:a3:c8:7f:fe:1c:f1:81:10:88:d9:60:33
-# SHA256 Fingerprint: 97:8c:d9:66:f2:fa:a0:7b:a7:aa:95:00:d9:c0:2e:9d:77:f2:cd:ad:a6:ad:6b:a7:4a:f4:b9:1c:66:59:3c:50
------BEGIN CERTIFICATE-----
-MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc
-UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS
-S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
-SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx
-OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry
-b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC
-VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE
-sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F
-ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY
-KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG
-+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG
-HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P
-IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M
-733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk
-Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW
-AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
-aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5
-mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa
-XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ
-qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
------END CERTIFICATE-----
-
# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
# Label: "D-TRUST Root Class 3 CA 2 2009"
@@ -3036,106 +2582,6 @@ xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
-----END CERTIFICATE-----
-# Issuer: CN=Autoridad de Certificacion Raiz del Estado Venezolano O=Sistema Nacional de Certificacion Electronica OU=Superintendencia de Servicios de Certificacion Electronica
-# Subject: CN=PSCProcert O=Sistema Nacional de Certificacion Electronica OU=Proveedor de Certificados PROCERT
-# Label: "PSCProcert"
-# Serial: 11
-# MD5 Fingerprint: e6:24:e9:12:01:ae:0c:de:8e:85:c4:ce:a3:12:dd:ec
-# SHA1 Fingerprint: 70:c1:8d:74:b4:28:81:0a:e4:fd:a5:75:d7:01:9f:99:b0:3d:50:74
-# SHA256 Fingerprint: 3c:fc:3c:14:d1:f6:84:ff:17:e3:8c:43:ca:44:0c:00:b9:67:ec:93:3e:8b:fe:06:4c:a1:d7:2c:90:f2:ad:b0
------BEGIN CERTIFICATE-----
-MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1
-dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
-YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
-dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
-aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
-IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
-KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw
-MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy
-b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx
-KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG
-A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u
-aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9
-7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74
-BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G
-ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9
-JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0
-PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2
-0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
-0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/
-6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m
-v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7
-K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev
-bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw
-MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w
-MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD
-gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0
-b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh
-bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0
-cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp
-ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg
-ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq
-hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD
-AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w
-MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag
-RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t
-UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl
-cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
-Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG
-AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN
-AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS
-1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB
-3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv
-Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh
-HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm
-pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz
-sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE
-qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb
-mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9
-opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H
-YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
------END CERTIFICATE-----
-
-# Issuer: CN=CA Disig Root R1 O=Disig a.s.
-# Subject: CN=CA Disig Root R1 O=Disig a.s.
-# Label: "CA Disig Root R1"
-# Serial: 14052245610670616104
-# MD5 Fingerprint: be:ec:11:93:9a:f5:69:21:bc:d7:c1:c0:67:89:cc:2a
-# SHA1 Fingerprint: 8e:1c:74:f8:a6:20:b9:e5:8a:f4:61:fa:ec:2b:47:56:51:1a:52:c6
-# SHA256 Fingerprint: f9:6f:23:f4:c3:e7:9c:07:7a:46:98:8d:5a:f5:90:06:76:a0:f0:39:cb:64:5d:d1:75:49:b2:16:c8:24:40:ce
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
-MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
-D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
-OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
-fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
-IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
-oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
-/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
-rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
-3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
-7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
-yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
-qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
-hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
-xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
-SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
-HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
-emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
-AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
-7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
-DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
-F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
-a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
-Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
------END CERTIFICATE-----
-
# Issuer: CN=CA Disig Root R2 O=Disig a.s.
# Subject: CN=CA Disig Root R2 O=Disig a.s.
# Label: "CA Disig Root R2"
@@ -3671,85 +3117,6 @@ r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1
gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+
-----END CERTIFICATE-----
-# Issuer: CN=Certification Authority of WoSign O=WoSign CA Limited
-# Subject: CN=Certification Authority of WoSign O=WoSign CA Limited
-# Label: "WoSign"
-# Serial: 125491772294754854453622855443212256657
-# MD5 Fingerprint: a1:f2:f9:b5:d2:c8:7a:74:b8:f3:05:f1:d7:e1:84:8d
-# SHA1 Fingerprint: b9:42:94:bf:91:ea:8f:b6:4b:e6:10:97:c7:fb:00:13:59:b6:76:cb
-# SHA256 Fingerprint: 4b:22:d5:a6:ae:c9:9f:3c:db:79:aa:5e:c0:68:38:47:9c:d5:ec:ba:71:64:f7:f2:2d:c1:d6:5f:63:d8:57:08
------BEGIN CERTIFICATE-----
-MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBV
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV
-BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgw
-MTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX
-b1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvcqN
-rLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1U
-fcIiePyOCbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcScc
-f+Hb0v1naMQFXQoOXXDX2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2
-ZjC1vt7tj/id07sBMOby8w7gLJKA84X5KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4M
-x1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR+ScPewavVIMYe+HdVHpR
-aG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ezEC8wQjch
-zDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDar
-uHqklWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221K
-mYo0SLwX3OSACCK28jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvA
-Sh0JWzko/amrzgD5LkhLJuYwTKVYyrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWv
-HYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0CAwEAAaNCMEAwDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R8bNLtwYgFP6H
-EtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
-LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJ
-MuYhOZO9sxXqT2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2e
-JXLOC62qx1ViC777Y7NhRCOjy+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VN
-g64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC2nz4SNAzqfkHx5Xh9T71XXG68pWp
-dIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes5cVAWubXbHssw1ab
-R80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/EaEQ
-PkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGce
-xGATVdVhmVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+
-J7x6v+Db9NpSvd4MVHAxkUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMl
-OtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGikpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWT
-ee5Ehr7XHuQe+w==
------END CERTIFICATE-----
-
-# Issuer: CN=CA 沃通根证书 O=WoSign CA Limited
-# Subject: CN=CA 沃通根证书 O=WoSign CA Limited
-# Label: "WoSign China"
-# Serial: 106921963437422998931660691310149453965
-# MD5 Fingerprint: 78:83:5b:52:16:76:c4:24:3b:83:78:e8:ac:da:9a:93
-# SHA1 Fingerprint: 16:32:47:8d:89:f9:21:3a:92:00:85:63:f5:a4:a7:d3:12:40:8a:d6
-# SHA256 Fingerprint: d6:f0:34:bd:94:aa:23:3f:02:97:ec:a4:24:5b:28:39:73:e4:47:aa:59:0f:31:0c:77:f4:8f:df:83:11:22:54
------BEGIN CERTIFICATE-----
-MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBG
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNV
-BAMMEkNBIOayg+mAmuagueivgeS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgw
-MTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRl
-ZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k8H/r
-D195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld1
-9AXbbQs5uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExf
-v5RxadmWPgxDT74wwJ85dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnk
-UkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+L
-NVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFyb7Ao65vh4YOhn0pdr8yb
-+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc76DbT52V
-qyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6K
-yX2m+Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0G
-AbQOXDBGVWCvOGU6yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaK
-J/kR8slC/k7e3x9cxKSGhxYzoacXGKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwEC
-AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
-BBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUAA4ICAQBqinA4
-WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
-yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj
-/feTZU7n85iYr83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6
-jBAyvd0zaziGfjk9DgNyp115j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2
-ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0AkLppRQjbbpCBhqcqBT/mhDn4t/lX
-X0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97qA4bLJyuQHCH2u2n
-FoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Yjj4D
-u9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10l
-O1Hm13ZBONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Le
-ie2uPAmvylezkolwQOQvT8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR1
-2KvxAmLBsX5VYc8T1yaw15zLKYs4SgsOkI26oQ==
------END CERTIFICATE-----
-
# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited
# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited
# Label: "COMODO RSA Certification Authority"
@@ -4261,56 +3628,6 @@ aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
-----END CERTIFICATE-----
-# Issuer: CN=Certification Authority of WoSign G2 O=WoSign CA Limited
-# Subject: CN=Certification Authority of WoSign G2 O=WoSign CA Limited
-# Label: "Certification Authority of WoSign G2"
-# Serial: 142423943073812161787490648904721057092
-# MD5 Fingerprint: c8:1c:7d:19:aa:cb:71:93:f2:50:f8:52:a8:1e:ba:60
-# SHA1 Fingerprint: fb:ed:dc:90:65:b7:27:20:37:bc:55:0c:9c:56:de:bb:f2:78:94:e1
-# SHA256 Fingerprint: d4:87:a5:6f:83:b0:74:82:e8:5e:96:33:94:c1:ec:c2:c9:e5:1d:09:03:ee:94:6b:02:c3:01:58:1e:d9:9e:16
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBY
-MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNV
-BAMTJENlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDEx
-MDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgxCzAJBgNVBAYTAkNOMRowGAYDVQQK
-ExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlmaWNhdGlvbiBBdXRo
-b3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPX
-JYY1kBaiXW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgO
-gHzKtB0TiGsOqCR3A9DuW/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg
-5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg95k4ot+vElbGs/V6r+kHLXZ1L3PR8du9n
-fwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BKv0mUYQs4kI9dJGwlezt5
-2eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJ
-KoZIhvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8
-fHulwqZm46qwtyeYP0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G
-3CE4Q3RM+zD4F3LBMvzIkRfEzFg3TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yy
-SrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu+sif/a+RZQp4OBXllxcU3fng
-LDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+7Q9LGOHSJDy7
-XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg=
------END CERTIFICATE-----
-
-# Issuer: CN=CA WoSign ECC Root O=WoSign CA Limited
-# Subject: CN=CA WoSign ECC Root O=WoSign CA Limited
-# Label: "CA WoSign ECC Root"
-# Serial: 138625735294506723296996289575837012112
-# MD5 Fingerprint: 80:c6:53:ee:61:82:28:72:f0:ff:21:b9:17:ca:b2:20
-# SHA1 Fingerprint: d2:7a:d2:be:ed:94:c0:a1:3c:c7:25:21:ea:5d:71:be:81:19:f3:2b
-# SHA256 Fingerprint: 8b:45:da:1c:06:f7:91:eb:0c:ab:f2:6b:e5:88:f5:fb:23:16:5c:2e:61:4b:f8:85:56:2d:0d:ce:50:b2:9b:02
------BEGIN CERTIFICATE-----
-MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQsw
-CQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMT
-EkNBIFdvU2lnbiBFQ0MgUm9vdDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4
-NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEb
-MBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACID
-YgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiUt5v8
-KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES
-1ns2o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
-FgQUqv3VWqP2h4syhf3RMluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB
-1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0Daupn75OcsqF1NnstTJFGG+rrQIwfcf3
-aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYua/GRspBl9JrmkO5K
------END CERTIFICATE-----
-
# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.
# Label: "SZAFIR ROOT CA2"
@@ -4874,3 +4191,285 @@ lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c
8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf
lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
-----END CERTIFICATE-----
+
+# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
+# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.
+# Label: "GDCA TrustAUTH R5 ROOT"
+# Serial: 9009899650740120186
+# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4
+# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4
+# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93
+-----BEGIN CERTIFICATE-----
+MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE
+BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ
+IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0
+MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV
+BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w
+HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj
+Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj
+TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u
+KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj
+qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm
+MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12
+ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP
+zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk
+L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC
+jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA
+HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC
+AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg
+p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm
+DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5
+COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry
+L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf
+JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg
+IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io
+2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV
+09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ
+XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq
+T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe
+MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Label: "TrustCor RootCert CA-1"
+# Serial: 15752444095811006489
+# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45
+# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a
+# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD
+VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk
+MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
+cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y
+IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB
+pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h
+IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG
+A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU
+cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid
+RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V
+seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme
+9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV
+EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW
+hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/
+DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw
+DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
+ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I
+/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf
+ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ
+yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts
+L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN
+zl/HHk484IkzlQsPpTLWPFp5LBk=
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Label: "TrustCor RootCert CA-2"
+# Serial: 2711694510199101698
+# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64
+# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0
+# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65
+-----BEGIN CERTIFICATE-----
+MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV
+BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw
+IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy
+dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig
+Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk
+MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg
+Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD
+VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy
+dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+
+QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq
+1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp
+2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK
+DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape
+az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF
+3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88
+oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM
+g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3
+mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh
+8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd
+BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U
+nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw
+DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX
+dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+
+MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL
+/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX
+CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa
+ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW
+2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7
+N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3
+Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB
+As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp
+5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu
+1uwJ
+-----END CERTIFICATE-----
+
+# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority
+# Label: "TrustCor ECA-1"
+# Serial: 9548242946988625984
+# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c
+# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd
+# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD
+VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk
+MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U
+cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y
+IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV
+BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw
+IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy
+dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig
+RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb
+3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA
+BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5
+3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou
+owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/
+wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF
+ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf
+BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/
+MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv
+civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2
+AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F
+hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50
+soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI
+WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi
+tJ/X5g==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
+# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation
+# Label: "SSL.com Root Certification Authority RSA"
+# Serial: 8875640296558310041
+# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29
+# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb
+# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69
+-----BEGIN CERTIFICATE-----
+MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE
+BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK
+DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz
+OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv
+bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN
+AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R
+xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX
+qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC
+C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3
+6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh
+/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF
+YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E
+JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc
+US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8
+ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm
++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi
+M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV
+HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G
+A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV
+cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc
+Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs
+PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/
+q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0
+cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr
+a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I
+H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y
+K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu
+nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf
+oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY
+Ic2wBlX7Jz9TkHCpBB5XJ7k=
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
+# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation
+# Label: "SSL.com Root Certification Authority ECC"
+# Serial: 8495723813297216424
+# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e
+# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a
+# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65
+-----BEGIN CERTIFICATE-----
+MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz
+WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0
+b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS
+b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB
+BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI
+7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg
+CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud
+EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD
+VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T
+kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+
+gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
+# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation
+# Label: "SSL.com EV Root Certification Authority RSA R2"
+# Serial: 6248227494352943350
+# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95
+# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a
+# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c
+-----BEGIN CERTIFICATE-----
+MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV
+BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE
+CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy
+MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G
+A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD
+DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq
+M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf
+OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa
+4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9
+HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR
+aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA
+b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ
+Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV
+PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO
+pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu
+UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY
+MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV
+HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4
+9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW
+s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5
+Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg
+cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM
+79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz
+/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt
+ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm
+Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK
+QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ
+w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi
+S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07
+mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
+# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation
+# Label: "SSL.com EV Root Certification Authority ECC"
+# Serial: 3182246526754555285
+# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90
+# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d
+# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8
+-----BEGIN CERTIFICATE-----
+MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
+VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
+U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
+Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
+NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
+dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
+bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
+AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
+VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
+WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
+MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
+5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
+ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
+h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
+-----END CERTIFICATE-----
diff --git a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm
index 6ff1ca593d..18a0972e32 100644
--- a/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm
+++ b/examples/cpp/helloworld/cocoapods/HelloWorldCpp/ViewController.mm
@@ -17,9 +17,9 @@
*/
#import "ViewController.h"
-#import <grpc++/grpc++.h>
-#include <grpc++/generic/generic_stub.h>
-#include <grpc++/generic/async_generic_service.h>
+#import <grpcpp/grpcpp.h>
+#include <grpcpp/generic/generic_stub.h>
+#include <grpcpp/generic/async_generic_service.h>
static void* tag(int i) { return (void*)(intptr_t)i; }
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 943ada7530..60b3dcb056 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -23,15 +23,15 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
- # version = '1.10.0-dev'
- version = '0.0.1'
+ # version = '1.11.0-dev'
+ version = '0.0.2'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
- grpc_version = '1.10.0-dev'
+ grpc_version = '1.11.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
@@ -42,8 +42,14 @@ Pod::Spec.new do |s|
s.osx.deployment_target = '10.9'
s.requires_arc = false
- # Add include prefix `grpc++` (i.e. `#include <grpc++/xxx.h>`).
- s.header_dir = 'grpc++'
+ name = 'grpcpp'
+ # Use `grpcpp` as framework name so that `#include <grpcpp/xxx.h>` works when built as
+ # framework.
+ s.module_name = name
+
+ # Add include prefix `grpcpp` so that `#include <grpcpp/xxx.h>` works when built as static
+ # library.
+ s.header_dir = name
s.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(PODS_TARGET_SRCROOT)/include"',
@@ -63,84 +69,86 @@ Pod::Spec.new do |s|
s.default_subspecs = 'Interface', 'Implementation'
+ s.header_mappings_dir = 'include/grpcpp'
+
s.subspec 'Interface' do |ss|
- ss.header_mappings_dir = 'include/grpc++'
+ ss.header_mappings_dir = 'include/grpcpp'
- ss.source_files = 'include/grpc++/alarm.h',
- 'include/grpc++/channel.h',
- 'include/grpc++/client_context.h',
- 'include/grpc++/completion_queue.h',
- 'include/grpc++/create_channel.h',
- 'include/grpc++/create_channel_posix.h',
- 'include/grpc++/ext/health_check_service_server_builder_option.h',
- 'include/grpc++/generic/async_generic_service.h',
- 'include/grpc++/generic/generic_stub.h',
- 'include/grpc++/grpc++.h',
- 'include/grpc++/health_check_service_interface.h',
- 'include/grpc++/impl/call.h',
- 'include/grpc++/impl/channel_argument_option.h',
- 'include/grpc++/impl/client_unary_call.h',
- 'include/grpc++/impl/codegen/core_codegen.h',
- 'include/grpc++/impl/grpc_library.h',
- 'include/grpc++/impl/method_handler_impl.h',
- 'include/grpc++/impl/rpc_method.h',
- 'include/grpc++/impl/rpc_service_method.h',
- 'include/grpc++/impl/serialization_traits.h',
- 'include/grpc++/impl/server_builder_option.h',
- 'include/grpc++/impl/server_builder_plugin.h',
- 'include/grpc++/impl/server_initializer.h',
- 'include/grpc++/impl/service_type.h',
- 'include/grpc++/resource_quota.h',
- 'include/grpc++/security/auth_context.h',
- 'include/grpc++/security/auth_metadata_processor.h',
- 'include/grpc++/security/credentials.h',
- 'include/grpc++/security/server_credentials.h',
- 'include/grpc++/server.h',
- 'include/grpc++/server_builder.h',
- 'include/grpc++/server_context.h',
- 'include/grpc++/server_posix.h',
- 'include/grpc++/support/async_stream.h',
- 'include/grpc++/support/async_unary_call.h',
- 'include/grpc++/support/byte_buffer.h',
- 'include/grpc++/support/channel_arguments.h',
- 'include/grpc++/support/config.h',
- 'include/grpc++/support/slice.h',
- 'include/grpc++/support/status.h',
- 'include/grpc++/support/status_code_enum.h',
- 'include/grpc++/support/string_ref.h',
- 'include/grpc++/support/stub_options.h',
- 'include/grpc++/support/sync_stream.h',
- 'include/grpc++/support/time.h',
- 'include/grpc++/impl/codegen/async_stream.h',
- 'include/grpc++/impl/codegen/async_unary_call.h',
- 'include/grpc++/impl/codegen/byte_buffer.h',
- 'include/grpc++/impl/codegen/call.h',
- 'include/grpc++/impl/codegen/call_hook.h',
- 'include/grpc++/impl/codegen/channel_interface.h',
- 'include/grpc++/impl/codegen/client_context.h',
- 'include/grpc++/impl/codegen/client_unary_call.h',
- 'include/grpc++/impl/codegen/completion_queue.h',
- 'include/grpc++/impl/codegen/completion_queue_tag.h',
- 'include/grpc++/impl/codegen/config.h',
- 'include/grpc++/impl/codegen/core_codegen_interface.h',
- 'include/grpc++/impl/codegen/create_auth_context.h',
- 'include/grpc++/impl/codegen/grpc_library.h',
- 'include/grpc++/impl/codegen/metadata_map.h',
- 'include/grpc++/impl/codegen/method_handler_impl.h',
- 'include/grpc++/impl/codegen/rpc_method.h',
- 'include/grpc++/impl/codegen/rpc_service_method.h',
- 'include/grpc++/impl/codegen/security/auth_context.h',
- 'include/grpc++/impl/codegen/serialization_traits.h',
- 'include/grpc++/impl/codegen/server_context.h',
- 'include/grpc++/impl/codegen/server_interface.h',
- 'include/grpc++/impl/codegen/service_type.h',
- 'include/grpc++/impl/codegen/slice.h',
- 'include/grpc++/impl/codegen/status.h',
- 'include/grpc++/impl/codegen/status_code_enum.h',
- 'include/grpc++/impl/codegen/string_ref.h',
- 'include/grpc++/impl/codegen/stub_options.h',
- 'include/grpc++/impl/codegen/sync_stream.h',
- 'include/grpc++/impl/codegen/time.h'
+ ss.source_files = 'include/grpcpp/alarm.h',
+ 'include/grpcpp/channel.h',
+ 'include/grpcpp/client_context.h',
+ 'include/grpcpp/completion_queue.h',
+ 'include/grpcpp/create_channel.h',
+ 'include/grpcpp/create_channel_posix.h',
+ 'include/grpcpp/ext/health_check_service_server_builder_option.h',
+ 'include/grpcpp/generic/async_generic_service.h',
+ 'include/grpcpp/generic/generic_stub.h',
+ 'include/grpcpp/grpcpp.h',
+ 'include/grpcpp/health_check_service_interface.h',
+ 'include/grpcpp/impl/call.h',
+ 'include/grpcpp/impl/channel_argument_option.h',
+ 'include/grpcpp/impl/client_unary_call.h',
+ 'include/grpcpp/impl/codegen/core_codegen.h',
+ 'include/grpcpp/impl/grpc_library.h',
+ 'include/grpcpp/impl/method_handler_impl.h',
+ 'include/grpcpp/impl/rpc_method.h',
+ 'include/grpcpp/impl/rpc_service_method.h',
+ 'include/grpcpp/impl/serialization_traits.h',
+ 'include/grpcpp/impl/server_builder_option.h',
+ 'include/grpcpp/impl/server_builder_plugin.h',
+ 'include/grpcpp/impl/server_initializer.h',
+ 'include/grpcpp/impl/service_type.h',
+ 'include/grpcpp/resource_quota.h',
+ 'include/grpcpp/security/auth_context.h',
+ 'include/grpcpp/security/auth_metadata_processor.h',
+ 'include/grpcpp/security/credentials.h',
+ 'include/grpcpp/security/server_credentials.h',
+ 'include/grpcpp/server.h',
+ 'include/grpcpp/server_builder.h',
+ 'include/grpcpp/server_context.h',
+ 'include/grpcpp/server_posix.h',
+ 'include/grpcpp/support/async_stream.h',
+ 'include/grpcpp/support/async_unary_call.h',
+ 'include/grpcpp/support/byte_buffer.h',
+ 'include/grpcpp/support/channel_arguments.h',
+ 'include/grpcpp/support/config.h',
+ 'include/grpcpp/support/slice.h',
+ 'include/grpcpp/support/status.h',
+ 'include/grpcpp/support/status_code_enum.h',
+ 'include/grpcpp/support/string_ref.h',
+ 'include/grpcpp/support/stub_options.h',
+ 'include/grpcpp/support/sync_stream.h',
+ 'include/grpcpp/support/time.h',
+ 'include/grpcpp/impl/codegen/async_stream.h',
+ 'include/grpcpp/impl/codegen/async_unary_call.h',
+ 'include/grpcpp/impl/codegen/byte_buffer.h',
+ 'include/grpcpp/impl/codegen/call.h',
+ 'include/grpcpp/impl/codegen/call_hook.h',
+ 'include/grpcpp/impl/codegen/channel_interface.h',
+ 'include/grpcpp/impl/codegen/client_context.h',
+ 'include/grpcpp/impl/codegen/client_unary_call.h',
+ 'include/grpcpp/impl/codegen/completion_queue.h',
+ 'include/grpcpp/impl/codegen/completion_queue_tag.h',
+ 'include/grpcpp/impl/codegen/config.h',
+ 'include/grpcpp/impl/codegen/core_codegen_interface.h',
+ 'include/grpcpp/impl/codegen/create_auth_context.h',
+ 'include/grpcpp/impl/codegen/grpc_library.h',
+ 'include/grpcpp/impl/codegen/metadata_map.h',
+ 'include/grpcpp/impl/codegen/method_handler_impl.h',
+ 'include/grpcpp/impl/codegen/rpc_method.h',
+ 'include/grpcpp/impl/codegen/rpc_service_method.h',
+ 'include/grpcpp/impl/codegen/security/auth_context.h',
+ 'include/grpcpp/impl/codegen/serialization_traits.h',
+ 'include/grpcpp/impl/codegen/server_context.h',
+ 'include/grpcpp/impl/codegen/server_interface.h',
+ 'include/grpcpp/impl/codegen/service_type.h',
+ 'include/grpcpp/impl/codegen/slice.h',
+ 'include/grpcpp/impl/codegen/status.h',
+ 'include/grpcpp/impl/codegen/status_code_enum.h',
+ 'include/grpcpp/impl/codegen/string_ref.h',
+ 'include/grpcpp/impl/codegen/stub_options.h',
+ 'include/grpcpp/impl/codegen/sync_stream.h',
+ 'include/grpcpp/impl/codegen/time.h'
end
s.subspec 'Implementation' do |ss|
@@ -149,7 +157,7 @@ Pod::Spec.new do |s|
ss.dependency 'gRPC-Core', grpc_version
ss.dependency 'nanopb', '~> 0.3'
- ss.source_files = 'include/grpc++/impl/codegen/core_codegen.h',
+ ss.source_files = 'include/grpcpp/impl/codegen/core_codegen.h',
'src/cpp/client/secure_credentials.h',
'src/cpp/common/secure_auth_context.h',
'src/cpp/server/secure_server_credentials.h',
@@ -212,7 +220,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/spinlock.h',
'src/core/lib/gpr/string.h',
'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/thd_internal.h',
+ 'src/core/lib/gpr/thd.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -263,11 +271,11 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
+ 'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
- 'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
+ 'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
@@ -288,6 +296,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
+ 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
@@ -295,6 +304,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/status_util.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
@@ -401,6 +411,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
@@ -425,12 +436,12 @@ Pod::Spec.new do |s|
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
+ 'src/core/lib/transport/status_metadata.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
'src/core/lib/transport/transport_impl.h',
'src/core/lib/debug/trace.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
- 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
@@ -446,7 +457,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h',
'src/core/ext/filters/workarounds/workaround_utils.h'
- ss.private_header_files = 'include/grpc++/impl/codegen/core_codegen.h',
+ ss.private_header_files = 'include/grpcpp/impl/codegen/core_codegen.h',
'src/cpp/client/secure_credentials.h',
'src/cpp/common/secure_auth_context.h',
'src/cpp/server/secure_server_credentials.h',
@@ -466,7 +477,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/spinlock.h',
'src/core/lib/gpr/string.h',
'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/thd_internal.h',
+ 'src/core/lib/gpr/thd.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -581,6 +592,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
@@ -605,6 +617,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
+ 'src/core/lib/transport/status_metadata.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
'src/core/lib/transport/transport_impl.h',
@@ -612,114 +625,6 @@ Pod::Spec.new do |s|
'src/core/ext/transport/inproc/inproc_transport.h'
end
- s.subspec 'Tests' do |ss|
- ss.header_mappings_dir = '.'
-
- ss.dependency "#{s.name}/Interface", version
- ss.dependency "#{s.name}/Implementation", version
- ss.dependency "gRPC-Core/Tests", grpc_version
-
- ss.source_files = 'test/cpp/util/create_test_channel.cc',
- 'test/cpp/util/string_ref_helper.cc',
- 'test/cpp/util/subprocess.cc',
- 'test/cpp/util/test_credentials_provider.cc',
- 'test/cpp/util/create_test_channel.h',
- 'test/cpp/util/string_ref_helper.h',
- 'test/cpp/util/subprocess.h',
- 'test/cpp/util/test_credentials_provider.h',
- 'test/core/util/test_config.h',
- 'test/core/end2end/data/ssl_test_data.h',
- 'test/core/security/oauth2_utils.h',
- 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h',
- 'test/core/end2end/cq_verifier.h',
- 'test/core/end2end/fixtures/http_proxy_fixture.h',
- 'test/core/end2end/fixtures/proxy.h',
- 'test/core/iomgr/endpoint_tests.h',
- 'test/core/util/channel_tracing_utils.h',
- 'test/core/util/debugger_macros.h',
- 'test/core/util/grpc_profiler.h',
- 'test/core/util/histogram.h',
- 'test/core/util/memory_counters.h',
- 'test/core/util/mock_endpoint.h',
- 'test/core/util/parse_hexstring.h',
- 'test/core/util/passthru_endpoint.h',
- 'test/core/util/port.h',
- 'test/core/util/port_server_client.h',
- 'test/core/util/slice_splitter.h',
- 'test/core/util/subprocess.h',
- 'test/core/util/tracer_util.h',
- 'test/core/util/trickle_endpoint.h',
- 'test/core/util/cmdline.h',
- 'src/core/lib/gpr/arena.h',
- 'src/core/lib/gpr/env.h',
- 'src/core/lib/gpr/fork.h',
- 'src/core/lib/gpr/host_port.h',
- 'src/core/lib/gpr/mpscq.h',
- 'src/core/lib/gpr/murmur_hash.h',
- 'src/core/lib/gpr/spinlock.h',
- 'src/core/lib/gpr/string.h',
- 'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/thd_internal.h',
- 'src/core/lib/gpr/time_precise.h',
- 'src/core/lib/gpr/tls.h',
- 'src/core/lib/gpr/tls_gcc.h',
- 'src/core/lib/gpr/tls_msvc.h',
- 'src/core/lib/gpr/tls_pthread.h',
- 'src/core/lib/gpr/tmpfile.h',
- 'src/core/lib/gpr/useful.h',
- 'src/core/lib/gprpp/abstract.h',
- 'src/core/lib/gprpp/atomic.h',
- 'src/core/lib/gprpp/atomic_with_atm.h',
- 'src/core/lib/gprpp/atomic_with_std.h',
- 'src/core/lib/gprpp/manual_constructor.h',
- 'src/core/lib/gprpp/memory.h',
- 'src/core/lib/profiling/timers.h',
- 'src/core/ext/filters/client_channel/backup_poller.h',
- 'src/core/ext/filters/client_channel/client_channel.h',
- 'src/core/ext/filters/client_channel/client_channel_factory.h',
- 'src/core/ext/filters/client_channel/connector.h',
- 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
- 'src/core/ext/filters/client_channel/http_proxy.h',
- 'src/core/ext/filters/client_channel/lb_policy.h',
- 'src/core/ext/filters/client_channel/lb_policy_factory.h',
- 'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/parse_address.h',
- 'src/core/ext/filters/client_channel/proxy_mapper.h',
- 'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
- 'src/core/ext/filters/client_channel/resolver.h',
- 'src/core/ext/filters/client_channel/resolver_factory.h',
- 'src/core/ext/filters/client_channel/resolver_registry.h',
- 'src/core/ext/filters/client_channel/retry_throttle.h',
- 'src/core/ext/filters/client_channel/subchannel.h',
- 'src/core/ext/filters/client_channel/subchannel_index.h',
- 'src/core/ext/filters/client_channel/uri_parser.h',
- 'src/core/ext/filters/deadline/deadline_filter.h',
- 'src/core/ext/transport/chttp2/transport/bin_decoder.h',
- 'src/core/ext/transport/chttp2/transport/bin_encoder.h',
- 'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
- 'src/core/ext/transport/chttp2/transport/flow_control.h',
- 'src/core/ext/transport/chttp2/transport/frame.h',
- 'src/core/ext/transport/chttp2/transport/frame_data.h',
- 'src/core/ext/transport/chttp2/transport/frame_goaway.h',
- 'src/core/ext/transport/chttp2/transport/frame_ping.h',
- 'src/core/ext/transport/chttp2/transport/frame_rst_stream.h',
- 'src/core/ext/transport/chttp2/transport/frame_settings.h',
- 'src/core/ext/transport/chttp2/transport/frame_window_update.h',
- 'src/core/ext/transport/chttp2/transport/hpack_encoder.h',
- 'src/core/ext/transport/chttp2/transport/hpack_parser.h',
- 'src/core/ext/transport/chttp2/transport/hpack_table.h',
- 'src/core/ext/transport/chttp2/transport/http2_settings.h',
- 'src/core/ext/transport/chttp2/transport/huffsyms.h',
- 'src/core/ext/transport/chttp2/transport/incoming_metadata.h',
- 'src/core/ext/transport/chttp2/transport/internal.h',
- 'src/core/ext/transport/chttp2/transport/stream_map.h',
- 'src/core/ext/transport/chttp2/transport/varint.h',
- 'src/core/ext/transport/chttp2/alpn/alpn.h',
- 'src/core/ext/filters/http/client/http_client_filter.h',
- 'src/core/ext/filters/http/message_compress/message_compress_filter.h',
- 'src/core/ext/filters/http/server/http_server_filter.h'
- end
-
s.prepare_command = <<-END_OF_COMMAND
find src/cpp/ -type f -exec sed -E -i'.back' 's;#include "third_party/nanopb/(.*)";#include <nanopb/\\1>;g' {} \\\;
find src/cpp/ -name "*.back" -type f -delete
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 88af7c7c79..903ec336e5 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.10.0-dev'
+ version = '1.11.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -124,7 +124,7 @@ Pod::Spec.new do |s|
'include/grpc/support/sync_generic.h',
'include/grpc/support/sync_posix.h',
'include/grpc/support/sync_windows.h',
- 'include/grpc/support/thd.h',
+ 'include/grpc/support/thd_id.h',
'include/grpc/support/time.h',
'include/grpc/impl/codegen/atm.h',
'include/grpc/impl/codegen/atm_gcc_atomic.h',
@@ -192,7 +192,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/spinlock.h',
'src/core/lib/gpr/string.h',
'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/thd_internal.h',
+ 'src/core/lib/gpr/thd.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -283,11 +283,11 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
+ 'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
- 'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
+ 'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
@@ -308,6 +308,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
+ 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
@@ -315,6 +316,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/status_util.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
@@ -421,6 +423,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
@@ -445,12 +448,12 @@ Pod::Spec.new do |s|
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
+ 'src/core/lib/transport/status_metadata.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
'src/core/lib/transport/transport_impl.h',
'src/core/lib/debug/trace.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
- 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
@@ -568,7 +571,6 @@ Pod::Spec.new do |s|
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@@ -599,6 +601,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
+ 'src/core/lib/transport/status_metadata.cc',
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
@@ -646,12 +649,12 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
+ 'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
- 'src/core/lib/security/transport/lb_targets_info.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
- 'src/core/lib/security/transport/security_connector.cc',
'src/core/lib/security/transport/security_handshaker.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
+ 'src/core/lib/security/transport/target_authority_table.cc',
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
@@ -674,12 +677,14 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
+ 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/status_util.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
@@ -725,7 +730,7 @@ Pod::Spec.new do |s|
'src/core/lib/gpr/spinlock.h',
'src/core/lib/gpr/string.h',
'src/core/lib/gpr/string_windows.h',
- 'src/core/lib/gpr/thd_internal.h',
+ 'src/core/lib/gpr/thd.h',
'src/core/lib/gpr/time_precise.h',
'src/core/lib/gpr/tls.h',
'src/core/lib/gpr/tls_gcc.h',
@@ -776,11 +781,11 @@ Pod::Spec.new do |s|
'src/core/lib/security/credentials/oauth2/oauth2_credentials.h',
'src/core/lib/security/credentials/plugin/plugin_credentials.h',
'src/core/lib/security/credentials/ssl/ssl_credentials.h',
+ 'src/core/lib/security/security_connector/security_connector.h',
'src/core/lib/security/transport/auth_filters.h',
- 'src/core/lib/security/transport/lb_targets_info.h',
'src/core/lib/security/transport/secure_endpoint.h',
- 'src/core/lib/security/transport/security_connector.h',
'src/core/lib/security/transport/security_handshaker.h',
+ 'src/core/lib/security/transport/target_authority_table.h',
'src/core/lib/security/transport/tsi_error.h',
'src/core/lib/security/util/json_util.h',
'src/core/tsi/alts_transport_security.h',
@@ -801,6 +806,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
+ 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
@@ -808,6 +814,7 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/status_util.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/client_channel/uri_parser.h',
@@ -914,6 +921,7 @@ Pod::Spec.new do |s|
'src/core/lib/slice/slice_hash_table.h',
'src/core/lib/slice/slice_internal.h',
'src/core/lib/slice/slice_string_helpers.h',
+ 'src/core/lib/slice/slice_weak_hash_table.h',
'src/core/lib/surface/api_trace.h',
'src/core/lib/surface/call.h',
'src/core/lib/surface/call_test_only.h',
@@ -938,12 +946,12 @@ Pod::Spec.new do |s|
'src/core/lib/transport/service_config.h',
'src/core/lib/transport/static_metadata.h',
'src/core/lib/transport/status_conversion.h',
+ 'src/core/lib/transport/status_metadata.h',
'src/core/lib/transport/timeout_encoding.h',
'src/core/lib/transport/transport.h',
'src/core/lib/transport/transport_impl.h',
'src/core/lib/debug/trace.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h',
- 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h',
'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h',
@@ -1080,6 +1088,21 @@ Pod::Spec.new do |s|
'test/core/end2end/tests/request_with_flags.cc',
'test/core/end2end/tests/request_with_payload.cc',
'test/core/end2end/tests/resource_quota_server.cc',
+ 'test/core/end2end/tests/retry.cc',
+ 'test/core/end2end/tests/retry_cancellation.cc',
+ 'test/core/end2end/tests/retry_disabled.cc',
+ 'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
+ 'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
+ 'test/core/end2end/tests/retry_non_retriable_status.cc',
+ 'test/core/end2end/tests/retry_recv_initial_metadata.cc',
+ 'test/core/end2end/tests/retry_recv_message.cc',
+ 'test/core/end2end/tests/retry_server_pushback_delay.cc',
+ 'test/core/end2end/tests/retry_server_pushback_disabled.cc',
+ 'test/core/end2end/tests/retry_streaming.cc',
+ 'test/core/end2end/tests/retry_streaming_after_commit.cc',
+ 'test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc',
+ 'test/core/end2end/tests/retry_throttled.cc',
+ 'test/core/end2end/tests/retry_too_many_attempts.cc',
'test/core/end2end/tests/server_finishes_request.cc',
'test/core/end2end/tests/shutdown_finishes_calls.cc',
'test/core/end2end/tests/shutdown_finishes_tags.cc',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index a0375bd0b8..149687e5b4 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.10.0-dev'
+ version = '1.11.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 280aafefb6..2497174417 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.10.0-dev'
+ version = '1.11.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 930d991a6c..68e06b5536 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.10.0-dev'
+ version = '1.11.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.def b/grpc.def
index 8a6210253a..2bafebbbd4 100644
--- a/grpc.def
+++ b/grpc.def
@@ -211,14 +211,7 @@ EXPORTS
gpr_stats_init
gpr_stats_inc
gpr_stats_read
- gpr_thd_new
- gpr_thd_options_default
- gpr_thd_options_set_detached
- gpr_thd_options_set_joinable
- gpr_thd_options_is_detached
- gpr_thd_options_is_joinable
gpr_thd_currentid
- gpr_thd_join
gpr_time_0
gpr_inf_future
gpr_inf_past
diff --git a/grpc.gemspec b/grpc.gemspec
index 3df5575d63..507c5e342f 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -59,7 +59,7 @@ Gem::Specification.new do |s|
s.files += %w( include/grpc/support/sync_generic.h )
s.files += %w( include/grpc/support/sync_posix.h )
s.files += %w( include/grpc/support/sync_windows.h )
- s.files += %w( include/grpc/support/thd.h )
+ s.files += %w( include/grpc/support/thd_id.h )
s.files += %w( include/grpc/support/time.h )
s.files += %w( include/grpc/impl/codegen/atm.h )
s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
@@ -83,7 +83,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/gpr/spinlock.h )
s.files += %w( src/core/lib/gpr/string.h )
s.files += %w( src/core/lib/gpr/string_windows.h )
- s.files += %w( src/core/lib/gpr/thd_internal.h )
+ s.files += %w( src/core/lib/gpr/thd.h )
s.files += %w( src/core/lib/gpr/time_precise.h )
s.files += %w( src/core/lib/gpr/tls.h )
s.files += %w( src/core/lib/gpr/tls_gcc.h )
@@ -209,11 +209,11 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h )
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h )
+ s.files += %w( src/core/lib/security/security_connector/security_connector.h )
s.files += %w( src/core/lib/security/transport/auth_filters.h )
- s.files += %w( src/core/lib/security/transport/lb_targets_info.h )
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
- s.files += %w( src/core/lib/security/transport/security_connector.h )
s.files += %w( src/core/lib/security/transport/security_handshaker.h )
+ s.files += %w( src/core/lib/security/transport/target_authority_table.h )
s.files += %w( src/core/lib/security/transport/tsi_error.h )
s.files += %w( src/core/lib/security/util/json_util.h )
s.files += %w( src/core/tsi/alts_transport_security.h )
@@ -234,6 +234,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
+ s.files += %w( src/core/ext/filters/client_channel/method_params.h )
s.files += %w( src/core/ext/filters/client_channel/parse_address.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h )
@@ -241,6 +242,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h )
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
+ s.files += %w( src/core/ext/filters/client_channel/status_util.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/filters/client_channel/uri_parser.h )
@@ -347,6 +349,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/slice_hash_table.h )
s.files += %w( src/core/lib/slice/slice_internal.h )
s.files += %w( src/core/lib/slice/slice_string_helpers.h )
+ s.files += %w( src/core/lib/slice/slice_weak_hash_table.h )
s.files += %w( src/core/lib/surface/api_trace.h )
s.files += %w( src/core/lib/surface/call.h )
s.files += %w( src/core/lib/surface/call_test_only.h )
@@ -371,12 +374,12 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/service_config.h )
s.files += %w( src/core/lib/transport/static_metadata.h )
s.files += %w( src/core/lib/transport/status_conversion.h )
+ s.files += %w( src/core/lib/transport/status_metadata.h )
s.files += %w( src/core/lib/transport/timeout_encoding.h )
s.files += %w( src/core/lib/transport/transport.h )
s.files += %w( src/core/lib/transport/transport_impl.h )
s.files += %w( src/core/lib/debug/trace.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h )
- s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h )
@@ -498,7 +501,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/slice/percent_encoding.cc )
s.files += %w( src/core/lib/slice/slice.cc )
s.files += %w( src/core/lib/slice/slice_buffer.cc )
- s.files += %w( src/core/lib/slice/slice_hash_table.cc )
s.files += %w( src/core/lib/slice/slice_intern.cc )
s.files += %w( src/core/lib/slice/slice_string_helpers.cc )
s.files += %w( src/core/lib/surface/api_trace.cc )
@@ -529,6 +531,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/service_config.cc )
s.files += %w( src/core/lib/transport/static_metadata.cc )
s.files += %w( src/core/lib/transport/status_conversion.cc )
+ s.files += %w( src/core/lib/transport/status_metadata.cc )
s.files += %w( src/core/lib/transport/timeout_encoding.cc )
s.files += %w( src/core/lib/transport/transport.cc )
s.files += %w( src/core/lib/transport/transport_op_string.cc )
@@ -576,12 +579,12 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc )
s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc )
s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc )
+ s.files += %w( src/core/lib/security/security_connector/security_connector.cc )
s.files += %w( src/core/lib/security/transport/client_auth_filter.cc )
- s.files += %w( src/core/lib/security/transport/lb_targets_info.cc )
s.files += %w( src/core/lib/security/transport/secure_endpoint.cc )
- s.files += %w( src/core/lib/security/transport/security_connector.cc )
s.files += %w( src/core/lib/security/transport/security_handshaker.cc )
s.files += %w( src/core/lib/security/transport/server_auth_filter.cc )
+ s.files += %w( src/core/lib/security/transport/target_authority_table.cc )
s.files += %w( src/core/lib/security/transport/tsi_error.cc )
s.files += %w( src/core/lib/security/util/json_util.cc )
s.files += %w( src/core/lib/surface/init_secure.cc )
@@ -604,12 +607,14 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
+ s.files += %w( src/core/ext/filters/client_channel/method_params.cc )
s.files += %w( src/core/ext/filters/client_channel/parse_address.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc )
+ s.files += %w( src/core/ext/filters/client_channel/status_util.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc )
s.files += %w( src/core/ext/filters/client_channel/uri_parser.cc )
@@ -657,20 +662,80 @@ Gem::Specification.new do |s|
s.files += %w( third_party/boringssl/crypto/curve25519/internal.h )
s.files += %w( third_party/boringssl/crypto/err/internal.h )
s.files += %w( third_party/boringssl/crypto/evp/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/aes/aes.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/aes/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/add.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/asm/x86_64-gcc.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/bn.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/bytes.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/cmp.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/ctx.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/div.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/gcd.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/generic.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/jacobi.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/montgomery.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/mul.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/prime.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/random.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/shift.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/bn/sqrt.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/cipher/aead.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/cipher/cipher.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/cipher/e_des.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/cipher/internal.h )
s.files += %w( third_party/boringssl/crypto/fipsmodule/delocate.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/des/des.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/des/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/digest/digest.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/digest/digests.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/digest/internal.h )
s.files += %w( third_party/boringssl/crypto/fipsmodule/digest/md32_common.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/ec.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/ec_key.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/oct.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/p224-64.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/p256-64.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/simple.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/util-64.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ec/wnaf.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/hmac/hmac.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/md4/md4.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/md5/md5.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/cbc.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/cfb.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/ctr.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/gcm.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/ofb.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/modes/polyval.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/rand/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rand/rand.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rand/urandom.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rsa/blinding.c )
s.files += %w( third_party/boringssl/crypto/fipsmodule/rsa/internal.h )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rsa/padding.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rsa/rsa.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/sha/sha1-altivec.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/sha/sha1.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/sha/sha256.c )
+ s.files += %w( third_party/boringssl/crypto/fipsmodule/sha/sha512.c )
s.files += %w( third_party/boringssl/crypto/internal.h )
s.files += %w( third_party/boringssl/crypto/obj/obj_dat.h )
s.files += %w( third_party/boringssl/crypto/pkcs7/internal.h )
diff --git a/grpc.gyp b/grpc.gyp
index 4c5dc8b9e3..ff3bbb4c29 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -323,7 +323,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@@ -354,6 +353,7 @@
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
+ 'src/core/lib/transport/status_metadata.cc',
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
@@ -401,12 +401,12 @@
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
+ 'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
- 'src/core/lib/security/transport/lb_targets_info.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
- 'src/core/lib/security/transport/security_connector.cc',
'src/core/lib/security/transport/security_handshaker.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
+ 'src/core/lib/security/transport/target_authority_table.cc',
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
@@ -429,12 +429,14 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
+ 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/status_util.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
@@ -623,7 +625,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@@ -654,6 +655,7 @@
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
+ 'src/core/lib/transport/status_metadata.cc',
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
@@ -669,12 +671,14 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
+ 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/status_util.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
@@ -841,7 +845,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@@ -872,6 +875,7 @@
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
+ 'src/core/lib/transport/status_metadata.cc',
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
@@ -887,12 +891,14 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
+ 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/status_util.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
@@ -1037,7 +1043,6 @@
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@@ -1068,6 +1073,7 @@
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
+ 'src/core/lib/transport/status_metadata.cc',
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
@@ -1116,12 +1122,14 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
+ 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/status_util.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
@@ -2492,6 +2500,21 @@
'test/core/end2end/tests/request_with_flags.cc',
'test/core/end2end/tests/request_with_payload.cc',
'test/core/end2end/tests/resource_quota_server.cc',
+ 'test/core/end2end/tests/retry.cc',
+ 'test/core/end2end/tests/retry_cancellation.cc',
+ 'test/core/end2end/tests/retry_disabled.cc',
+ 'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
+ 'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
+ 'test/core/end2end/tests/retry_non_retriable_status.cc',
+ 'test/core/end2end/tests/retry_recv_initial_metadata.cc',
+ 'test/core/end2end/tests/retry_recv_message.cc',
+ 'test/core/end2end/tests/retry_server_pushback_delay.cc',
+ 'test/core/end2end/tests/retry_server_pushback_disabled.cc',
+ 'test/core/end2end/tests/retry_streaming.cc',
+ 'test/core/end2end/tests/retry_streaming_after_commit.cc',
+ 'test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc',
+ 'test/core/end2end/tests/retry_throttled.cc',
+ 'test/core/end2end/tests/retry_too_many_attempts.cc',
'test/core/end2end/tests/server_finishes_request.cc',
'test/core/end2end/tests/shutdown_finishes_calls.cc',
'test/core/end2end/tests/shutdown_finishes_tags.cc',
@@ -2565,6 +2588,21 @@
'test/core/end2end/tests/request_with_flags.cc',
'test/core/end2end/tests/request_with_payload.cc',
'test/core/end2end/tests/resource_quota_server.cc',
+ 'test/core/end2end/tests/retry.cc',
+ 'test/core/end2end/tests/retry_cancellation.cc',
+ 'test/core/end2end/tests/retry_disabled.cc',
+ 'test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc',
+ 'test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc',
+ 'test/core/end2end/tests/retry_non_retriable_status.cc',
+ 'test/core/end2end/tests/retry_recv_initial_metadata.cc',
+ 'test/core/end2end/tests/retry_recv_message.cc',
+ 'test/core/end2end/tests/retry_server_pushback_delay.cc',
+ 'test/core/end2end/tests/retry_server_pushback_disabled.cc',
+ 'test/core/end2end/tests/retry_streaming.cc',
+ 'test/core/end2end/tests/retry_streaming_after_commit.cc',
+ 'test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc',
+ 'test/core/end2end/tests/retry_throttled.cc',
+ 'test/core/end2end/tests/retry_too_many_attempts.cc',
'test/core/end2end/tests/server_finishes_request.cc',
'test/core/end2end/tests/shutdown_finishes_calls.cc',
'test/core/end2end/tests/shutdown_finishes_tags.cc',
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index 37d4189201..dce742ee88 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,72 +16,13 @@
*
*/
-/// An Alarm posts the user provided tag to its associated completion queue upon
-/// expiry or cancellation.
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_ALARM_H
#define GRPCXX_ALARM_H
-#include <grpc++/impl/codegen/completion_queue.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/codegen/grpc_library.h>
-#include <grpc++/impl/codegen/time.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc/grpc.h>
-
-namespace grpc {
-
-/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
-class Alarm : private GrpcLibraryCodegen {
- public:
- /// Create an unset completion queue alarm
- Alarm();
-
- /// Destroy the given completion queue alarm, cancelling it in the process.
- ~Alarm();
-
- /// DEPRECATED: Create and set a completion queue alarm instance associated to
- /// \a cq.
- /// This form is deprecated because it is inherently racy.
- /// \internal We rely on the presence of \a cq for grpc initialization. If \a
- /// cq were ever to be removed, a reference to a static
- /// internal::GrpcLibraryInitializer instance would need to be introduced
- /// here. \endinternal.
- template <typename T>
- Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() {
- SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
- }
-
- /// Trigger an alarm instance on completion queue \a cq at the specified time.
- /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
- /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
- /// event's success bit will be true, false otherwise (ie, upon cancellation).
- template <typename T>
- void Set(CompletionQueue* cq, const T& deadline, void* tag) {
- SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
- }
-
- /// Alarms aren't copyable.
- Alarm(const Alarm&) = delete;
- Alarm& operator=(const Alarm&) = delete;
-
- /// Alarms are movable.
- Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
- Alarm& operator=(Alarm&& rhs) {
- alarm_ = rhs.alarm_;
- rhs.alarm_ = nullptr;
- return *this;
- }
-
- /// Cancel a completion queue alarm. Calling this function over an alarm that
- /// has already fired has no effect.
- void Cancel();
-
- private:
- void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag);
-
- internal::CompletionQueueTag* alarm_;
-};
-
-} // namespace grpc
+#include <grpcpp/alarm.h>
#endif // GRPCXX_ALARM_H
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index e9fb5a5d09..b1154cefb3 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,63 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_CHANNEL_H
#define GRPCXX_CHANNEL_H
-#include <memory>
-
-#include <grpc++/impl/call.h>
-#include <grpc++/impl/codegen/channel_interface.h>
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/grpc_library.h>
-#include <grpc/grpc.h>
-
-struct grpc_channel;
-
-namespace grpc {
-/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
-class Channel final : public ChannelInterface,
- public internal::CallHook,
- public std::enable_shared_from_this<Channel>,
- private GrpcLibraryCodegen {
- public:
- ~Channel();
-
- /// Get the current channel state. If the channel is in IDLE and
- /// \a try_to_connect is set to true, try to connect.
- grpc_connectivity_state GetState(bool try_to_connect) override;
-
- /// Returns the LB policy name, or the empty string if not yet available.
- grpc::string GetLoadBalancingPolicyName() const;
-
- /// Returns the service config in JSON form, or the empty string if
- /// not available.
- grpc::string GetServiceConfigJSON() const;
-
- private:
- template <class InputMessage, class OutputMessage>
- friend class internal::BlockingUnaryCallImpl;
- friend std::shared_ptr<Channel> CreateChannelInternal(
- const grpc::string& host, grpc_channel* c_channel);
- Channel(const grpc::string& host, grpc_channel* c_channel);
-
- internal::Call CreateCall(const internal::RpcMethod& method,
- ClientContext* context,
- CompletionQueue* cq) override;
- void PerformOpsOnCall(internal::CallOpSetInterface* ops,
- internal::Call* call) override;
- void* RegisterMethod(const char* method) override;
-
- void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
- gpr_timespec deadline, CompletionQueue* cq,
- void* tag) override;
- bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
- gpr_timespec deadline) override;
-
- const grpc::string host_;
- grpc_channel* const c_channel_; // owned
-};
-
-} // namespace grpc
+#include <grpcpp/channel.h>
#endif // GRPCXX_CHANNEL_H
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index cf42a627ad..4b23644059 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,24 +16,13 @@
*
*/
-/// A ClientContext allows the person implementing a service client to:
-///
-/// - Add custom metadata key-value pairs that will propagated to the server
-/// side.
-/// - Control call settings such as compression and authentication.
-/// - Initial and trailing metadata coming from the server.
-/// - Get performance metrics (ie, census).
-///
-/// Context settings are only relevant to the call they are invoked with, that
-/// is to say, they aren't sticky. Some of these settings, such as the
-/// compression options, can be made persistant at channel construction time
-/// (see \a grpc::CreateCustomChannel).
-///
-/// \warning ClientContext instances should \em not be reused across rpcs.
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
#ifndef GRPCXX_CLIENT_CONTEXT_H
#define GRPCXX_CLIENT_CONTEXT_H
-#include <grpc++/impl/codegen/client_context.h>
+#include <grpcpp/client_context.h>
#endif // GRPCXX_CLIENT_CONTEXT_H
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index a71123e0af..98ef18f0f6 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_COMPLETION_QUEUE_H
#define GRPCXX_COMPLETION_QUEUE_H
-#include <grpc++/impl/codegen/completion_queue.h>
+#include <grpcpp/completion_queue.h>
#endif // GRPCXX_COMPLETION_QUEUE_H
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 7ba1131a5f..d95f3a9797 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,43 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_CREATE_CHANNEL_H
#define GRPCXX_CREATE_CHANNEL_H
-#include <memory>
-
-#include <grpc++/channel.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/support/channel_arguments.h>
-#include <grpc++/support/config.h>
-
-namespace grpc {
-
-/// Create a new \a Channel pointing to \a target.
-///
-/// \param target The URI of the endpoint to connect to.
-/// \param creds Credentials to use for the created channel. If it does not
-/// hold an object or is invalid, a lame channel (one on which all operations
-/// fail) is returned.
-std::shared_ptr<Channel> CreateChannel(
- const grpc::string& target,
- const std::shared_ptr<ChannelCredentials>& creds);
-
-/// Create a new \em custom \a Channel pointing to \a target.
-///
-/// \warning For advanced use and testing ONLY. Override default channel
-/// arguments only if necessary.
-///
-/// \param target The URI of the endpoint to connect to.
-/// \param creds Credentials to use for the created channel. If it does not
-/// hold an object or is invalid, a lame channel (one on which all operations
-/// fail) is returned.
-/// \param args Options for channel creation.
-std::shared_ptr<Channel> CreateCustomChannel(
- const grpc::string& target,
- const std::shared_ptr<ChannelCredentials>& creds,
- const ChannelArguments& args);
-
-} // namespace grpc
+#include <grpcpp/create_channel.h>
#endif // GRPCXX_CREATE_CHANNEL_H
diff --git a/include/grpc++/create_channel_posix.h b/include/grpc++/create_channel_posix.h
index 10f7e4a60e..8c8983ba60 100644
--- a/include/grpc++/create_channel_posix.h
+++ b/include/grpc++/create_channel_posix.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,37 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_CREATE_CHANNEL_POSIX_H
#define GRPCXX_CREATE_CHANNEL_POSIX_H
-#include <memory>
-
-#include <grpc++/channel.h>
-#include <grpc++/support/channel_arguments.h>
-#include <grpc/support/port_platform.h>
-
-namespace grpc {
-
-#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
-
-/// Create a new \a Channel communicating over the given file descriptor.
-///
-/// \param target The name of the target.
-/// \param fd The file descriptor representing a socket.
-std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
- int fd);
-
-/// Create a new \a Channel communicating over given file descriptor with custom
-/// channel arguments.
-///
-/// \param target The name of the target.
-/// \param fd The file descriptor representing a socket.
-/// \param args Options for channel creation.
-std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
- const grpc::string& target, int fd, const ChannelArguments& args);
-
-#endif // GPR_SUPPORT_CHANNELS_FROM_FD
-
-} // namespace grpc
+#include <grpcpp/create_channel_posix.h>
#endif // GRPCXX_CREATE_CHANNEL_POSIX_H
diff --git a/include/grpc++/ext/health_check_service_server_builder_option.h b/include/grpc++/ext/health_check_service_server_builder_option.h
index 89af294aa9..cb82fc03b6 100644
--- a/include/grpc++/ext/health_check_service_server_builder_option.h
+++ b/include/grpc++/ext/health_check_service_server_builder_option.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,32 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
#define GRPCXX_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
-#include <memory>
-
-#include <grpc++/health_check_service_interface.h>
-#include <grpc++/impl/server_builder_option.h>
-#include <grpc++/support/config.h>
-
-namespace grpc {
-
-class HealthCheckServiceServerBuilderOption : public ServerBuilderOption {
- public:
- /// The ownership of \a hc will be taken and transferred to the grpc server.
- /// To explicitly disable default service, pass in a nullptr.
- explicit HealthCheckServiceServerBuilderOption(
- std::unique_ptr<HealthCheckServiceInterface> hc);
- ~HealthCheckServiceServerBuilderOption() override {}
- void UpdateArguments(ChannelArguments* args) override;
- void UpdatePlugins(
- std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) override;
-
- private:
- std::unique_ptr<HealthCheckServiceInterface> hc_;
-};
-
-} // namespace grpc
+#include <grpcpp/ext/health_check_service_server_builder_option.h>
#endif // GRPCXX_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
diff --git a/include/grpc++/ext/proto_server_reflection_plugin.h b/include/grpc++/ext/proto_server_reflection_plugin.h
index ee3fafd7da..02e21b9219 100644
--- a/include/grpc++/ext/proto_server_reflection_plugin.h
+++ b/include/grpc++/ext/proto_server_reflection_plugin.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,39 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
#define GRPCXX_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
-#include <grpc++/impl/server_builder_plugin.h>
-#include <grpc++/support/config.h>
-
-namespace grpc {
-class ServerInitializer;
-class ProtoServerReflection;
-} // namespace grpc
-
-namespace grpc {
-namespace reflection {
-
-class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
- public:
- ProtoServerReflectionPlugin();
- ::grpc::string name() override;
- void InitServer(::grpc::ServerInitializer* si) override;
- void Finish(::grpc::ServerInitializer* si) override;
- void ChangeArguments(const ::grpc::string& name, void* value) override;
- bool has_async_methods() const override;
- bool has_sync_methods() const override;
-
- private:
- std::shared_ptr<grpc::ProtoServerReflection> reflection_service_;
-};
-
-/// Add proto reflection plugin to \a ServerBuilder.
-/// This function should be called at the static initialization time.
-void InitProtoReflectionServerBuilderPlugin();
-
-} // namespace reflection
-} // namespace grpc
+#include <grpcpp/ext/proto_server_reflection_plugin.h>
#endif // GRPCXX_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
diff --git a/include/grpc++/generic/async_generic_service.h b/include/grpc++/generic/async_generic_service.h
index b1ea4f3909..d3283fac6f 100644
--- a/include/grpc++/generic/async_generic_service.h
+++ b/include/grpc++/generic/async_generic_service.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,63 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_GENERIC_ASYNC_GENERIC_SERVICE_H
#define GRPCXX_GENERIC_ASYNC_GENERIC_SERVICE_H
-#include <grpc++/support/async_stream.h>
-#include <grpc++/support/byte_buffer.h>
-
-struct grpc_server;
-
-namespace grpc {
-
-typedef ServerAsyncReaderWriter<ByteBuffer, ByteBuffer>
- GenericServerAsyncReaderWriter;
-
-class GenericServerContext final : public ServerContext {
- public:
- const grpc::string& method() const { return method_; }
- const grpc::string& host() const { return host_; }
-
- private:
- friend class Server;
- friend class ServerInterface;
-
- grpc::string method_;
- grpc::string host_;
-};
-
-// A generic service at the server side accepts all RPC methods and hosts. It is
-// typically used in proxies. The generic service can be registered to a server
-// which also has other services.
-// Sample usage:
-// ServerBuilder builder;
-// auto cq = builder.AddCompletionQueue();
-// AsyncGenericService generic_service;
-// builder.RegisterAsyncGeneicService(&generic_service);
-// auto server = builder.BuildAndStart();
-//
-// // request a new call
-// GenericServerContext context;
-// GenericAsyncReaderWriter stream;
-// generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag);
-//
-// When tag is retrieved from cq->Next(), context.method() can be used to look
-// at the method and the RPC can be handled accordingly.
-class AsyncGenericService final {
- public:
- AsyncGenericService() : server_(nullptr) {}
-
- void RequestCall(GenericServerContext* ctx,
- GenericServerAsyncReaderWriter* reader_writer,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag);
-
- private:
- friend class Server;
- Server* server_;
-};
-
-} // namespace grpc
+#include <grpcpp/generic/async_generic_service.h>
#endif // GRPCXX_GENERIC_ASYNC_GENERIC_SERVICE_H
diff --git a/include/grpc++/generic/generic_stub.h b/include/grpc++/generic/generic_stub.h
index e72826bdc1..502953b5de 100644
--- a/include/grpc++/generic/generic_stub.h
+++ b/include/grpc++/generic/generic_stub.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,56 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_GENERIC_GENERIC_STUB_H
#define GRPCXX_GENERIC_GENERIC_STUB_H
-#include <grpc++/support/async_stream.h>
-#include <grpc++/support/async_unary_call.h>
-#include <grpc++/support/byte_buffer.h>
-
-namespace grpc {
-
-class CompletionQueue;
-typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
- GenericClientAsyncReaderWriter;
-typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
-
-/// Generic stubs provide a type-unsafe interface to call gRPC methods
-/// by name.
-class GenericStub final {
- public:
- explicit GenericStub(std::shared_ptr<ChannelInterface> channel)
- : channel_(channel) {}
-
- /// Setup a call to a named method \a method using \a context, but don't
- /// start it. Let it be started explicitly with StartCall and a tag.
- /// The return value only indicates whether or not registration of the call
- /// succeeded (i.e. the call won't proceed if the return value is nullptr).
- std::unique_ptr<GenericClientAsyncReaderWriter> PrepareCall(
- ClientContext* context, const grpc::string& method, CompletionQueue* cq);
-
- /// Setup a unary call to a named method \a method using \a context, and don't
- /// start it. Let it be started explicitly with StartCall.
- /// The return value only indicates whether or not registration of the call
- /// succeeded (i.e. the call won't proceed if the return value is nullptr).
- std::unique_ptr<GenericClientAsyncResponseReader> PrepareUnaryCall(
- ClientContext* context, const grpc::string& method,
- const ByteBuffer& request, CompletionQueue* cq);
-
- /// DEPRECATED for multi-threaded use
- /// Begin a call to a named method \a method using \a context.
- /// A tag \a tag will be delivered to \a cq when the call has been started
- /// (i.e, initial metadata has been sent).
- /// The return value only indicates whether or not registration of the call
- /// succeeded (i.e. the call won't proceed if the return value is nullptr).
- std::unique_ptr<GenericClientAsyncReaderWriter> Call(
- ClientContext* context, const grpc::string& method, CompletionQueue* cq,
- void* tag);
-
- private:
- std::shared_ptr<ChannelInterface> channel_;
-};
-
-} // namespace grpc
+#include <grpcpp/generic/generic_stub.h>
#endif // GRPCXX_GENERIC_GENERIC_STUB_H
diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h
index 31ed436c5e..9f1d7b1bc1 100644
--- a/include/grpc++/grpc++.h
+++ b/include/grpc++/grpc++.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,53 +16,13 @@
*
*/
-/// \mainpage gRPC C++ API
-///
-/// The gRPC C++ API mainly consists of the following classes:
-/// <br>
-/// - grpc::Channel, which represents the connection to an endpoint. See [the
-/// gRPC Concepts page](https://grpc.io/docs/guides/concepts.html) for more
-/// details. Channels are created by the factory function grpc::CreateChannel.
-///
-/// - grpc::CompletionQueue, the producer-consumer queue used for all
-/// asynchronous communication with the gRPC runtime.
-///
-/// - grpc::ClientContext and grpc::ServerContext, where optional configuration
-/// for an RPC can be set, such as setting custom metadata to be conveyed to the
-/// peer, compression settings, authentication, etc.
-///
-/// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder.
-///
-/// Streaming calls are handled with the streaming classes in
-/// \ref sync_stream.h and
-/// \ref async_stream.h.
-///
-/// Refer to the
-/// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp)
-/// for code putting these pieces into play.
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
#ifndef GRPCXX_GRPCXX_H
#define GRPCXX_GRPCXX_H
-// Pragma for http://include-what-you-use.org/ tool, tells that following
-// headers are not private for grpc++.h and are part of its interface.
-// IWYU pragma: begin_exports
-#include <grpc/grpc.h>
-
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/create_channel_posix.h>
-#include <grpc++/server.h>
-#include <grpc++/server_builder.h>
-#include <grpc++/server_context.h>
-#include <grpc++/server_posix.h>
-// IWYU pragma: end_exports
-
-namespace grpc {
-/// Return gRPC library version.
-grpc::string Version();
-} // namespace grpc
+#include <grpcpp/grpcpp.h>
#endif // GRPCXX_GRPCXX_H
diff --git a/include/grpc++/health_check_service_interface.h b/include/grpc++/health_check_service_interface.h
index 7d4d36abb9..0cb0668e48 100644
--- a/include/grpc++/health_check_service_interface.h
+++ b/include/grpc++/health_check_service_interface.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,39 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_HEALTH_CHECK_SERVICE_INTERFACE_H
#define GRPCXX_HEALTH_CHECK_SERVICE_INTERFACE_H
-#include <grpc++/support/config.h>
-
-namespace grpc {
-
-const char kHealthCheckServiceInterfaceArg[] =
- "grpc.health_check_service_interface";
-
-/// The gRPC server uses this interface to expose the health checking service
-/// without depending on protobuf.
-class HealthCheckServiceInterface {
- public:
- virtual ~HealthCheckServiceInterface() {}
-
- /// Set or change the serving status of the given \a service_name.
- virtual void SetServingStatus(const grpc::string& service_name,
- bool serving) = 0;
- /// Apply to all registered service names.
- virtual void SetServingStatus(bool serving) = 0;
-};
-
-/// Enable/disable the default health checking service. This applies to all C++
-/// servers created afterwards. For each server, user can override the default
-/// with a HealthCheckServiceServerBuilderOption.
-/// NOT thread safe.
-void EnableDefaultHealthCheckService(bool enable);
-
-/// Returns whether the default health checking service is enabled.
-/// NOT thread safe.
-bool DefaultHealthCheckServiceEnabled();
-
-} // namespace grpc
+#include <grpcpp/health_check_service_interface.h>
#endif // GRPCXX_HEALTH_CHECK_SERVICE_INTERFACE_H
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index fceaa3b0f9..b1da2b6358 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CALL_H
#define GRPCXX_IMPL_CALL_H
-#include <grpc++/impl/codegen/call.h>
+#include <grpcpp/impl/call.h>
#endif // GRPCXX_IMPL_CALL_H
diff --git a/include/grpc++/impl/channel_argument_option.h b/include/grpc++/impl/channel_argument_option.h
index f157ec1d7e..3468378de6 100644
--- a/include/grpc++/impl/channel_argument_option.h
+++ b/include/grpc++/impl/channel_argument_option.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2017 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,22 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
#define GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
-#include <map>
-#include <memory>
-
-#include <grpc++/impl/server_builder_option.h>
-#include <grpc++/support/channel_arguments.h>
-
-namespace grpc {
-
-std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
- const grpc::string& name, const grpc::string& value);
-std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
- const grpc::string& name, int value);
-
-} // namespace grpc
+#include <grpcpp/impl/channel_argument_option.h>
#endif // GRPCXX_IMPL_CHANNEL_ARGUMENT_OPTION_H
diff --git a/include/grpc++/impl/client_unary_call.h b/include/grpc++/impl/client_unary_call.h
index d679727907..75e656071f 100644
--- a/include/grpc++/impl/client_unary_call.h
+++ b/include/grpc++/impl/client_unary_call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CLIENT_UNARY_CALL_H
#define GRPCXX_IMPL_CLIENT_UNARY_CALL_H
-#include <grpc++/impl/codegen/client_unary_call.h>
+#include <grpcpp/impl/client_unary_call.h>
#endif // GRPCXX_IMPL_CLIENT_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h
index 4476033463..a034470a70 100644
--- a/include/grpc++/impl/codegen/async_stream.h
+++ b/include/grpc++/impl/codegen/async_stream.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,1053 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
#define GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
-#include <grpc++/impl/codegen/call.h>
-#include <grpc++/impl/codegen/channel_interface.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/server_context.h>
-#include <grpc++/impl/codegen/service_type.h>
-#include <grpc++/impl/codegen/status.h>
-
-namespace grpc {
-
-class CompletionQueue;
-
-namespace internal {
-/// Common interface for all client side asynchronous streaming.
-class ClientAsyncStreamingInterface {
- public:
- virtual ~ClientAsyncStreamingInterface() {}
-
- /// Start the call that was set up by the constructor, but only if the
- /// constructor was invoked through the "Prepare" API which doesn't actually
- /// start the call
- virtual void StartCall(void* tag) = 0;
-
- /// Request notification of the reading of the initial metadata. Completion
- /// will be notified by \a tag on the associated completion queue.
- /// This call is optional, but if it is used, it cannot be used concurrently
- /// with or after the \a AsyncReaderInterface::Read method.
- ///
- /// \param[in] tag Tag identifying this request.
- virtual void ReadInitialMetadata(void* tag) = 0;
-
- /// Indicate that the stream is to be finished and request notification for
- /// when the call has been ended.
- /// Should not be used concurrently with other operations.
- ///
- /// It is appropriate to call this method when both:
- /// * the client side has no more message to send
- /// (this can be declared implicitly by calling this method, or
- /// explicitly through an earlier call to the <i>WritesDone</i> method
- /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or
- /// \a ClientAsyncReaderWriterInterface::WritesDone).
- /// * there are no more messages to be received from the server (this can
- /// be known implicitly by the calling code, or explicitly from an
- /// earlier call to \a AsyncReaderInterface::Read that yielded a failed
- /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
- ///
- /// This function will return when either:
- /// - all incoming messages have been read and the server has returned
- /// a status.
- /// - the server has returned a non-OK status.
- /// - the call failed for some reason and the library generated a
- /// status.
- ///
- /// Note that implementations of this method attempt to receive initial
- /// metadata from the server if initial metadata hasn't yet been received.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[out] status To be updated with the operation status.
- virtual void Finish(Status* status, void* tag) = 0;
-};
-
-/// An interface that yields a sequence of messages of type \a R.
-template <class R>
-class AsyncReaderInterface {
- public:
- virtual ~AsyncReaderInterface() {}
-
- /// Read a message of type \a R into \a msg. Completion will be notified by \a
- /// tag on the associated completion queue.
- /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
- /// should not be called concurrently with other streaming APIs
- /// on the same stream. It is not meaningful to call it concurrently
- /// with another \a AsyncReaderInterface::Read on the same stream since reads
- /// on the same stream are delivered in order.
- ///
- /// \param[out] msg Where to eventually store the read message.
- /// \param[in] tag The tag identifying the operation.
- ///
- /// Side effect: note that this method attempt to receive initial metadata for
- /// a stream if it hasn't yet been received.
- virtual void Read(R* msg, void* tag) = 0;
-};
-
-/// An interface that can be fed a sequence of messages of type \a W.
-template <class W>
-class AsyncWriterInterface {
- public:
- virtual ~AsyncWriterInterface() {}
-
- /// Request the writing of \a msg with identifying tag \a tag.
- ///
- /// Only one write may be outstanding at any given time. This means that
- /// after calling Write, one must wait to receive \a tag from the completion
- /// queue BEFORE calling Write again.
- /// This is thread-safe with respect to \a AsyncReaderInterface::Read
- ///
- /// \param[in] msg The message to be written.
- /// \param[in] tag The tag identifying the operation.
- virtual void Write(const W& msg, void* tag) = 0;
-
- /// Request the writing of \a msg using WriteOptions \a options with
- /// identifying tag \a tag.
- ///
- /// Only one write may be outstanding at any given time. This means that
- /// after calling Write, one must wait to receive \a tag from the completion
- /// queue BEFORE calling Write again.
- /// WriteOptions \a options is used to set the write options of this message.
- /// This is thread-safe with respect to \a AsyncReaderInterface::Read
- ///
- /// \param[in] msg The message to be written.
- /// \param[in] options The WriteOptions to be used to write this message.
- /// \param[in] tag The tag identifying the operation.
- virtual void Write(const W& msg, WriteOptions options, void* tag) = 0;
-
- /// Request the writing of \a msg and coalesce it with the writing
- /// of trailing metadata, using WriteOptions \a options with
- /// identifying tag \a tag.
- ///
- /// For client, WriteLast is equivalent of performing Write and
- /// WritesDone in a single step.
- /// For server, WriteLast buffers the \a msg. The writing of \a msg is held
- /// until Finish is called, where \a msg and trailing metadata are coalesced
- /// and write is initiated. Note that WriteLast can only buffer \a msg up to
- /// the flow control window size. If \a msg size is larger than the window
- /// size, it will be sent on wire without buffering.
- ///
- /// \param[in] msg The message to be written.
- /// \param[in] options The WriteOptions to be used to write this message.
- /// \param[in] tag The tag identifying the operation.
- void WriteLast(const W& msg, WriteOptions options, void* tag) {
- Write(msg, options.set_last_message(), tag);
- }
-};
-
-} // namespace internal
-
-template <class R>
-class ClientAsyncReaderInterface
- : public internal::ClientAsyncStreamingInterface,
- public internal::AsyncReaderInterface<R> {};
-
-namespace internal {
-template <class R>
-class ClientAsyncReaderFactory {
- public:
- /// Create a stream object.
- /// Write the first request out if \a start is set.
- /// \a tag will be notified on \a cq when the call has been started and
- /// \a request has been written out. If \a start is not set, \a tag must be
- /// nullptr and the actual call must be initiated by StartCall
- /// Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- template <class W>
- static ClientAsyncReader<R>* Create(ChannelInterface* channel,
- CompletionQueue* cq,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context, const W& request,
- bool start, void* tag) {
- ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
- return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncReader<R>)))
- ClientAsyncReader<R>(call, context, request, start, tag);
- }
-};
-} // namespace internal
-
-/// Async client-side API for doing server-streaming RPCs,
-/// where the incoming message stream coming from the server has
-/// messages of type \a R.
-template <class R>
-class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
- public:
- // always allocated against a call arena, no memory free required
- static void operator delete(void* ptr, std::size_t size) {
- assert(size == sizeof(ClientAsyncReader));
- }
-
- void StartCall(void* tag) override {
- assert(!started_);
- started_ = true;
- StartCallInternal(tag);
- }
-
- /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata
- /// method for semantics.
- ///
- /// Side effect:
- /// - upon receiving initial metadata from the server,
- /// the \a ClientContext associated with this call is updated, and the
- /// calling code can access the received metadata through the
- /// \a ClientContext.
- void ReadInitialMetadata(void* tag) override {
- assert(started_);
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- meta_ops_.set_output_tag(tag);
- meta_ops_.RecvInitialMetadata(context_);
- call_.PerformOps(&meta_ops_);
- }
-
- void Read(R* msg, void* tag) override {
- assert(started_);
- read_ops_.set_output_tag(tag);
- if (!context_->initial_metadata_received_) {
- read_ops_.RecvInitialMetadata(context_);
- }
- read_ops_.RecvMessage(msg);
- call_.PerformOps(&read_ops_);
- }
-
- /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
- ///
- /// Side effect:
- /// - the \a ClientContext associated with this call is updated with
- /// possible initial and trailing metadata received from the server.
- void Finish(Status* status, void* tag) override {
- assert(started_);
- finish_ops_.set_output_tag(tag);
- if (!context_->initial_metadata_received_) {
- finish_ops_.RecvInitialMetadata(context_);
- }
- finish_ops_.ClientRecvStatus(context_, status);
- call_.PerformOps(&finish_ops_);
- }
-
- private:
- friend class internal::ClientAsyncReaderFactory<R>;
- template <class W>
- ClientAsyncReader(::grpc::internal::Call call, ClientContext* context,
- const W& request, bool start, void* tag)
- : context_(context), call_(call), started_(start) {
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
- init_ops_.ClientSendClose();
- if (start) {
- StartCallInternal(tag);
- } else {
- assert(tag == nullptr);
- }
- }
-
- void StartCallInternal(void* tag) {
- init_ops_.SendInitialMetadata(context_->send_initial_metadata_,
- context_->initial_metadata_flags());
- init_ops_.set_output_tag(tag);
- call_.PerformOps(&init_ops_);
- }
-
- ClientContext* context_;
- ::grpc::internal::Call call_;
- bool started_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- init_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- meta_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpRecvMessage<R>>
- read_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpClientRecvStatus>
- finish_ops_;
-};
-
-/// Common interface for client side asynchronous writing.
-template <class W>
-class ClientAsyncWriterInterface
- : public internal::ClientAsyncStreamingInterface,
- public internal::AsyncWriterInterface<W> {
- public:
- /// Signal the client is done with the writes (half-close the client stream).
- /// Thread-safe with respect to \a AsyncReaderInterface::Read
- ///
- /// \param[in] tag The tag identifying the operation.
- virtual void WritesDone(void* tag) = 0;
-};
-
-namespace internal {
-template <class W>
-class ClientAsyncWriterFactory {
- public:
- /// Create a stream object.
- /// Start the RPC if \a start is set
- /// \a tag will be notified on \a cq when the call has been started (i.e.
- /// intitial metadata sent) and \a request has been written out.
- /// If \a start is not set, \a tag must be nullptr and the actual call
- /// must be initiated by StartCall
- /// Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- /// \a response will be filled in with the single expected response
- /// message from the server upon a successful call to the \a Finish
- /// method of this instance.
- template <class R>
- static ClientAsyncWriter<W>* Create(ChannelInterface* channel,
- CompletionQueue* cq,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context, R* response,
- bool start, void* tag) {
- ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
- return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncWriter<W>)))
- ClientAsyncWriter<W>(call, context, response, start, tag);
- }
-};
-} // namespace internal
-
-/// Async API on the client side for doing client-streaming RPCs,
-/// where the outgoing message stream going to the server contains
-/// messages of type \a W.
-template <class W>
-class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
- public:
- // always allocated against a call arena, no memory free required
- static void operator delete(void* ptr, std::size_t size) {
- assert(size == sizeof(ClientAsyncWriter));
- }
-
- void StartCall(void* tag) override {
- assert(!started_);
- started_ = true;
- StartCallInternal(tag);
- }
-
- /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for
- /// semantics.
- ///
- /// Side effect:
- /// - upon receiving initial metadata from the server, the \a ClientContext
- /// associated with this call is updated, and the calling code can access
- /// the received metadata through the \a ClientContext.
- void ReadInitialMetadata(void* tag) override {
- assert(started_);
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- meta_ops_.set_output_tag(tag);
- meta_ops_.RecvInitialMetadata(context_);
- call_.PerformOps(&meta_ops_);
- }
-
- void Write(const W& msg, void* tag) override {
- assert(started_);
- write_ops_.set_output_tag(tag);
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
- call_.PerformOps(&write_ops_);
- }
-
- void Write(const W& msg, WriteOptions options, void* tag) override {
- assert(started_);
- write_ops_.set_output_tag(tag);
- if (options.is_last_message()) {
- options.set_buffer_hint();
- write_ops_.ClientSendClose();
- }
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
- call_.PerformOps(&write_ops_);
- }
-
- void WritesDone(void* tag) override {
- assert(started_);
- write_ops_.set_output_tag(tag);
- write_ops_.ClientSendClose();
- call_.PerformOps(&write_ops_);
- }
-
- /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
- ///
- /// Side effect:
- /// - the \a ClientContext associated with this call is updated with
- /// possible initial and trailing metadata received from the server.
- /// - attempts to fill in the \a response parameter passed to this class's
- /// constructor with the server's response message.
- void Finish(Status* status, void* tag) override {
- assert(started_);
- finish_ops_.set_output_tag(tag);
- if (!context_->initial_metadata_received_) {
- finish_ops_.RecvInitialMetadata(context_);
- }
- finish_ops_.ClientRecvStatus(context_, status);
- call_.PerformOps(&finish_ops_);
- }
-
- private:
- friend class internal::ClientAsyncWriterFactory<W>;
- template <class R>
- ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context,
- R* response, bool start, void* tag)
- : context_(context), call_(call), started_(start) {
- finish_ops_.RecvMessage(response);
- finish_ops_.AllowNoMessage();
- if (start) {
- StartCallInternal(tag);
- } else {
- assert(tag == nullptr);
- }
- }
-
- void StartCallInternal(void* tag) {
- write_ops_.SendInitialMetadata(context_->send_initial_metadata_,
- context_->initial_metadata_flags());
- // if corked bit is set in context, we just keep the initial metadata
- // buffered up to coalesce with later message send. No op is performed.
- if (!context_->initial_metadata_corked_) {
- write_ops_.set_output_tag(tag);
- call_.PerformOps(&write_ops_);
- }
- }
-
- ClientContext* context_;
- ::grpc::internal::Call call_;
- bool started_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- meta_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- write_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpGenericRecvMessage,
- ::grpc::internal::CallOpClientRecvStatus>
- finish_ops_;
-};
-
-/// Async client-side interface for bi-directional streaming,
-/// where the client-to-server message stream has messages of type \a W,
-/// and the server-to-client message stream has messages of type \a R.
-template <class W, class R>
-class ClientAsyncReaderWriterInterface
- : public internal::ClientAsyncStreamingInterface,
- public internal::AsyncWriterInterface<W>,
- public internal::AsyncReaderInterface<R> {
- public:
- /// Signal the client is done with the writes (half-close the client stream).
- /// Thread-safe with respect to \a AsyncReaderInterface::Read
- ///
- /// \param[in] tag The tag identifying the operation.
- virtual void WritesDone(void* tag) = 0;
-};
-
-namespace internal {
-template <class W, class R>
-class ClientAsyncReaderWriterFactory {
- public:
- /// Create a stream object.
- /// Start the RPC request if \a start is set.
- /// \a tag will be notified on \a cq when the call has been started (i.e.
- /// intitial metadata sent). If \a start is not set, \a tag must be
- /// nullptr and the actual call must be initiated by StartCall
- /// Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- static ClientAsyncReaderWriter<W, R>* Create(
- ChannelInterface* channel, CompletionQueue* cq,
- const ::grpc::internal::RpcMethod& method, ClientContext* context,
- bool start, void* tag) {
- ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
-
- return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncReaderWriter<W, R>)))
- ClientAsyncReaderWriter<W, R>(call, context, start, tag);
- }
-};
-} // namespace internal
-
-/// Async client-side interface for bi-directional streaming,
-/// where the outgoing message stream going to the server
-/// has messages of type \a W, and the incoming message stream coming
-/// from the server has messages of type \a R.
-template <class W, class R>
-class ClientAsyncReaderWriter final
- : public ClientAsyncReaderWriterInterface<W, R> {
- public:
- // always allocated against a call arena, no memory free required
- static void operator delete(void* ptr, std::size_t size) {
- assert(size == sizeof(ClientAsyncReaderWriter));
- }
-
- void StartCall(void* tag) override {
- assert(!started_);
- started_ = true;
- StartCallInternal(tag);
- }
-
- /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method
- /// for semantics of this method.
- ///
- /// Side effect:
- /// - upon receiving initial metadata from the server, the \a ClientContext
- /// is updated with it, and then the receiving initial metadata can
- /// be accessed through this \a ClientContext.
- void ReadInitialMetadata(void* tag) override {
- assert(started_);
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- meta_ops_.set_output_tag(tag);
- meta_ops_.RecvInitialMetadata(context_);
- call_.PerformOps(&meta_ops_);
- }
-
- void Read(R* msg, void* tag) override {
- assert(started_);
- read_ops_.set_output_tag(tag);
- if (!context_->initial_metadata_received_) {
- read_ops_.RecvInitialMetadata(context_);
- }
- read_ops_.RecvMessage(msg);
- call_.PerformOps(&read_ops_);
- }
-
- void Write(const W& msg, void* tag) override {
- assert(started_);
- write_ops_.set_output_tag(tag);
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
- call_.PerformOps(&write_ops_);
- }
-
- void Write(const W& msg, WriteOptions options, void* tag) override {
- assert(started_);
- write_ops_.set_output_tag(tag);
- if (options.is_last_message()) {
- options.set_buffer_hint();
- write_ops_.ClientSendClose();
- }
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
- call_.PerformOps(&write_ops_);
- }
-
- void WritesDone(void* tag) override {
- assert(started_);
- write_ops_.set_output_tag(tag);
- write_ops_.ClientSendClose();
- call_.PerformOps(&write_ops_);
- }
-
- /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
- /// Side effect
- /// - the \a ClientContext associated with this call is updated with
- /// possible initial and trailing metadata sent from the server.
- void Finish(Status* status, void* tag) override {
- assert(started_);
- finish_ops_.set_output_tag(tag);
- if (!context_->initial_metadata_received_) {
- finish_ops_.RecvInitialMetadata(context_);
- }
- finish_ops_.ClientRecvStatus(context_, status);
- call_.PerformOps(&finish_ops_);
- }
-
- private:
- friend class internal::ClientAsyncReaderWriterFactory<W, R>;
- ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context,
- bool start, void* tag)
- : context_(context), call_(call), started_(start) {
- if (start) {
- StartCallInternal(tag);
- } else {
- assert(tag == nullptr);
- }
- }
-
- void StartCallInternal(void* tag) {
- write_ops_.SendInitialMetadata(context_->send_initial_metadata_,
- context_->initial_metadata_flags());
- // if corked bit is set in context, we just keep the initial metadata
- // buffered up to coalesce with later message send. No op is performed.
- if (!context_->initial_metadata_corked_) {
- write_ops_.set_output_tag(tag);
- call_.PerformOps(&write_ops_);
- }
- }
-
- ClientContext* context_;
- ::grpc::internal::Call call_;
- bool started_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- meta_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpRecvMessage<R>>
- read_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- write_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpClientRecvStatus>
- finish_ops_;
-};
-
-template <class W, class R>
-class ServerAsyncReaderInterface
- : public internal::ServerAsyncStreamingInterface,
- public internal::AsyncReaderInterface<R> {
- public:
- /// Indicate that the stream is to be finished with a certain status code
- /// and also send out \a msg response to the client.
- /// Request notification for when the server has sent the response and the
- /// appropriate signals to the client to end the call.
- /// Should not be used concurrently with other operations.
- ///
- /// It is appropriate to call this method when:
- /// * all messages from the client have been received (either known
- /// implictly, or explicitly because a previous
- /// \a AsyncReaderInterface::Read operation with a non-ok result,
- /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
- ///
- /// This operation will end when the server has finished sending out initial
- /// metadata (if not sent already), response message, and status, or if
- /// some failure occurred when trying to do so.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[in] status To be sent to the client as the result of this call.
- /// \param[in] msg To be sent to the client as the response for this call.
- virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
-
- /// Indicate that the stream is to be finished with a certain
- /// non-OK status code.
- /// Request notification for when the server has sent the appropriate
- /// signals to the client to end the call.
- /// Should not be used concurrently with other operations.
- ///
- /// This call is meant to end the call with some error, and can be called at
- /// any point that the server would like to "fail" the call (though note
- /// this shouldn't be called concurrently with any other "sending" call, like
- /// \a AsyncWriterInterface::Write).
- ///
- /// This operation will end when the server has finished sending out initial
- /// metadata (if not sent already), and status, or if some failure occurred
- /// when trying to do so.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[in] status To be sent to the client as the result of this call.
- /// - Note: \a status must have a non-OK code.
- virtual void FinishWithError(const Status& status, void* tag) = 0;
-};
-
-/// Async server-side API for doing client-streaming RPCs,
-/// where the incoming message stream from the client has messages of type \a R,
-/// and the single response message sent from the server is type \a W.
-template <class W, class R>
-class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
- public:
- explicit ServerAsyncReader(ServerContext* ctx)
- : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
-
- /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
- ///
- /// Implicit input parameter:
- /// - The initial metadata that will be sent to the client from this op will
- /// be taken from the \a ServerContext associated with the call.
- void SendInitialMetadata(void* tag) override {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- meta_ops_.set_output_tag(tag);
- meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- meta_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_.PerformOps(&meta_ops_);
- }
-
- void Read(R* msg, void* tag) override {
- read_ops_.set_output_tag(tag);
- read_ops_.RecvMessage(msg);
- call_.PerformOps(&read_ops_);
- }
-
- /// See the \a ServerAsyncReaderInterface.Read method for semantics
- ///
- /// Side effect:
- /// - also sends initial metadata if not alreay sent.
- /// - uses the \a ServerContext associated with this call to send possible
- /// initial and trailing metadata.
- ///
- /// Note: \a msg is not sent if \a status has a non-OK code.
- void Finish(const W& msg, const Status& status, void* tag) override {
- finish_ops_.set_output_tag(tag);
- if (!ctx_->sent_initial_metadata_) {
- finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- finish_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- // The response is dropped if the status is not OK.
- if (status.ok()) {
- finish_ops_.ServerSendStatus(ctx_->trailing_metadata_,
- finish_ops_.SendMessage(msg));
- } else {
- finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
- }
- call_.PerformOps(&finish_ops_);
- }
-
- /// See the \a ServerAsyncReaderInterface.Read method for semantics
- ///
- /// Side effect:
- /// - also sends initial metadata if not alreay sent.
- /// - uses the \a ServerContext associated with this call to send possible
- /// initial and trailing metadata.
- void FinishWithError(const Status& status, void* tag) override {
- GPR_CODEGEN_ASSERT(!status.ok());
- finish_ops_.set_output_tag(tag);
- if (!ctx_->sent_initial_metadata_) {
- finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- finish_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
- call_.PerformOps(&finish_ops_);
- }
-
- private:
- void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
-
- ::grpc::internal::Call call_;
- ServerContext* ctx_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
- meta_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpServerSendStatus>
- finish_ops_;
-};
-
-template <class W>
-class ServerAsyncWriterInterface
- : public internal::ServerAsyncStreamingInterface,
- public internal::AsyncWriterInterface<W> {
- public:
- /// Indicate that the stream is to be finished with a certain status code.
- /// Request notification for when the server has sent the appropriate
- /// signals to the client to end the call.
- /// Should not be used concurrently with other operations.
- ///
- /// It is appropriate to call this method when either:
- /// * all messages from the client have been received (either known
- /// implictly, or explicitly because a previous \a
- /// AsyncReaderInterface::Read operation with a non-ok
- /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'.
- /// * it is desired to end the call early with some non-OK status code.
- ///
- /// This operation will end when the server has finished sending out initial
- /// metadata (if not sent already), response message, and status, or if
- /// some failure occurred when trying to do so.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[in] status To be sent to the client as the result of this call.
- virtual void Finish(const Status& status, void* tag) = 0;
-
- /// Request the writing of \a msg and coalesce it with trailing metadata which
- /// contains \a status, using WriteOptions options with
- /// identifying tag \a tag.
- ///
- /// WriteAndFinish is equivalent of performing WriteLast and Finish
- /// in a single step.
- ///
- /// \param[in] msg The message to be written.
- /// \param[in] options The WriteOptions to be used to write this message.
- /// \param[in] status The Status that server returns to client.
- /// \param[in] tag The tag identifying the operation.
- virtual void WriteAndFinish(const W& msg, WriteOptions options,
- const Status& status, void* tag) = 0;
-};
-
-/// Async server-side API for doing server streaming RPCs,
-/// where the outgoing message stream from the server has messages of type \a W.
-template <class W>
-class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
- public:
- explicit ServerAsyncWriter(ServerContext* ctx)
- : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
-
- /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
- ///
- /// Implicit input parameter:
- /// - The initial metadata that will be sent to the client from this op will
- /// be taken from the \a ServerContext associated with the call.
- ///
- /// \param[in] tag Tag identifying this request.
- void SendInitialMetadata(void* tag) override {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- meta_ops_.set_output_tag(tag);
- meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- meta_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_.PerformOps(&meta_ops_);
- }
-
- void Write(const W& msg, void* tag) override {
- write_ops_.set_output_tag(tag);
- EnsureInitialMetadataSent(&write_ops_);
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
- call_.PerformOps(&write_ops_);
- }
-
- void Write(const W& msg, WriteOptions options, void* tag) override {
- write_ops_.set_output_tag(tag);
- if (options.is_last_message()) {
- options.set_buffer_hint();
- }
-
- EnsureInitialMetadataSent(&write_ops_);
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
- call_.PerformOps(&write_ops_);
- }
-
- /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics.
- ///
- /// Implicit input parameter:
- /// - the \a ServerContext associated with this call is used
- /// for sending trailing (and initial) metadata to the client.
- ///
- /// Note: \a status must have an OK code.
- void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
- void* tag) override {
- write_ops_.set_output_tag(tag);
- EnsureInitialMetadataSent(&write_ops_);
- options.set_buffer_hint();
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
- write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
- call_.PerformOps(&write_ops_);
- }
-
- /// See the \a ServerAsyncWriterInterface.Finish method for semantics.
- ///
- /// Implicit input parameter:
- /// - the \a ServerContext associated with this call is used for sending
- /// trailing (and initial if not already sent) metadata to the client.
- ///
- /// Note: there are no restrictions are the code of
- /// \a status,it may be non-OK
- void Finish(const Status& status, void* tag) override {
- finish_ops_.set_output_tag(tag);
- EnsureInitialMetadataSent(&finish_ops_);
- finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
- call_.PerformOps(&finish_ops_);
- }
-
- private:
- void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
-
- template <class T>
- void EnsureInitialMetadataSent(T* ops) {
- if (!ctx_->sent_initial_metadata_) {
- ops->SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ops->set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- }
-
- ::grpc::internal::Call call_;
- ServerContext* ctx_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
- meta_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpServerSendStatus>
- write_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpServerSendStatus>
- finish_ops_;
-};
-
-/// Server-side interface for asynchronous bi-directional streaming.
-template <class W, class R>
-class ServerAsyncReaderWriterInterface
- : public internal::ServerAsyncStreamingInterface,
- public internal::AsyncWriterInterface<W>,
- public internal::AsyncReaderInterface<R> {
- public:
- /// Indicate that the stream is to be finished with a certain status code.
- /// Request notification for when the server has sent the appropriate
- /// signals to the client to end the call.
- /// Should not be used concurrently with other operations.
- ///
- /// It is appropriate to call this method when either:
- /// * all messages from the client have been received (either known
- /// implictly, or explicitly because a previous \a
- /// AsyncReaderInterface::Read operation
- /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok'
- /// with 'false'.
- /// * it is desired to end the call early with some non-OK status code.
- ///
- /// This operation will end when the server has finished sending out initial
- /// metadata (if not sent already), response message, and status, or if some
- /// failure occurred when trying to do so.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[in] status To be sent to the client as the result of this call.
- virtual void Finish(const Status& status, void* tag) = 0;
-
- /// Request the writing of \a msg and coalesce it with trailing metadata which
- /// contains \a status, using WriteOptions options with
- /// identifying tag \a tag.
- ///
- /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
- /// single step.
- ///
- /// \param[in] msg The message to be written.
- /// \param[in] options The WriteOptions to be used to write this message.
- /// \param[in] status The Status that server returns to client.
- /// \param[in] tag The tag identifying the operation.
- virtual void WriteAndFinish(const W& msg, WriteOptions options,
- const Status& status, void* tag) = 0;
-};
-
-/// Async server-side API for doing bidirectional streaming RPCs,
-/// where the incoming message stream coming from the client has messages of
-/// type \a R, and the outgoing message stream coming from the server has
-/// messages of type \a W.
-template <class W, class R>
-class ServerAsyncReaderWriter final
- : public ServerAsyncReaderWriterInterface<W, R> {
- public:
- explicit ServerAsyncReaderWriter(ServerContext* ctx)
- : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
-
- /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
- ///
- /// Implicit input parameter:
- /// - The initial metadata that will be sent to the client from this op will
- /// be taken from the \a ServerContext associated with the call.
- ///
- /// \param[in] tag Tag identifying this request.
- void SendInitialMetadata(void* tag) override {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- meta_ops_.set_output_tag(tag);
- meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- meta_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_.PerformOps(&meta_ops_);
- }
-
- void Read(R* msg, void* tag) override {
- read_ops_.set_output_tag(tag);
- read_ops_.RecvMessage(msg);
- call_.PerformOps(&read_ops_);
- }
-
- void Write(const W& msg, void* tag) override {
- write_ops_.set_output_tag(tag);
- EnsureInitialMetadataSent(&write_ops_);
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
- call_.PerformOps(&write_ops_);
- }
-
- void Write(const W& msg, WriteOptions options, void* tag) override {
- write_ops_.set_output_tag(tag);
- if (options.is_last_message()) {
- options.set_buffer_hint();
- }
- EnsureInitialMetadataSent(&write_ops_);
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
- call_.PerformOps(&write_ops_);
- }
-
- /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish
- /// method for semantics.
- ///
- /// Implicit input parameter:
- /// - the \a ServerContext associated with this call is used
- /// for sending trailing (and initial) metadata to the client.
- ///
- /// Note: \a status must have an OK code.
- void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
- void* tag) override {
- write_ops_.set_output_tag(tag);
- EnsureInitialMetadataSent(&write_ops_);
- options.set_buffer_hint();
- GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
- write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
- call_.PerformOps(&write_ops_);
- }
-
- /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics.
- ///
- /// Implicit input parameter:
- /// - the \a ServerContext associated with this call is used for sending
- /// trailing (and initial if not already sent) metadata to the client.
- ///
- /// Note: there are no restrictions are the code of \a status,
- /// it may be non-OK
- void Finish(const Status& status, void* tag) override {
- finish_ops_.set_output_tag(tag);
- EnsureInitialMetadataSent(&finish_ops_);
-
- finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
- call_.PerformOps(&finish_ops_);
- }
-
- private:
- friend class ::grpc::Server;
-
- void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
-
- template <class T>
- void EnsureInitialMetadataSent(T* ops) {
- if (!ctx_->sent_initial_metadata_) {
- ops->SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ops->set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- }
-
- ::grpc::internal::Call call_;
- ServerContext* ctx_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
- meta_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpServerSendStatus>
- write_ops_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpServerSendStatus>
- finish_ops_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/async_stream.h>
#endif // GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index fb573004cb..2b08920a30 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,294 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
#define GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
-#include <assert.h>
-#include <grpc++/impl/codegen/call.h>
-#include <grpc++/impl/codegen/channel_interface.h>
-#include <grpc++/impl/codegen/client_context.h>
-#include <grpc++/impl/codegen/server_context.h>
-#include <grpc++/impl/codegen/service_type.h>
-#include <grpc++/impl/codegen/status.h>
-
-namespace grpc {
-
-class CompletionQueue;
-extern CoreCodegenInterface* g_core_codegen_interface;
-
-/// An interface relevant for async client side unary RPCs (which send
-/// one request message to a server and receive one response message).
-template <class R>
-class ClientAsyncResponseReaderInterface {
- public:
- virtual ~ClientAsyncResponseReaderInterface() {}
-
- /// Start the call that was set up by the constructor, but only if the
- /// constructor was invoked through the "Prepare" API which doesn't actually
- /// start the call
- virtual void StartCall() = 0;
-
- /// Request notification of the reading of initial metadata. Completion
- /// will be notified by \a tag on the associated completion queue.
- /// This call is optional, but if it is used, it cannot be used concurrently
- /// with or after the \a Finish method.
- ///
- /// \param[in] tag Tag identifying this request.
- virtual void ReadInitialMetadata(void* tag) = 0;
-
- /// Request to receive the server's response \a msg and final \a status for
- /// the call, and to notify \a tag on this call's completion queue when
- /// finished.
- ///
- /// This function will return when either:
- /// - when the server's response message and status have been received.
- /// - when the server has returned a non-OK status (no message expected in
- /// this case).
- /// - when the call failed for some reason and the library generated a
- /// non-OK status.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[out] status To be updated with the operation status.
- /// \param[out] msg To be filled in with the server's response message.
- virtual void Finish(R* msg, Status* status, void* tag) = 0;
-};
-
-namespace internal {
-template <class R>
-class ClientAsyncResponseReaderFactory {
- public:
- /// Start a call and write the request out if \a start is set.
- /// \a tag will be notified on \a cq when the call has been started (i.e.
- /// intitial metadata sent) and \a request has been written out.
- /// If \a start is not set, the actual call must be initiated by StartCall
- /// Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- template <class W>
- static ClientAsyncResponseReader<R>* Create(
- ChannelInterface* channel, CompletionQueue* cq,
- const ::grpc::internal::RpcMethod& method, ClientContext* context,
- const W& request, bool start) {
- ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
- return new (g_core_codegen_interface->grpc_call_arena_alloc(
- call.call(), sizeof(ClientAsyncResponseReader<R>)))
- ClientAsyncResponseReader<R>(call, context, request, start);
- }
-};
-} // namespace internal
-
-/// Async API for client-side unary RPCs, where the message response
-/// received from the server is of type \a R.
-template <class R>
-class ClientAsyncResponseReader final
- : public ClientAsyncResponseReaderInterface<R> {
- public:
- // always allocated against a call arena, no memory free required
- static void operator delete(void* ptr, std::size_t size) {
- assert(size == sizeof(ClientAsyncResponseReader));
- }
-
- // This operator should never be called as the memory should be freed as part
- // of the arena destruction. It only exists to provide a matching operator
- // delete to the operator new so that some compilers will not complain (see
- // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
- // there are no tests catching the compiler warning.
- static void operator delete(void*, void*) { assert(0); }
-
- void StartCall() override {
- assert(!started_);
- started_ = true;
- StartCallInternal();
- }
-
- /// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for
- /// semantics.
- ///
- /// Side effect:
- /// - the \a ClientContext associated with this call is updated with
- /// possible initial and trailing metadata sent from the server.
- void ReadInitialMetadata(void* tag) override {
- assert(started_);
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- meta_buf.set_output_tag(tag);
- meta_buf.RecvInitialMetadata(context_);
- call_.PerformOps(&meta_buf);
- }
-
- /// See \a ClientAysncResponseReaderInterface::Finish for semantics.
- ///
- /// Side effect:
- /// - the \a ClientContext associated with this call is updated with
- /// possible initial and trailing metadata sent from the server.
- void Finish(R* msg, Status* status, void* tag) override {
- assert(started_);
- finish_buf.set_output_tag(tag);
- if (!context_->initial_metadata_received_) {
- finish_buf.RecvInitialMetadata(context_);
- }
- finish_buf.RecvMessage(msg);
- finish_buf.AllowNoMessage();
- finish_buf.ClientRecvStatus(context_, status);
- call_.PerformOps(&finish_buf);
- }
-
- private:
- friend class internal::ClientAsyncResponseReaderFactory<R>;
- ClientContext* const context_;
- ::grpc::internal::Call call_;
- bool started_;
-
- template <class W>
- ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context,
- const W& request, bool start)
- : context_(context), call_(call), started_(start) {
- // Bind the metadata at time of StartCallInternal but set up the rest here
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(init_buf.SendMessage(request).ok());
- init_buf.ClientSendClose();
- if (start) StartCallInternal();
- }
-
- void StartCallInternal() {
- init_buf.SendInitialMetadata(context_->send_initial_metadata_,
- context_->initial_metadata_flags());
- call_.PerformOps(&init_buf);
- }
-
- // disable operator new
- static void* operator new(std::size_t size);
- static void* operator new(std::size_t size, void* p) { return p; }
-
- ::grpc::internal::SneakyCallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- init_buf;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- meta_buf;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpRecvMessage<R>,
- ::grpc::internal::CallOpClientRecvStatus>
- finish_buf;
-};
-
-/// Async server-side API for handling unary calls, where the single
-/// response message sent to the client is of type \a W.
-template <class W>
-class ServerAsyncResponseWriter final
- : public internal::ServerAsyncStreamingInterface {
- public:
- explicit ServerAsyncResponseWriter(ServerContext* ctx)
- : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
-
- /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
- ///
- /// Side effect:
- /// The initial metadata that will be sent to the client from this op will
- /// be taken from the \a ServerContext associated with the call.
- ///
- /// \param[in] tag Tag identifying this request.
- void SendInitialMetadata(void* tag) override {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- meta_buf_.set_output_tag(tag);
- meta_buf_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- meta_buf_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_.PerformOps(&meta_buf_);
- }
-
- /// Indicate that the stream is to be finished and request notification
- /// when the server has sent the appropriate signals to the client to
- /// end the call. Should not be used concurrently with other operations.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[in] status To be sent to the client as the result of the call.
- /// \param[in] msg Message to be sent to the client.
- ///
- /// Side effect:
- /// - also sends initial metadata if not already sent (using the
- /// \a ServerContext associated with this call).
- ///
- /// Note: if \a status has a non-OK code, then \a msg will not be sent,
- /// and the client will receive only the status with possible trailing
- /// metadata.
- void Finish(const W& msg, const Status& status, void* tag) {
- finish_buf_.set_output_tag(tag);
- if (!ctx_->sent_initial_metadata_) {
- finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- finish_buf_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- // The response is dropped if the status is not OK.
- if (status.ok()) {
- finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
- finish_buf_.SendMessage(msg));
- } else {
- finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
- }
- call_.PerformOps(&finish_buf_);
- }
-
- /// Indicate that the stream is to be finished with a non-OK status,
- /// and request notification for when the server has finished sending the
- /// appropriate signals to the client to end the call.
- /// Should not be used concurrently with other operations.
- ///
- /// \param[in] tag Tag identifying this request.
- /// \param[in] status To be sent to the client as the result of the call.
- /// - Note: \a status must have a non-OK code.
- ///
- /// Side effect:
- /// - also sends initial metadata if not already sent (using the
- /// \a ServerContext associated with this call).
- void FinishWithError(const Status& status, void* tag) {
- GPR_CODEGEN_ASSERT(!status.ok());
- finish_buf_.set_output_tag(tag);
- if (!ctx_->sent_initial_metadata_) {
- finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- finish_buf_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
- call_.PerformOps(&finish_buf_);
- }
-
- private:
- void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
-
- ::grpc::internal::Call call_;
- ServerContext* ctx_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
- meta_buf_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpServerSendStatus>
- finish_buf_;
-};
-
-} // namespace grpc
-
-namespace std {
-template <class R>
-class default_delete<grpc::ClientAsyncResponseReader<R>> {
- public:
- void operator()(void* p) {}
-};
-template <class R>
-class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
- public:
- void operator()(void* p) {}
-};
-} // namespace std
+#include <grpcpp/impl/codegen/async_unary_call.h>
#endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/byte_buffer.h b/include/grpc++/impl/codegen/byte_buffer.h
index fe73ce7a83..b754fa24e9 100644
--- a/include/grpc++/impl/codegen/byte_buffer.h
+++ b/include/grpc++/impl/codegen/byte_buffer.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2017 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,142 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_BYTE_BUFFER_H
#define GRPCXX_IMPL_CODEGEN_BYTE_BUFFER_H
-#include <grpc/impl/codegen/byte_buffer.h>
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
-#include <grpc++/impl/codegen/slice.h>
-#include <grpc++/impl/codegen/status.h>
-
-#include <vector>
-
-namespace grpc {
-
-namespace internal {
-class CallOpSendMessage;
-template <class R>
-class CallOpRecvMessage;
-class CallOpGenericRecvMessage;
-class MethodHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class RpcMethodHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class ServerStreamingHandler;
-template <class R>
-class DeserializeFuncType;
-} // namespace internal
-/// A sequence of bytes.
-class ByteBuffer final {
- public:
- /// Constuct an empty buffer.
- ByteBuffer() : buffer_(nullptr) {}
-
- /// Construct buffer from \a slices, of which there are \a nslices.
- ByteBuffer(const Slice* slices, size_t nslices);
-
- /// Constuct a byte buffer by referencing elements of existing buffer
- /// \a buf. Wrapper of core function grpc_byte_buffer_copy
- ByteBuffer(const ByteBuffer& buf);
-
- ~ByteBuffer() {
- if (buffer_) {
- g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_);
- }
- }
-
- ByteBuffer& operator=(const ByteBuffer&);
-
- /// Dump (read) the buffer contents into \a slices.
- Status Dump(std::vector<Slice>* slices) const;
-
- /// Remove all data.
- void Clear() {
- if (buffer_) {
- g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_);
- buffer_ = nullptr;
- }
- }
-
- /// Make a duplicate copy of the internals of this byte
- /// buffer so that we have our own owned version of it.
- /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable
- void Duplicate() {
- buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_);
- }
-
- /// Forget underlying byte buffer without destroying
- /// Use this only for un-owned byte buffers
- void Release() { buffer_ = nullptr; }
-
- /// Buffer size in bytes.
- size_t Length() const;
-
- /// Swap the state of *this and *other.
- void Swap(ByteBuffer* other);
-
- /// Is this ByteBuffer valid?
- bool Valid() const { return (buffer_ != nullptr); }
-
- private:
- friend class SerializationTraits<ByteBuffer, void>;
- friend class internal::CallOpSendMessage;
- template <class R>
- friend class internal::CallOpRecvMessage;
- friend class internal::CallOpGenericRecvMessage;
- friend class internal::MethodHandler;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class internal::RpcMethodHandler;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class internal::ServerStreamingHandler;
- template <class R>
- friend class internal::DeserializeFuncType;
-
- grpc_byte_buffer* buffer_;
-
- // takes ownership
- void set_buffer(grpc_byte_buffer* buf) {
- if (buffer_) {
- Clear();
- }
- buffer_ = buf;
- }
-
- grpc_byte_buffer* c_buffer() { return buffer_; }
- grpc_byte_buffer** c_buffer_ptr() { return &buffer_; }
-
- class ByteBufferPointer {
- public:
- ByteBufferPointer(const ByteBuffer* b)
- : bbuf_(const_cast<ByteBuffer*>(b)) {}
- operator ByteBuffer*() { return bbuf_; }
- operator grpc_byte_buffer*() { return bbuf_->buffer_; }
- operator grpc_byte_buffer**() { return &bbuf_->buffer_; }
-
- private:
- ByteBuffer* bbuf_;
- };
- ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); }
-};
-
-template <>
-class SerializationTraits<ByteBuffer, void> {
- public:
- static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) {
- dest->set_buffer(byte_buffer->buffer_);
- return Status::OK;
- }
- static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer,
- bool* own_buffer) {
- *buffer = source;
- *own_buffer = true;
- return Status::OK;
- }
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/byte_buffer.h>
#endif // GRPCXX_IMPL_CODEGEN_BYTE_BUFFER_H
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index c04526c59b..dadab5454a 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,694 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CALL_H
#define GRPCXX_IMPL_CODEGEN_CALL_H
-#include <assert.h>
-#include <cstring>
-#include <functional>
-#include <map>
-#include <memory>
-
-#include <grpc++/impl/codegen/byte_buffer.h>
-#include <grpc++/impl/codegen/call_hook.h>
-#include <grpc++/impl/codegen/client_context.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
-#include <grpc++/impl/codegen/slice.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/string_ref.h>
-
-#include <grpc/impl/codegen/atm.h>
-#include <grpc/impl/codegen/compression_types.h>
-#include <grpc/impl/codegen/grpc_types.h>
-
-namespace grpc {
-
-class ByteBuffer;
-class CompletionQueue;
-extern CoreCodegenInterface* g_core_codegen_interface;
-
-namespace internal {
-class Call;
-class CallHook;
-
-const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
-
-// TODO(yangg) if the map is changed before we send, the pointers will be a
-// mess. Make sure it does not happen.
-inline grpc_metadata* FillMetadataArray(
- const std::multimap<grpc::string, grpc::string>& metadata,
- size_t* metadata_count, const grpc::string& optional_error_details) {
- *metadata_count = metadata.size() + (optional_error_details.empty() ? 0 : 1);
- if (*metadata_count == 0) {
- return nullptr;
- }
- grpc_metadata* metadata_array =
- (grpc_metadata*)(g_core_codegen_interface->gpr_malloc(
- (*metadata_count) * sizeof(grpc_metadata)));
- size_t i = 0;
- for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
- metadata_array[i].key = SliceReferencingString(iter->first);
- metadata_array[i].value = SliceReferencingString(iter->second);
- }
- if (!optional_error_details.empty()) {
- metadata_array[i].key =
- g_core_codegen_interface->grpc_slice_from_static_buffer(
- kBinaryErrorDetailsKey, sizeof(kBinaryErrorDetailsKey) - 1);
- metadata_array[i].value = SliceReferencingString(optional_error_details);
- }
- return metadata_array;
-}
-} // namespace internal
-
-/// Per-message write options.
-class WriteOptions {
- public:
- WriteOptions() : flags_(0), last_message_(false) {}
- WriteOptions(const WriteOptions& other)
- : flags_(other.flags_), last_message_(other.last_message_) {}
-
- /// Clear all flags.
- inline void Clear() { flags_ = 0; }
-
- /// Returns raw flags bitset.
- inline uint32_t flags() const { return flags_; }
-
- /// Sets flag for the disabling of compression for the next message write.
- ///
- /// \sa GRPC_WRITE_NO_COMPRESS
- inline WriteOptions& set_no_compression() {
- SetBit(GRPC_WRITE_NO_COMPRESS);
- return *this;
- }
-
- /// Clears flag for the disabling of compression for the next message write.
- ///
- /// \sa GRPC_WRITE_NO_COMPRESS
- inline WriteOptions& clear_no_compression() {
- ClearBit(GRPC_WRITE_NO_COMPRESS);
- return *this;
- }
-
- /// Get value for the flag indicating whether compression for the next
- /// message write is forcefully disabled.
- ///
- /// \sa GRPC_WRITE_NO_COMPRESS
- inline bool get_no_compression() const {
- return GetBit(GRPC_WRITE_NO_COMPRESS);
- }
-
- /// Sets flag indicating that the write may be buffered and need not go out on
- /// the wire immediately.
- ///
- /// \sa GRPC_WRITE_BUFFER_HINT
- inline WriteOptions& set_buffer_hint() {
- SetBit(GRPC_WRITE_BUFFER_HINT);
- return *this;
- }
-
- /// Clears flag indicating that the write may be buffered and need not go out
- /// on the wire immediately.
- ///
- /// \sa GRPC_WRITE_BUFFER_HINT
- inline WriteOptions& clear_buffer_hint() {
- ClearBit(GRPC_WRITE_BUFFER_HINT);
- return *this;
- }
-
- /// Get value for the flag indicating that the write may be buffered and need
- /// not go out on the wire immediately.
- ///
- /// \sa GRPC_WRITE_BUFFER_HINT
- inline bool get_buffer_hint() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
-
- /// corked bit: aliases set_buffer_hint currently, with the intent that
- /// set_buffer_hint will be removed in the future
- inline WriteOptions& set_corked() {
- SetBit(GRPC_WRITE_BUFFER_HINT);
- return *this;
- }
-
- inline WriteOptions& clear_corked() {
- ClearBit(GRPC_WRITE_BUFFER_HINT);
- return *this;
- }
-
- inline bool is_corked() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
-
- /// last-message bit: indicates this is the last message in a stream
- /// client-side: makes Write the equivalent of performing Write, WritesDone
- /// in a single step
- /// server-side: hold the Write until the service handler returns (sync api)
- /// or until Finish is called (async api)
- inline WriteOptions& set_last_message() {
- last_message_ = true;
- return *this;
- }
-
- /// Clears flag indicating that this is the last message in a stream,
- /// disabling coalescing.
- inline WriteOptions& clear_last_message() {
- last_message_ = false;
- return *this;
- }
-
- /// Guarantee that all bytes have been written to the wire before completing
- /// this write (usually writes are completed when they pass flow control)
- inline WriteOptions& set_write_through() {
- SetBit(GRPC_WRITE_THROUGH);
- return *this;
- }
-
- inline bool is_write_through() const { return GetBit(GRPC_WRITE_THROUGH); }
-
- /// Get value for the flag indicating that this is the last message, and
- /// should be coalesced with trailing metadata.
- ///
- /// \sa GRPC_WRITE_LAST_MESSAGE
- bool is_last_message() const { return last_message_; }
-
- WriteOptions& operator=(const WriteOptions& rhs) {
- flags_ = rhs.flags_;
- return *this;
- }
-
- private:
- void SetBit(const uint32_t mask) { flags_ |= mask; }
-
- void ClearBit(const uint32_t mask) { flags_ &= ~mask; }
-
- bool GetBit(const uint32_t mask) const { return (flags_ & mask) != 0; }
-
- uint32_t flags_;
- bool last_message_;
-};
-
-namespace internal {
-/// Default argument for CallOpSet. I is unused by the class, but can be
-/// used for generating multiple names for the same thing.
-template <int I>
-class CallNoOp {
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {}
- void FinishOp(bool* status) {}
-};
-
-class CallOpSendInitialMetadata {
- public:
- CallOpSendInitialMetadata() : send_(false) {
- maybe_compression_level_.is_set = false;
- }
-
- void SendInitialMetadata(
- const std::multimap<grpc::string, grpc::string>& metadata,
- uint32_t flags) {
- maybe_compression_level_.is_set = false;
- send_ = true;
- flags_ = flags;
- initial_metadata_ =
- FillMetadataArray(metadata, &initial_metadata_count_, "");
- }
-
- void set_compression_level(grpc_compression_level level) {
- maybe_compression_level_.is_set = true;
- maybe_compression_level_.level = level;
- }
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (!send_) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- op->flags = flags_;
- op->reserved = NULL;
- op->data.send_initial_metadata.count = initial_metadata_count_;
- op->data.send_initial_metadata.metadata = initial_metadata_;
- op->data.send_initial_metadata.maybe_compression_level.is_set =
- maybe_compression_level_.is_set;
- if (maybe_compression_level_.is_set) {
- op->data.send_initial_metadata.maybe_compression_level.level =
- maybe_compression_level_.level;
- }
- }
- void FinishOp(bool* status) {
- if (!send_) return;
- g_core_codegen_interface->gpr_free(initial_metadata_);
- send_ = false;
- }
-
- bool send_;
- uint32_t flags_;
- size_t initial_metadata_count_;
- grpc_metadata* initial_metadata_;
- struct {
- bool is_set;
- grpc_compression_level level;
- } maybe_compression_level_;
-};
-
-class CallOpSendMessage {
- public:
- CallOpSendMessage() : send_buf_() {}
-
- /// Send \a message using \a options for the write. The \a options are cleared
- /// after use.
- template <class M>
- Status SendMessage(const M& message,
- WriteOptions options) GRPC_MUST_USE_RESULT;
-
- template <class M>
- Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (!send_buf_.Valid()) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_SEND_MESSAGE;
- op->flags = write_options_.flags();
- op->reserved = NULL;
- op->data.send_message.send_message = send_buf_.c_buffer();
- // Flags are per-message: clear them after use.
- write_options_.Clear();
- }
- void FinishOp(bool* status) { send_buf_.Clear(); }
-
- private:
- ByteBuffer send_buf_;
- WriteOptions write_options_;
-};
-
-template <class M>
-Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) {
- write_options_ = options;
- bool own_buf;
- // TODO(vjpai): Remove the void below when possible
- // The void in the template parameter below should not be needed
- // (since it should be implicit) but is needed due to an observed
- // difference in behavior between clang and gcc for certain internal users
- Status result = SerializationTraits<M, void>::Serialize(
- message, send_buf_.bbuf_ptr(), &own_buf);
- if (!own_buf) {
- send_buf_.Duplicate();
- }
- return result;
-}
-
-template <class M>
-Status CallOpSendMessage::SendMessage(const M& message) {
- return SendMessage(message, WriteOptions());
-}
-
-template <class R>
-class CallOpRecvMessage {
- public:
- CallOpRecvMessage()
- : got_message(false),
- message_(nullptr),
- allow_not_getting_message_(false) {}
-
- void RecvMessage(R* message) { message_ = message; }
-
- // Do not change status if no message is received.
- void AllowNoMessage() { allow_not_getting_message_ = true; }
-
- bool got_message;
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (message_ == nullptr) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_RECV_MESSAGE;
- op->flags = 0;
- op->reserved = NULL;
- op->data.recv_message.recv_message = recv_buf_.c_buffer_ptr();
- }
-
- void FinishOp(bool* status) {
- if (message_ == nullptr) return;
- if (recv_buf_.Valid()) {
- if (*status) {
- got_message = *status =
- SerializationTraits<R>::Deserialize(recv_buf_.bbuf_ptr(), message_)
- .ok();
- recv_buf_.Release();
- } else {
- got_message = false;
- recv_buf_.Clear();
- }
- } else {
- got_message = false;
- if (!allow_not_getting_message_) {
- *status = false;
- }
- }
- message_ = nullptr;
- }
-
- private:
- R* message_;
- ByteBuffer recv_buf_;
- bool allow_not_getting_message_;
-};
-
-class DeserializeFunc {
- public:
- virtual Status Deserialize(ByteBuffer* buf) = 0;
- virtual ~DeserializeFunc() {}
-};
-
-template <class R>
-class DeserializeFuncType final : public DeserializeFunc {
- public:
- DeserializeFuncType(R* message) : message_(message) {}
- Status Deserialize(ByteBuffer* buf) override {
- return SerializationTraits<R>::Deserialize(buf->bbuf_ptr(), message_);
- }
-
- ~DeserializeFuncType() override {}
-
- private:
- R* message_; // Not a managed pointer because management is external to this
-};
-
-class CallOpGenericRecvMessage {
- public:
- CallOpGenericRecvMessage()
- : got_message(false), allow_not_getting_message_(false) {}
-
- template <class R>
- void RecvMessage(R* message) {
- // Use an explicit base class pointer to avoid resolution error in the
- // following unique_ptr::reset for some old implementations.
- DeserializeFunc* func = new DeserializeFuncType<R>(message);
- deserialize_.reset(func);
- }
-
- // Do not change status if no message is received.
- void AllowNoMessage() { allow_not_getting_message_ = true; }
-
- bool got_message;
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (!deserialize_) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_RECV_MESSAGE;
- op->flags = 0;
- op->reserved = NULL;
- op->data.recv_message.recv_message = recv_buf_.c_buffer_ptr();
- }
-
- void FinishOp(bool* status) {
- if (!deserialize_) return;
- if (recv_buf_.Valid()) {
- if (*status) {
- got_message = true;
- *status = deserialize_->Deserialize(&recv_buf_).ok();
- recv_buf_.Release();
- } else {
- got_message = false;
- recv_buf_.Clear();
- }
- } else {
- got_message = false;
- if (!allow_not_getting_message_) {
- *status = false;
- }
- }
- deserialize_.reset();
- }
-
- private:
- std::unique_ptr<DeserializeFunc> deserialize_;
- ByteBuffer recv_buf_;
- bool allow_not_getting_message_;
-};
-
-class CallOpClientSendClose {
- public:
- CallOpClientSendClose() : send_(false) {}
-
- void ClientSendClose() { send_ = true; }
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (!send_) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
- op->flags = 0;
- op->reserved = NULL;
- }
- void FinishOp(bool* status) { send_ = false; }
-
- private:
- bool send_;
-};
-
-class CallOpServerSendStatus {
- public:
- CallOpServerSendStatus() : send_status_available_(false) {}
-
- void ServerSendStatus(
- const std::multimap<grpc::string, grpc::string>& trailing_metadata,
- const Status& status) {
- send_error_details_ = status.error_details();
- trailing_metadata_ = FillMetadataArray(
- trailing_metadata, &trailing_metadata_count_, send_error_details_);
- send_status_available_ = true;
- send_status_code_ = static_cast<grpc_status_code>(status.error_code());
- send_error_message_ = status.error_message();
- }
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (!send_status_available_) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
- op->data.send_status_from_server.trailing_metadata_count =
- trailing_metadata_count_;
- op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
- op->data.send_status_from_server.status = send_status_code_;
- error_message_slice_ = SliceReferencingString(send_error_message_);
- op->data.send_status_from_server.status_details =
- send_error_message_.empty() ? nullptr : &error_message_slice_;
- op->flags = 0;
- op->reserved = NULL;
- }
-
- void FinishOp(bool* status) {
- if (!send_status_available_) return;
- g_core_codegen_interface->gpr_free(trailing_metadata_);
- send_status_available_ = false;
- }
-
- private:
- bool send_status_available_;
- grpc_status_code send_status_code_;
- grpc::string send_error_details_;
- grpc::string send_error_message_;
- size_t trailing_metadata_count_;
- grpc_metadata* trailing_metadata_;
- grpc_slice error_message_slice_;
-};
-
-class CallOpRecvInitialMetadata {
- public:
- CallOpRecvInitialMetadata() : metadata_map_(nullptr) {}
-
- void RecvInitialMetadata(ClientContext* context) {
- context->initial_metadata_received_ = true;
- metadata_map_ = &context->recv_initial_metadata_;
- }
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (metadata_map_ == nullptr) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_RECV_INITIAL_METADATA;
- op->data.recv_initial_metadata.recv_initial_metadata = metadata_map_->arr();
- op->flags = 0;
- op->reserved = NULL;
- }
-
- void FinishOp(bool* status) {
- if (metadata_map_ == nullptr) return;
- metadata_map_->FillMap();
- metadata_map_ = nullptr;
- }
-
- private:
- MetadataMap* metadata_map_;
-};
-
-class CallOpClientRecvStatus {
- public:
- CallOpClientRecvStatus()
- : recv_status_(nullptr), debug_error_string_(nullptr) {}
-
- void ClientRecvStatus(ClientContext* context, Status* status) {
- client_context_ = context;
- metadata_map_ = &client_context_->trailing_metadata_;
- recv_status_ = status;
- error_message_ = g_core_codegen_interface->grpc_empty_slice();
- }
-
- protected:
- void AddOp(grpc_op* ops, size_t* nops) {
- if (recv_status_ == nullptr) return;
- grpc_op* op = &ops[(*nops)++];
- op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
- op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
- op->data.recv_status_on_client.status = &status_code_;
- op->data.recv_status_on_client.status_details = &error_message_;
- op->data.recv_status_on_client.error_string = &debug_error_string_;
- op->flags = 0;
- op->reserved = NULL;
- }
-
- void FinishOp(bool* status) {
- if (recv_status_ == nullptr) return;
- metadata_map_->FillMap();
- grpc::string binary_error_details;
- auto iter = metadata_map_->map()->find(kBinaryErrorDetailsKey);
- if (iter != metadata_map_->map()->end()) {
- binary_error_details =
- grpc::string(iter->second.begin(), iter->second.length());
- }
- *recv_status_ = Status(static_cast<StatusCode>(status_code_),
- grpc::string(GRPC_SLICE_START_PTR(error_message_),
- GRPC_SLICE_END_PTR(error_message_)),
- binary_error_details);
- client_context_->set_debug_error_string(
- debug_error_string_ != nullptr ? debug_error_string_ : "");
- g_core_codegen_interface->grpc_slice_unref(error_message_);
- if (debug_error_string_ != nullptr) {
- g_core_codegen_interface->gpr_free((void*)debug_error_string_);
- }
- recv_status_ = nullptr;
- }
-
- private:
- ClientContext* client_context_;
- MetadataMap* metadata_map_;
- Status* recv_status_;
- const char* debug_error_string_;
- grpc_status_code status_code_;
- grpc_slice error_message_;
-};
-
-/// An abstract collection of call ops, used to generate the
-/// grpc_call_op structure to pass down to the lower layers,
-/// and as it is-a CompletionQueueTag, also massages the final
-/// completion into the correct form for consumption in the C++
-/// API.
-class CallOpSetInterface : public CompletionQueueTag {
- public:
- /// Fills in grpc_op, starting from ops[*nops] and moving
- /// upwards.
- virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0;
-};
-
-/// Primary implementation of CallOpSetInterface.
-/// Since we cannot use variadic templates, we declare slots up to
-/// the maximum count of ops we'll need in a set. We leverage the
-/// empty base class optimization to slim this class (especially
-/// when there are many unused slots used). To avoid duplicate base classes,
-/// the template parmeter for CallNoOp is varied by argument position.
-template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
- class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
- class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
-class CallOpSet : public CallOpSetInterface,
- public Op1,
- public Op2,
- public Op3,
- public Op4,
- public Op5,
- public Op6 {
- public:
- CallOpSet() : return_tag_(this), call_(nullptr) {}
- void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override {
- this->Op1::AddOp(ops, nops);
- this->Op2::AddOp(ops, nops);
- this->Op3::AddOp(ops, nops);
- this->Op4::AddOp(ops, nops);
- this->Op5::AddOp(ops, nops);
- this->Op6::AddOp(ops, nops);
- g_core_codegen_interface->grpc_call_ref(call);
- call_ = call;
- }
-
- bool FinalizeResult(void** tag, bool* status) override {
- this->Op1::FinishOp(status);
- this->Op2::FinishOp(status);
- this->Op3::FinishOp(status);
- this->Op4::FinishOp(status);
- this->Op5::FinishOp(status);
- this->Op6::FinishOp(status);
- *tag = return_tag_;
-
- g_core_codegen_interface->grpc_call_unref(call_);
- return true;
- }
-
- void set_output_tag(void* return_tag) { return_tag_ = return_tag; }
-
- private:
- void* return_tag_;
- grpc_call* call_;
-};
-
-/// A CallOpSet that does not post completions to the completion queue.
-///
-/// Allows hiding some completions that the C core must generate from
-/// C++ users.
-template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
- class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
- class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
-class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
- public:
- bool FinalizeResult(void** tag, bool* status) override {
- typedef CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> Base;
- return Base::FinalizeResult(tag, status) && false;
- }
-};
-
-/// Straightforward wrapping of the C call object
-class Call final {
- public:
- /** call is owned by the caller */
- Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
- : call_hook_(call_hook),
- cq_(cq),
- call_(call),
- max_receive_message_size_(-1) {}
-
- Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
- int max_receive_message_size)
- : call_hook_(call_hook),
- cq_(cq),
- call_(call),
- max_receive_message_size_(max_receive_message_size) {}
-
- void PerformOps(CallOpSetInterface* ops) {
- call_hook_->PerformOpsOnCall(ops, this);
- }
-
- grpc_call* call() const { return call_; }
- CompletionQueue* cq() const { return cq_; }
-
- int max_receive_message_size() const { return max_receive_message_size_; }
-
- private:
- CallHook* call_hook_;
- CompletionQueue* cq_;
- grpc_call* call_;
- int max_receive_message_size_;
-};
-} // namespace internal
-} // namespace grpc
+#include <grpcpp/impl/codegen/call.h>
#endif // GRPCXX_IMPL_CODEGEN_CALL_H
diff --git a/include/grpc++/impl/codegen/call_hook.h b/include/grpc++/impl/codegen/call_hook.h
index 44e9de220e..cf5ed571b2 100644
--- a/include/grpc++/impl/codegen/call_hook.h
+++ b/include/grpc++/impl/codegen/call_hook.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,24 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
#define GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
-namespace grpc {
-
-namespace internal {
-class CallOpSetInterface;
-class Call;
-
-/// This is an interface that Channel and Server implement to allow them to hook
-/// performing ops.
-class CallHook {
- public:
- virtual ~CallHook() {}
- virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
-};
-} // namespace internal
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/call_hook.h>
#endif // GRPCXX_IMPL_CODEGEN_CALL_HOOK_H
diff --git a/include/grpc++/impl/codegen/channel_interface.h b/include/grpc++/impl/codegen/channel_interface.h
index 769f853974..c6e782e9c4 100644
--- a/include/grpc++/impl/codegen/channel_interface.h
+++ b/include/grpc++/impl/codegen/channel_interface.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,106 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
#define GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
-#include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/time.h>
-#include <grpc/impl/codegen/connectivity_state.h>
-
-namespace grpc {
-class ChannelInterface;
-class ClientContext;
-class CompletionQueue;
-
-template <class R>
-class ClientReader;
-template <class W>
-class ClientWriter;
-template <class W, class R>
-class ClientReaderWriter;
-
-namespace internal {
-class Call;
-class CallOpSetInterface;
-class RpcMethod;
-template <class InputMessage, class OutputMessage>
-class BlockingUnaryCallImpl;
-template <class R>
-class ClientAsyncReaderFactory;
-template <class W>
-class ClientAsyncWriterFactory;
-template <class W, class R>
-class ClientAsyncReaderWriterFactory;
-template <class R>
-class ClientAsyncResponseReaderFactory;
-} // namespace internal
-
-/// Codegen interface for \a grpc::Channel.
-class ChannelInterface {
- public:
- virtual ~ChannelInterface() {}
- /// Get the current channel state. If the channel is in IDLE and
- /// \a try_to_connect is set to true, try to connect.
- virtual grpc_connectivity_state GetState(bool try_to_connect) = 0;
-
- /// Return the \a tag on \a cq when the channel state is changed or \a
- /// deadline expires. \a GetState needs to called to get the current state.
- template <typename T>
- void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
- CompletionQueue* cq, void* tag) {
- TimePoint<T> deadline_tp(deadline);
- NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
- }
-
- /// Blocking wait for channel state change or \a deadline expiration.
- /// \a GetState needs to called to get the current state.
- template <typename T>
- bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
- TimePoint<T> deadline_tp(deadline);
- return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
- }
-
- /// Wait for this channel to be connected
- template <typename T>
- bool WaitForConnected(T deadline) {
- grpc_connectivity_state state;
- while ((state = GetState(true)) != GRPC_CHANNEL_READY) {
- if (!WaitForStateChange(state, deadline)) return false;
- }
- return true;
- }
-
- private:
- template <class R>
- friend class ::grpc::ClientReader;
- template <class W>
- friend class ::grpc::ClientWriter;
- template <class W, class R>
- friend class ::grpc::ClientReaderWriter;
- template <class R>
- friend class ::grpc::internal::ClientAsyncReaderFactory;
- template <class W>
- friend class ::grpc::internal::ClientAsyncWriterFactory;
- template <class W, class R>
- friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
- template <class R>
- friend class ::grpc::internal::ClientAsyncResponseReaderFactory;
- template <class InputMessage, class OutputMessage>
- friend class ::grpc::internal::BlockingUnaryCallImpl;
- friend class ::grpc::internal::RpcMethod;
- virtual internal::Call CreateCall(const internal::RpcMethod& method,
- ClientContext* context,
- CompletionQueue* cq) = 0;
- virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
- internal::Call* call) = 0;
- virtual void* RegisterMethod(const char* method) = 0;
- virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
- gpr_timespec deadline,
- CompletionQueue* cq, void* tag) = 0;
- virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
- gpr_timespec deadline) = 0;
-};
-} // namespace grpc
+#include <grpcpp/impl/codegen/channel_interface.h>
#endif // GRPCXX_IMPL_CODEGEN_CHANNEL_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index 38cce27b99..107532cb6b 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,427 +16,13 @@
*
*/
-/// A ClientContext allows the person implementing a service client to:
-///
-/// - Add custom metadata key-value pairs that will propagated to the server
-/// side.
-/// - Control call settings such as compression and authentication.
-/// - Initial and trailing metadata coming from the server.
-/// - Get performance metrics (ie, census).
-///
-/// Context settings are only relevant to the call they are invoked with, that
-/// is to say, they aren't sticky. Some of these settings, such as the
-/// compression options, can be made persistent at channel construction time
-/// (see \a grpc::CreateCustomChannel).
-///
-/// \warning ClientContext instances should \em not be reused across rpcs.
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
#ifndef GRPCXX_IMPL_CODEGEN_CLIENT_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_CLIENT_CONTEXT_H
-#include <map>
-#include <memory>
-#include <mutex>
-#include <string>
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/create_auth_context.h>
-#include <grpc++/impl/codegen/metadata_map.h>
-#include <grpc++/impl/codegen/security/auth_context.h>
-#include <grpc++/impl/codegen/slice.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/string_ref.h>
-#include <grpc++/impl/codegen/time.h>
-#include <grpc/impl/codegen/compression_types.h>
-#include <grpc/impl/codegen/propagation_bits.h>
-
-struct census_context;
-struct grpc_call;
-
-namespace grpc {
-
-class Channel;
-class ChannelInterface;
-class CompletionQueue;
-class CallCredentials;
-class ClientContext;
-
-namespace internal {
-class RpcMethod;
-class CallOpClientRecvStatus;
-class CallOpRecvInitialMetadata;
-template <class InputMessage, class OutputMessage>
-class BlockingUnaryCallImpl;
-} // namespace internal
-
-template <class R>
-class ClientReader;
-template <class W>
-class ClientWriter;
-template <class W, class R>
-class ClientReaderWriter;
-template <class R>
-class ClientAsyncReader;
-template <class W>
-class ClientAsyncWriter;
-template <class W, class R>
-class ClientAsyncReaderWriter;
-template <class R>
-class ClientAsyncResponseReader;
-class ServerContext;
-
-/// Options for \a ClientContext::FromServerContext specifying which traits from
-/// the \a ServerContext to propagate (copy) from it into a new \a
-/// ClientContext.
-///
-/// \see ClientContext::FromServerContext
-class PropagationOptions {
- public:
- PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
-
- PropagationOptions& enable_deadline_propagation() {
- propagate_ |= GRPC_PROPAGATE_DEADLINE;
- return *this;
- }
-
- PropagationOptions& disable_deadline_propagation() {
- propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
- return *this;
- }
-
- PropagationOptions& enable_census_stats_propagation() {
- propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
- return *this;
- }
-
- PropagationOptions& disable_census_stats_propagation() {
- propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
- return *this;
- }
-
- PropagationOptions& enable_census_tracing_propagation() {
- propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
- return *this;
- }
-
- PropagationOptions& disable_census_tracing_propagation() {
- propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
- return *this;
- }
-
- PropagationOptions& enable_cancellation_propagation() {
- propagate_ |= GRPC_PROPAGATE_CANCELLATION;
- return *this;
- }
-
- PropagationOptions& disable_cancellation_propagation() {
- propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
- return *this;
- }
-
- uint32_t c_bitmask() const { return propagate_; }
-
- private:
- uint32_t propagate_;
-};
-
-namespace testing {
-class InteropClientContextInspector;
-} // namespace testing
-
-/// A ClientContext allows the person implementing a service client to:
-///
-/// - Add custom metadata key-value pairs that will propagated to the server
-/// side.
-/// - Control call settings such as compression and authentication.
-/// - Initial and trailing metadata coming from the server.
-/// - Get performance metrics (ie, census).
-///
-/// Context settings are only relevant to the call they are invoked with, that
-/// is to say, they aren't sticky. Some of these settings, such as the
-/// compression options, can be made persistent at channel construction time
-/// (see \a grpc::CreateCustomChannel).
-///
-/// \warning ClientContext instances should \em not be reused across rpcs.
-class ClientContext {
- public:
- ClientContext();
- ~ClientContext();
-
- /// Create a new \a ClientContext as a child of an incoming server call,
- /// according to \a options (\see PropagationOptions).
- ///
- /// \param server_context The source server context to use as the basis for
- /// constructing the client context.
- /// \param options The options controlling what to copy from the \a
- /// server_context.
- ///
- /// \return A newly constructed \a ClientContext instance based on \a
- /// server_context, with traits propagated (copied) according to \a options.
- static std::unique_ptr<ClientContext> FromServerContext(
- const ServerContext& server_context,
- PropagationOptions options = PropagationOptions());
-
- /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
- /// a client call. These are made available at the server side by the \a
- /// grpc::ServerContext::client_metadata() method.
- ///
- /// \warning This method should only be called before invoking the rpc.
- ///
- /// \param meta_key The metadata key. If \a meta_value is binary data, it must
- /// end in "-bin".
- /// \param meta_value The metadata value. If its value is binary, the key name
- /// must end in "-bin".
- void AddMetadata(const grpc::string& meta_key,
- const grpc::string& meta_value);
-
- /// Return a collection of initial metadata key-value pairs. Note that keys
- /// may happen more than once (ie, a \a std::multimap is returned).
- ///
- /// \warning This method should only be called after initial metadata has been
- /// received. For streaming calls, see \a
- /// ClientReaderInterface::WaitForInitialMetadata().
- ///
- /// \return A multimap of initial metadata key-value pairs from the server.
- const std::multimap<grpc::string_ref, grpc::string_ref>&
- GetServerInitialMetadata() const {
- GPR_CODEGEN_ASSERT(initial_metadata_received_);
- return *recv_initial_metadata_.map();
- }
-
- /// Return a collection of trailing metadata key-value pairs. Note that keys
- /// may happen more than once (ie, a \a std::multimap is returned).
- ///
- /// \warning This method is only callable once the stream has finished.
- ///
- /// \return A multimap of metadata trailing key-value pairs from the server.
- const std::multimap<grpc::string_ref, grpc::string_ref>&
- GetServerTrailingMetadata() const {
- // TODO(yangg) check finished
- return *trailing_metadata_.map();
- }
-
- /// Set the deadline for the client call.
- ///
- /// \warning This method should only be called before invoking the rpc.
- ///
- /// \param deadline the deadline for the client call. Units are determined by
- /// the type used.
- template <typename T>
- void set_deadline(const T& deadline) {
- TimePoint<T> deadline_tp(deadline);
- deadline_ = deadline_tp.raw_time();
- }
-
- /// EXPERIMENTAL: Indicate that this request is idempotent.
- /// By default, RPCs are assumed to <i>not</i> be idempotent.
- ///
- /// If true, the gRPC library assumes that it's safe to initiate
- /// this RPC multiple times.
- void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
-
- /// EXPERIMENTAL: Set this request to be cacheable.
- /// If set, grpc is free to use the HTTP GET verb for sending the request,
- /// with the possibility of receiving a cached response.
- void set_cacheable(bool cacheable) { cacheable_ = cacheable; }
-
- /// EXPERIMENTAL: Trigger wait-for-ready or not on this request.
- /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
- /// If set, if an RPC is made when a channel's connectivity state is
- /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast",
- /// and the channel will wait until the channel is READY before making the
- /// call.
- void set_wait_for_ready(bool wait_for_ready) {
- wait_for_ready_ = wait_for_ready;
- wait_for_ready_explicitly_set_ = true;
- }
-
- /// DEPRECATED: Use set_wait_for_ready() instead.
- void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); }
-
- /// Return the deadline for the client call.
- std::chrono::system_clock::time_point deadline() const {
- return Timespec2Timepoint(deadline_);
- }
-
- /// Return a \a gpr_timespec representation of the client call's deadline.
- gpr_timespec raw_deadline() const { return deadline_; }
-
- /// Set the per call authority header (see
- /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
- void set_authority(const grpc::string& authority) { authority_ = authority; }
-
- /// Return the authentication context for this client call.
- ///
- /// \see grpc::AuthContext.
- std::shared_ptr<const AuthContext> auth_context() const {
- if (auth_context_.get() == nullptr) {
- auth_context_ = CreateAuthContext(call_);
- }
- return auth_context_;
- }
-
- /// Set credentials for the client call.
- ///
- /// A credentials object encapsulates all the state needed by a client to
- /// authenticate with a server and make various assertions, e.g., about the
- /// client’s identity, role, or whether it is authorized to make a particular
- /// call.
- ///
- /// \see https://grpc.io/docs/guides/auth.html
- void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
- creds_ = creds;
- }
-
- /// Return the compression algorithm the client call will request be used.
- /// Note that the gRPC runtime may decide to ignore this request, for example,
- /// due to resource constraints.
- grpc_compression_algorithm compression_algorithm() const {
- return compression_algorithm_;
- }
-
- /// Set \a algorithm to be the compression algorithm used for the client call.
- ///
- /// \param algorithm The compression algorithm used for the client call.
- void set_compression_algorithm(grpc_compression_algorithm algorithm);
-
- /// Flag whether the initial metadata should be \a corked
- ///
- /// If \a corked is true, then the initial metadata will be coalesced with the
- /// write of first message in the stream. As a result, any tag set for the
- /// initial metadata operation (starting a client-streaming or bidi-streaming
- /// RPC) will not actually be sent to the completion queue or delivered
- /// via Next.
- ///
- /// \param corked The flag indicating whether the initial metadata is to be
- /// corked or not.
- void set_initial_metadata_corked(bool corked) {
- initial_metadata_corked_ = corked;
- }
-
- /// Return the peer uri in a string.
- ///
- /// \warning This value is never authenticated or subject to any security
- /// related code. It must not be used for any authentication related
- /// functionality. Instead, use auth_context.
- ///
- /// \return The call's peer URI.
- grpc::string peer() const;
-
- /// Get and set census context.
- void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
- struct census_context* census_context() const {
- return census_context_;
- }
-
- /// Send a best-effort out-of-band cancel on the call associated with
- /// this client context. The call could be in any stage; e.g., if it is
- /// already finished, it may still return success.
- ///
- /// There is no guarantee the call will be cancelled.
- ///
- /// Note that TryCancel() does not change any of the tags that are pending
- /// on the completion queue. All pending tags will still be delivered
- /// (though their ok result may reflect the effect of cancellation).
- void TryCancel();
-
- /// Global Callbacks
- ///
- /// Can be set exactly once per application to install hooks whenever
- /// a client context is constructed and destructed.
- class GlobalCallbacks {
- public:
- virtual ~GlobalCallbacks() {}
- virtual void DefaultConstructor(ClientContext* context) = 0;
- virtual void Destructor(ClientContext* context) = 0;
- };
- static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
-
- /// Should be used for framework-level extensions only.
- /// Applications never need to call this method.
- grpc_call* c_call() { return call_; }
-
- /// EXPERIMENTAL debugging API
- ///
- /// if status is not ok() for an RPC, this will return a detailed string
- /// of the gRPC Core error that led to the failure. It should not be relied
- /// upon for anything other than gaining more debug data in failure cases.
- grpc::string debug_error_string() const { return debug_error_string_; }
-
- private:
- // Disallow copy and assign.
- ClientContext(const ClientContext&);
- ClientContext& operator=(const ClientContext&);
-
- friend class ::grpc::testing::InteropClientContextInspector;
- friend class ::grpc::internal::CallOpClientRecvStatus;
- friend class ::grpc::internal::CallOpRecvInitialMetadata;
- friend class Channel;
- template <class R>
- friend class ::grpc::ClientReader;
- template <class W>
- friend class ::grpc::ClientWriter;
- template <class W, class R>
- friend class ::grpc::ClientReaderWriter;
- template <class R>
- friend class ::grpc::ClientAsyncReader;
- template <class W>
- friend class ::grpc::ClientAsyncWriter;
- template <class W, class R>
- friend class ::grpc::ClientAsyncReaderWriter;
- template <class R>
- friend class ::grpc::ClientAsyncResponseReader;
- template <class InputMessage, class OutputMessage>
- friend class ::grpc::internal::BlockingUnaryCallImpl;
-
- // Used by friend class CallOpClientRecvStatus
- void set_debug_error_string(const grpc::string& debug_error_string) {
- debug_error_string_ = debug_error_string;
- }
-
- grpc_call* call() const { return call_; }
- void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
-
- uint32_t initial_metadata_flags() const {
- return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
- (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) |
- (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) |
- (wait_for_ready_explicitly_set_
- ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET
- : 0) |
- (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0);
- }
-
- grpc::string authority() { return authority_; }
-
- bool initial_metadata_received_;
- bool wait_for_ready_;
- bool wait_for_ready_explicitly_set_;
- bool idempotent_;
- bool cacheable_;
- std::shared_ptr<Channel> channel_;
- std::mutex mu_;
- grpc_call* call_;
- bool call_canceled_;
- gpr_timespec deadline_;
- grpc::string authority_;
- std::shared_ptr<CallCredentials> creds_;
- mutable std::shared_ptr<const AuthContext> auth_context_;
- struct census_context* census_context_;
- std::multimap<grpc::string, grpc::string> send_initial_metadata_;
- internal::MetadataMap recv_initial_metadata_;
- internal::MetadataMap trailing_metadata_;
-
- grpc_call* propagate_from_call_;
- PropagationOptions propagation_options_;
-
- grpc_compression_algorithm compression_algorithm_;
- bool initial_metadata_corked_;
-
- grpc::string debug_error_string_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/client_context.h>
#endif // GRPCXX_IMPL_CODEGEN_CLIENT_CONTEXT_H
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h
index 543e54b972..f7dff1f1f0 100644
--- a/include/grpc++/impl/codegen/client_unary_call.h
+++ b/include/grpc++/impl/codegen/client_unary_call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,75 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
#define GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
-#include <grpc++/impl/codegen/call.h>
-#include <grpc++/impl/codegen/channel_interface.h>
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/status.h>
-
-namespace grpc {
-
-class Channel;
-class ClientContext;
-class CompletionQueue;
-
-namespace internal {
-class RpcMethod;
-/// Wrapper that performs a blocking unary call
-template <class InputMessage, class OutputMessage>
-Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context, const InputMessage& request,
- OutputMessage* result) {
- return BlockingUnaryCallImpl<InputMessage, OutputMessage>(
- channel, method, context, request, result)
- .status();
-}
-
-template <class InputMessage, class OutputMessage>
-class BlockingUnaryCallImpl {
- public:
- BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method,
- ClientContext* context, const InputMessage& request,
- OutputMessage* result) {
- CompletionQueue cq(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue
- Call call(channel->CreateCall(method, context, &cq));
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
- CallOpClientSendClose, CallOpClientRecvStatus>
- ops;
- status_ = ops.SendMessage(request);
- if (!status_.ok()) {
- return;
- }
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- ops.RecvInitialMetadata(context);
- ops.RecvMessage(result);
- ops.AllowNoMessage();
- ops.ClientSendClose();
- ops.ClientRecvStatus(context, &status_);
- call.PerformOps(&ops);
- if (cq.Pluck(&ops)) {
- if (!ops.got_message && status_.ok()) {
- status_ = Status(StatusCode::UNIMPLEMENTED,
- "No message returned for unary request");
- }
- } else {
- GPR_CODEGEN_ASSERT(!status_.ok());
- }
- }
- Status status() { return status_; }
-
- private:
- Status status_;
-};
-
-} // namespace internal
-} // namespace grpc
+#include <grpcpp/impl/codegen/client_unary_call.h>
#endif // GRPCXX_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index 83477d0489..107549550b 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,368 +16,13 @@
*
*/
-/// A completion queue implements a concurrent producer-consumer queue, with
-/// two main API-exposed methods: \a Next and \a AsyncNext. These
-/// methods are the essential component of the gRPC C++ asynchronous API.
-/// There is also a \a Shutdown method to indicate that a given completion queue
-/// will no longer have regular events. This must be called before the
-/// completion queue is destroyed.
-/// All completion queue APIs are thread-safe and may be used concurrently with
-/// any other completion queue API invocation; it is acceptable to have
-/// multiple threads calling \a Next or \a AsyncNext on the same or different
-/// completion queues, or to call these methods concurrently with a \a Shutdown
-/// elsewhere.
-/// \remark{All other API calls on completion queue should be completed before
-/// a completion queue destructor is called.}
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
#define GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/grpc_library.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/time.h>
-#include <grpc/impl/codegen/atm.h>
-
-struct grpc_completion_queue;
-
-namespace grpc {
-
-template <class R>
-class ClientReader;
-template <class W>
-class ClientWriter;
-template <class W, class R>
-class ClientReaderWriter;
-template <class R>
-class ServerReader;
-template <class W>
-class ServerWriter;
-namespace internal {
-template <class W, class R>
-class ServerReaderWriterBody;
-} // namespace internal
-
-class Channel;
-class ChannelInterface;
-class ClientContext;
-class CompletionQueue;
-class Server;
-class ServerBuilder;
-class ServerContext;
-class ServerInterface;
-
-namespace internal {
-class CompletionQueueTag;
-class RpcMethod;
-template <class ServiceType, class RequestType, class ResponseType>
-class RpcMethodHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class ClientStreamingHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class ServerStreamingHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class BidiStreamingHandler;
-class UnknownMethodHandler;
-template <class Streamer, bool WriteNeeded>
-class TemplatedBidiStreamingHandler;
-template <class InputMessage, class OutputMessage>
-class BlockingUnaryCallImpl;
-} // namespace internal
-
-extern CoreCodegenInterface* g_core_codegen_interface;
-
-/// A thin wrapper around \ref grpc_completion_queue (see \ref
-/// src/core/lib/surface/completion_queue.h).
-/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
-/// performance servers.
-class CompletionQueue : private GrpcLibraryCodegen {
- public:
- /// Default constructor. Implicitly creates a \a grpc_completion_queue
- /// instance.
- CompletionQueue()
- : CompletionQueue(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}) {}
-
- /// Wrap \a take, taking ownership of the instance.
- ///
- /// \param take The completion queue instance to wrap. Ownership is taken.
- explicit CompletionQueue(grpc_completion_queue* take);
-
- /// Destructor. Destroys the owned wrapped completion queue / instance.
- ~CompletionQueue() {
- g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
- }
-
- /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
- enum NextStatus {
- SHUTDOWN, ///< The completion queue has been shutdown and fully-drained
- GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
- ///< associated value; \a ok indicating its success.
- TIMEOUT ///< deadline was reached.
- };
-
- /// Read from the queue, blocking until an event is available or the queue is
- /// shutting down.
- ///
- /// \param tag[out] Updated to point to the read event's tag.
- /// \param ok[out] true if read a successful event, false otherwise.
- ///
- /// Note that each tag sent to the completion queue (through RPC operations
- /// or alarms) will be delivered out of the completion queue by a call to
- /// Next (or a related method), regardless of whether the operation succeeded
- /// or not. Success here means that this operation completed in the normal
- /// valid manner.
- ///
- /// Server-side RPC request: \a ok indicates that the RPC has indeed
- /// been started. If it is false, the server has been Shutdown
- /// before this particular call got matched to an incoming RPC.
- ///
- /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is
- /// going to go to the wire. If it is false, it not going to the wire. This
- /// would happen if the channel is either permanently broken or
- /// transiently broken but with the fail-fast option. (Note that async unary
- /// RPCs don't post a CQ tag at this point, nor do client-streaming
- /// or bidi-streaming RPCs that have the initial metadata corked option set.)
- ///
- /// Client-side Write, Client-side WritesDone, Server-side Write,
- /// Server-side Finish, Server-side SendInitialMetadata (which is
- /// typically included in Write or Finish when not done explicitly):
- /// \a ok means that the data/metadata/status/etc is going to go to the
- /// wire. If it is false, it not going to the wire because the call
- /// is already dead (i.e., canceled, deadline expired, other side
- /// dropped the channel, etc).
- ///
- /// Client-side Read, Server-side Read, Client-side
- /// RecvInitialMetadata (which is typically included in Read if not
- /// done explicitly): \a ok indicates whether there is a valid message
- /// that got read. If not, you know that there are certainly no more
- /// messages that can ever be read from this stream. For the client-side
- /// operations, this only happens because the call is dead. For the
- /// server-sider operation, though, this could happen because the client
- /// has done a WritesDone already.
- ///
- /// Client-side Finish: \a ok should always be true
- ///
- /// Server-side AsyncNotifyWhenDone: \a ok should always be true
- ///
- /// Alarm: \a ok is true if it expired, false if it was canceled
- ///
- /// \return true if got an event, false if the queue is fully drained and
- /// shut down.
- bool Next(void** tag, bool* ok) {
- return (AsyncNextInternal(tag, ok,
- g_core_codegen_interface->gpr_inf_future(
- GPR_CLOCK_REALTIME)) != SHUTDOWN);
- }
-
- /// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
- /// Both \a tag and \a ok are updated upon success (if an event is available
- /// within the \a deadline). A \a tag points to an arbitrary location usually
- /// employed to uniquely identify an event.
- ///
- /// \param tag[out] Upon sucess, updated to point to the event's tag.
- /// \param ok[out] Upon sucess, true if a successful event, false otherwise
- /// See documentation for CompletionQueue::Next for explanation of ok
- /// \param deadline[in] How long to block in wait for an event.
- ///
- /// \return The type of event read.
- template <typename T>
- NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
- TimePoint<T> deadline_tp(deadline);
- return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
- }
-
- /// EXPERIMENTAL
- /// First executes \a F, then reads from the queue, blocking up to
- /// \a deadline (or the queue's shutdown).
- /// Both \a tag and \a ok are updated upon success (if an event is available
- /// within the \a deadline). A \a tag points to an arbitrary location usually
- /// employed to uniquely identify an event.
- ///
- /// \param F[in] Function to execute before calling AsyncNext on this queue.
- /// \param tag[out] Upon sucess, updated to point to the event's tag.
- /// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
- /// \param deadline[in] How long to block in wait for an event.
- ///
- /// \return The type of event read.
- template <typename T, typename F>
- NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
- CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
- f();
- if (cache.Flush(tag, ok)) {
- return GOT_EVENT;
- } else {
- return AsyncNext(tag, ok, deadline);
- }
- }
-
- /// Request the shutdown of the queue.
- ///
- /// \warning This method must be called at some point if this completion queue
- /// is accessed with Next or AsyncNext. \a Next will not return false
- /// until this method has been called and all pending tags have been drained.
- /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .)
- /// Only once either one of these methods does that (that is, once the queue
- /// has been \em drained) can an instance of this class be destroyed.
- /// Also note that applications must ensure that no work is enqueued on this
- /// completion queue after this method is called.
- void Shutdown();
-
- /// Returns a \em raw pointer to the underlying \a grpc_completion_queue
- /// instance.
- ///
- /// \warning Remember that the returned instance is owned. No transfer of
- /// owership is performed.
- grpc_completion_queue* cq() { return cq_; }
-
- protected:
- /// Private constructor of CompletionQueue only visible to friend classes
- CompletionQueue(const grpc_completion_queue_attributes& attributes) {
- cq_ = g_core_codegen_interface->grpc_completion_queue_create(
- g_core_codegen_interface->grpc_completion_queue_factory_lookup(
- &attributes),
- &attributes, NULL);
- InitialAvalanching(); // reserve this for the future shutdown
- }
-
- private:
- // Friend synchronous wrappers so that they can access Pluck(), which is
- // a semi-private API geared towards the synchronous implementation.
- template <class R>
- friend class ::grpc::ClientReader;
- template <class W>
- friend class ::grpc::ClientWriter;
- template <class W, class R>
- friend class ::grpc::ClientReaderWriter;
- template <class R>
- friend class ::grpc::ServerReader;
- template <class W>
- friend class ::grpc::ServerWriter;
- template <class W, class R>
- friend class ::grpc::internal::ServerReaderWriterBody;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class ::grpc::internal::RpcMethodHandler;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class ::grpc::internal::ClientStreamingHandler;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class ::grpc::internal::ServerStreamingHandler;
- template <class Streamer, bool WriteNeeded>
- friend class ::grpc::internal::TemplatedBidiStreamingHandler;
- friend class ::grpc::internal::UnknownMethodHandler;
- friend class ::grpc::Server;
- friend class ::grpc::ServerContext;
- friend class ::grpc::ServerInterface;
- template <class InputMessage, class OutputMessage>
- friend class ::grpc::internal::BlockingUnaryCallImpl;
-
- /// EXPERIMENTAL
- /// Creates a Thread Local cache to store the first event
- /// On this completion queue queued from this thread. Once
- /// initialized, it must be flushed on the same thread.
- class CompletionQueueTLSCache {
- public:
- CompletionQueueTLSCache(CompletionQueue* cq);
- ~CompletionQueueTLSCache();
- bool Flush(void** tag, bool* ok);
-
- private:
- CompletionQueue* cq_;
- bool flushed_;
- };
-
- NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
-
- /// Wraps \a grpc_completion_queue_pluck.
- /// \warning Must not be mixed with calls to \a Next.
- bool Pluck(internal::CompletionQueueTag* tag) {
- auto deadline =
- g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
- auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
- cq_, tag, deadline, nullptr);
- bool ok = ev.success != 0;
- void* ignored = tag;
- GPR_CODEGEN_ASSERT(tag->FinalizeResult(&ignored, &ok));
- GPR_CODEGEN_ASSERT(ignored == tag);
- // Ignore mutations by FinalizeResult: Pluck returns the C API status
- return ev.success != 0;
- }
-
- /// Performs a single polling pluck on \a tag.
- /// \warning Must not be mixed with calls to \a Next.
- ///
- /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
- /// shutdown. This is most likely a bug and if it is a bug, then change this
- /// implementation to simple call the other TryPluck function with a zero
- /// timeout. i.e:
- /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
- void TryPluck(internal::CompletionQueueTag* tag) {
- auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
- auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
- cq_, tag, deadline, nullptr);
- if (ev.type == GRPC_QUEUE_TIMEOUT) return;
- bool ok = ev.success != 0;
- void* ignored = tag;
- // the tag must be swallowed if using TryPluck
- GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
- }
-
- /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
- /// the pluck() was successful and returned the tag.
- ///
- /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
- /// that the tag is internal not something that is returned to the user.
- void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) {
- auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
- cq_, tag, deadline, nullptr);
- if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
- return;
- }
-
- bool ok = ev.success != 0;
- void* ignored = tag;
- GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
- }
-
- /// Manage state of avalanching operations : completion queue tags that
- /// trigger other completion queue operations. The underlying core completion
- /// queue should not really shutdown until all avalanching operations have
- /// been finalized. Note that we maintain the requirement that an avalanche
- /// registration must take place before CQ shutdown (which must be maintained
- /// elsehwere)
- void InitialAvalanching() {
- gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
- }
- void RegisterAvalanching() {
- gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
- static_cast<gpr_atm>(1));
- }
- void CompleteAvalanching();
-
- grpc_completion_queue* cq_; // owned
-
- gpr_atm avalanches_in_flight_;
-};
-
-/// A specific type of completion queue used by the processing of notifications
-/// by servers. Instantiated by \a ServerBuilder.
-class ServerCompletionQueue : public CompletionQueue {
- public:
- bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
-
- private:
- grpc_cq_polling_type polling_type_;
- friend class ServerBuilder;
- /// \param is_frequently_polled Informs the GRPC library about whether the
- /// server completion queue would be actively polled (by calling Next() or
- /// AsyncNext()). By default all server completion queues are assumed to be
- /// frequently polled.
- ServerCompletionQueue(grpc_cq_polling_type polling_type)
- : CompletionQueue(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type}),
- polling_type_(polling_type) {}
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/completion_queue.h>
#endif // GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
diff --git a/include/grpc++/impl/codegen/completion_queue_tag.h b/include/grpc++/impl/codegen/completion_queue_tag.h
index cb16bcf9ff..994fa2a904 100644
--- a/include/grpc++/impl/codegen/completion_queue_tag.h
+++ b/include/grpc++/impl/codegen/completion_queue_tag.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,24 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
#define GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
-namespace grpc {
-
-namespace internal {
-/// An interface allowing implementors to process and filter event tags.
-class CompletionQueueTag {
- public:
- virtual ~CompletionQueueTag() {}
- /// Called prior to returning from Next(), return value is the status of the
- /// operation (return status is the default thing to do). If this function
- /// returns false, the tag is dropped and not returned from the completion
- /// queue
- virtual bool FinalizeResult(void** tag, bool* status) = 0;
-};
-} // namespace internal
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
#endif // GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
diff --git a/include/grpc++/impl/codegen/config.h b/include/grpc++/impl/codegen/config.h
index b5ac9a752e..237bf38d3e 100644
--- a/include/grpc++/impl/codegen/config.h
+++ b/include/grpc++/impl/codegen/config.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,26 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CONFIG_H
#define GRPCXX_IMPL_CODEGEN_CONFIG_H
-#ifndef GRPC_CUSTOM_STRING
-#include <string>
-#define GRPC_CUSTOM_STRING std::string
-#endif
-
-/// The following macros are deprecated and appear only for users
-/// with PB files generated using gRPC 1.0.x plugins. They should
-/// not be used in new code
-#define GRPC_OVERRIDE override // deprecated
-#define GRPC_FINAL final // deprecated
-
-namespace grpc {
-
-typedef GRPC_CUSTOM_STRING string;
-
-using std::to_string;
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/config.h>
#endif // GRPCXX_IMPL_CODEGEN_CONFIG_H
diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h
index 7387fa25c6..debd74aae7 100644
--- a/include/grpc++/impl/codegen/config_protobuf.h
+++ b/include/grpc++/impl/codegen/config_protobuf.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,80 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
#define GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
-#define GRPC_OPEN_SOURCE_PROTO
-
-#ifndef GRPC_CUSTOM_PROTOBUF_INT64
-#include <google/protobuf/stubs/common.h>
-#define GRPC_CUSTOM_PROTOBUF_INT64 ::google::protobuf::int64
-#endif
-
-#ifndef GRPC_CUSTOM_MESSAGE
-#ifdef GRPC_USE_PROTO_LITE
-#include <google/protobuf/message_lite.h>
-#define GRPC_CUSTOM_MESSAGE ::google::protobuf::MessageLite
-#else
-#include <google/protobuf/message.h>
-#define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message
-#endif
-#endif
-
-#ifndef GRPC_CUSTOM_DESCRIPTOR
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor
-#define GRPC_CUSTOM_DESCRIPTORPOOL ::google::protobuf::DescriptorPool
-#define GRPC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor
-#define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor
-#define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto
-#define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor
-#define GRPC_CUSTOM_SERVICEDESCRIPTOR ::google::protobuf::ServiceDescriptor
-#define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation
-#endif
-
-#ifndef GRPC_CUSTOM_DESCRIPTORDATABASE
-#include <google/protobuf/descriptor_database.h>
-#define GRPC_CUSTOM_DESCRIPTORDATABASE ::google::protobuf::DescriptorDatabase
-#define GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE \
- ::google::protobuf::SimpleDescriptorDatabase
-#endif
-
-#ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#define GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM \
- ::google::protobuf::io::ZeroCopyOutputStream
-#define GRPC_CUSTOM_ZEROCOPYINPUTSTREAM \
- ::google::protobuf::io::ZeroCopyInputStream
-#define GRPC_CUSTOM_CODEDINPUTSTREAM ::google::protobuf::io::CodedInputStream
-#endif
-
-namespace grpc {
-namespace protobuf {
-
-typedef GRPC_CUSTOM_MESSAGE Message;
-typedef GRPC_CUSTOM_PROTOBUF_INT64 int64;
-
-typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;
-typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool;
-typedef GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase;
-typedef GRPC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor;
-typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;
-typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto;
-typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor;
-typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor;
-typedef GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase;
-typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation;
-
-namespace io {
-typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream;
-typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream;
-typedef GRPC_CUSTOM_CODEDINPUTSTREAM CodedInputStream;
-} // namespace io
-
-} // namespace protobuf
-} // namespace grpc
+#include <grpcpp/impl/codegen/config_protobuf.h>
#endif // GRPCXX_IMPL_CODEGEN_CONFIG_PROTOBUF_H
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index d7c57bebb9..ee600a9d12 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,102 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H
#define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H
-// This file should be compiled as part of grpc++.
-
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc/byte_buffer.h>
-#include <grpc/grpc.h>
-#include <grpc/impl/codegen/grpc_types.h>
-
-namespace grpc {
-
-/// Implementation of the core codegen interface.
-class CoreCodegen final : public CoreCodegenInterface {
- private:
- virtual const grpc_completion_queue_factory*
- grpc_completion_queue_factory_lookup(
- const grpc_completion_queue_attributes* attributes) override;
- virtual grpc_completion_queue* grpc_completion_queue_create(
- const grpc_completion_queue_factory* factory,
- const grpc_completion_queue_attributes* attributes,
- void* reserved) override;
- grpc_completion_queue* grpc_completion_queue_create_for_next(
- void* reserved) override;
- grpc_completion_queue* grpc_completion_queue_create_for_pluck(
- void* reserved) override;
- void grpc_completion_queue_destroy(grpc_completion_queue* cq) override;
- grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag,
- gpr_timespec deadline,
- void* reserved) override;
-
- void* gpr_malloc(size_t size) override;
- void gpr_free(void* p) override;
-
- void grpc_init() override;
- void grpc_shutdown() override;
-
- void gpr_mu_init(gpr_mu* mu) override;
- void gpr_mu_destroy(gpr_mu* mu) override;
- void gpr_mu_lock(gpr_mu* mu) override;
- void gpr_mu_unlock(gpr_mu* mu) override;
- void gpr_cv_init(gpr_cv* cv) override;
- void gpr_cv_destroy(gpr_cv* cv) override;
- int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) override;
- void gpr_cv_signal(gpr_cv* cv) override;
- void gpr_cv_broadcast(gpr_cv* cv) override;
-
- grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
- grpc_status_code status,
- const char* description,
- void* reserved) override;
- void grpc_call_ref(grpc_call* call) override;
- void grpc_call_unref(grpc_call* call) override;
- virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) override;
-
- grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb) override;
- void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
-
- int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
- grpc_byte_buffer* buffer) override;
- void grpc_byte_buffer_reader_destroy(
- grpc_byte_buffer_reader* reader) override;
- int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
- grpc_slice* slice) override;
-
- grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
- size_t nslices) override;
- grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
- void (*destroy)(void*),
- void* user_data) override;
- grpc_slice grpc_empty_slice() override;
- grpc_slice grpc_slice_malloc(size_t length) override;
- void grpc_slice_unref(grpc_slice slice) override;
- grpc_slice grpc_slice_ref(grpc_slice slice) override;
- grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) override;
- grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split) override;
- grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end) override;
- void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) override;
- void grpc_slice_buffer_pop(grpc_slice_buffer* sb) override;
- grpc_slice grpc_slice_from_static_buffer(const void* buffer,
- size_t length) override;
- grpc_slice grpc_slice_from_copied_buffer(const void* buffer,
- size_t length) override;
- void grpc_metadata_array_init(grpc_metadata_array* array) override;
- void grpc_metadata_array_destroy(grpc_metadata_array* array) override;
-
- gpr_timespec gpr_inf_future(gpr_clock_type type) override;
- gpr_timespec gpr_time_0(gpr_clock_type type) override;
-
- virtual const Status& ok() override;
- virtual const Status& cancelled() override;
-
- void assert_fail(const char* failed_assertion, const char* file,
- int line) override;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/core_codegen.h>
#endif // GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index d7ad7a4b57..03b3f675e1 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,125 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
#define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc/impl/codegen/byte_buffer_reader.h>
-#include <grpc/impl/codegen/grpc_types.h>
-#include <grpc/impl/codegen/sync.h>
-
-namespace grpc {
-
-/// Interface between the codegen library and the minimal subset of core
-/// features required by the generated code.
-///
-/// All undocumented methods are simply forwarding the call to their namesakes.
-/// Please refer to their corresponding documentation for details.
-///
-/// \warning This interface should be considered internal and private.
-class CoreCodegenInterface {
- public:
- /// Upon a failed assertion, log the error.
- virtual void assert_fail(const char* failed_assertion, const char* file,
- int line) = 0;
-
- virtual const grpc_completion_queue_factory*
- grpc_completion_queue_factory_lookup(
- const grpc_completion_queue_attributes* attributes) = 0;
- virtual grpc_completion_queue* grpc_completion_queue_create(
- const grpc_completion_queue_factory* factory,
- const grpc_completion_queue_attributes* attributes, void* reserved) = 0;
- virtual grpc_completion_queue* grpc_completion_queue_create_for_next(
- void* reserved) = 0;
- virtual grpc_completion_queue* grpc_completion_queue_create_for_pluck(
- void* reserved) = 0;
- virtual void grpc_completion_queue_destroy(grpc_completion_queue* cq) = 0;
- virtual grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq,
- void* tag,
- gpr_timespec deadline,
- void* reserved) = 0;
-
- virtual void* gpr_malloc(size_t size) = 0;
- virtual void gpr_free(void* p) = 0;
-
- // These are only to be used to fix edge cases involving grpc_init and
- // grpc_shutdown. Calling grpc_init from the codegen interface before
- // the real grpc_init is called will cause a crash, so if you use this
- // function, ensure that it is not the first call to grpc_init.
- virtual void grpc_init() = 0;
- virtual void grpc_shutdown() = 0;
-
- virtual void gpr_mu_init(gpr_mu* mu) = 0;
- virtual void gpr_mu_destroy(gpr_mu* mu) = 0;
- virtual void gpr_mu_lock(gpr_mu* mu) = 0;
- virtual void gpr_mu_unlock(gpr_mu* mu) = 0;
- virtual void gpr_cv_init(gpr_cv* cv) = 0;
- virtual void gpr_cv_destroy(gpr_cv* cv) = 0;
- virtual int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu,
- gpr_timespec abs_deadline) = 0;
- virtual void gpr_cv_signal(gpr_cv* cv) = 0;
- virtual void gpr_cv_broadcast(gpr_cv* cv) = 0;
-
- virtual grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb) = 0;
- virtual void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) = 0;
-
- virtual int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
- grpc_byte_buffer* buffer)
- GRPC_MUST_USE_RESULT = 0;
- virtual void grpc_byte_buffer_reader_destroy(
- grpc_byte_buffer_reader* reader) = 0;
- virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
- grpc_slice* slice) = 0;
-
- virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
- size_t nslices) = 0;
- virtual grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
- void (*destroy)(void*),
- void* user_data) = 0;
- virtual grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
- grpc_status_code status,
- const char* description,
- void* reserved) = 0;
- virtual void grpc_call_ref(grpc_call* call) = 0;
- virtual void grpc_call_unref(grpc_call* call) = 0;
- virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) = 0;
- virtual grpc_slice grpc_empty_slice() = 0;
- virtual grpc_slice grpc_slice_malloc(size_t length) = 0;
- virtual void grpc_slice_unref(grpc_slice slice) = 0;
- virtual grpc_slice grpc_slice_ref(grpc_slice slice) = 0;
- virtual grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) = 0;
- virtual grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split) = 0;
- virtual grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end) = 0;
- virtual void grpc_slice_buffer_add(grpc_slice_buffer* sb,
- grpc_slice slice) = 0;
- virtual void grpc_slice_buffer_pop(grpc_slice_buffer* sb) = 0;
- virtual grpc_slice grpc_slice_from_static_buffer(const void* buffer,
- size_t length) = 0;
- virtual grpc_slice grpc_slice_from_copied_buffer(const void* buffer,
- size_t length) = 0;
-
- virtual void grpc_metadata_array_init(grpc_metadata_array* array) = 0;
- virtual void grpc_metadata_array_destroy(grpc_metadata_array* array) = 0;
-
- virtual const Status& ok() = 0;
- virtual const Status& cancelled() = 0;
-
- virtual gpr_timespec gpr_inf_future(gpr_clock_type type) = 0;
- virtual gpr_timespec gpr_time_0(gpr_clock_type type) = 0;
-};
-
-extern CoreCodegenInterface* g_core_codegen_interface;
-
-/// Codegen specific version of \a GPR_ASSERT.
-#define GPR_CODEGEN_ASSERT(x) \
- do { \
- if (!(x)) { \
- grpc::g_core_codegen_interface->assert_fail(#x, __FILE__, __LINE__); \
- } \
- } while (0)
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
#endif // GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/create_auth_context.h b/include/grpc++/impl/codegen/create_auth_context.h
index afa6302c00..ef89229f4d 100644
--- a/include/grpc++/impl/codegen/create_auth_context.h
+++ b/include/grpc++/impl/codegen/create_auth_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,18 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_CREATE_AUTH_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_CREATE_AUTH_CONTEXT_H
-#include <memory>
-
-#include <grpc++/impl/codegen/security/auth_context.h>
-#include <grpc/impl/codegen/grpc_types.h>
-
-namespace grpc {
-
-std::shared_ptr<const AuthContext> CreateAuthContext(grpc_call* call);
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/create_auth_context.h>
#endif // GRPCXX_IMPL_CODEGEN_CREATE_AUTH_CONTEXT_H
diff --git a/include/grpc++/impl/codegen/grpc_library.h b/include/grpc++/impl/codegen/grpc_library.h
index 6036ad7eaa..33c3e2546c 100644
--- a/include/grpc++/impl/codegen/grpc_library.h
+++ b/include/grpc++/impl/codegen/grpc_library.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,48 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
#define GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-
-namespace grpc {
-
-class GrpcLibraryInterface {
- public:
- virtual void init() = 0;
- virtual void shutdown() = 0;
-};
-
-/// Initialized by \a grpc::GrpcLibraryInitializer from
-/// <grpc++/impl/grpc_library.h>
-extern GrpcLibraryInterface* g_glip;
-
-/// Classes that require gRPC to be initialized should inherit from this class.
-class GrpcLibraryCodegen {
- public:
- GrpcLibraryCodegen(bool call_grpc_init = true) : grpc_init_called_(false) {
- if (call_grpc_init) {
- GPR_CODEGEN_ASSERT(g_glip &&
- "gRPC library not initialized. See "
- "grpc::internal::GrpcLibraryInitializer.");
- g_glip->init();
- grpc_init_called_ = true;
- }
- }
- virtual ~GrpcLibraryCodegen() {
- if (grpc_init_called_) {
- GPR_CODEGEN_ASSERT(g_glip &&
- "gRPC library not initialized. See "
- "grpc::internal::GrpcLibraryInitializer.");
- g_glip->shutdown();
- }
- }
-
- private:
- bool grpc_init_called_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/grpc_library.h>
#endif // GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
diff --git a/include/grpc++/impl/codegen/metadata_map.h b/include/grpc++/impl/codegen/metadata_map.h
index 8dc7211ba8..41c5ad375e 100644
--- a/include/grpc++/impl/codegen/metadata_map.h
+++ b/include/grpc++/impl/codegen/metadata_map.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,43 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_METADATA_MAP_H
#define GRPCXX_IMPL_CODEGEN_METADATA_MAP_H
-#include <grpc++/impl/codegen/slice.h>
-
-namespace grpc {
-
-namespace internal {
-class MetadataMap {
- public:
- MetadataMap() { memset(&arr_, 0, sizeof(arr_)); }
-
- ~MetadataMap() {
- g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
- }
-
- void FillMap() {
- for (size_t i = 0; i < arr_.count; i++) {
- // TODO(yangg) handle duplicates?
- map_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
- StringRefFromSlice(&arr_.metadata[i].key),
- StringRefFromSlice(&arr_.metadata[i].value)));
- }
- }
-
- std::multimap<grpc::string_ref, grpc::string_ref>* map() { return &map_; }
- const std::multimap<grpc::string_ref, grpc::string_ref>* map() const {
- return &map_;
- }
- grpc_metadata_array* arr() { return &arr_; }
-
- private:
- grpc_metadata_array arr_;
- std::multimap<grpc::string_ref, grpc::string_ref> map_;
-};
-} // namespace internal
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/metadata_map.h>
#endif // GRPCXX_IMPL_CODEGEN_METADATA_MAP_H
diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h
index daf090f86c..0bdb620616 100644
--- a/include/grpc++/impl/codegen/method_handler_impl.h
+++ b/include/grpc++/impl/codegen/method_handler_impl.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,287 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
#define GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
-#include <grpc++/impl/codegen/byte_buffer.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/rpc_service_method.h>
-#include <grpc++/impl/codegen/sync_stream.h>
-
-namespace grpc {
-
-namespace internal {
-
-// Invoke the method handler, fill in the status, and
-// return whether or not we finished safely (without an exception).
-// Note that exception handling is 0-cost in most compiler/library
-// implementations (except when an exception is actually thrown),
-// so this process doesn't require additional overhead in the common case.
-// Additionally, we don't need to return if we caught an exception or not;
-// the handling is the same in either case.
-template <class Callable>
-Status CatchingFunctionHandler(Callable&& handler) {
-#if GRPC_ALLOW_EXCEPTIONS
- try {
- return handler();
- } catch (...) {
- return Status(StatusCode::UNKNOWN, "Unexpected error in RPC handling");
- }
-#else // GRPC_ALLOW_EXCEPTIONS
- return handler();
-#endif // GRPC_ALLOW_EXCEPTIONS
-}
-
-/// A wrapper class of an application provided rpc method handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class RpcMethodHandler : public MethodHandler {
- public:
- RpcMethodHandler(std::function<Status(ServiceType*, ServerContext*,
- const RequestType*, ResponseType*)>
- func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) final {
- RequestType req;
- Status status = SerializationTraits<RequestType>::Deserialize(
- param.request.bbuf_ptr(), &req);
- ResponseType rsp;
- if (status.ok()) {
- status = CatchingFunctionHandler([this, &param, &req, &rsp] {
- return func_(service_, param.server_context, &req, &rsp);
- });
- }
-
- GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
- ops;
- ops.SendInitialMetadata(param.server_context->initial_metadata_,
- param.server_context->initial_metadata_flags());
- if (param.server_context->compression_level_set()) {
- ops.set_compression_level(param.server_context->compression_level());
- }
- if (status.ok()) {
- status = ops.SendMessage(rsp);
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- /// Application provided rpc handler function.
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ResponseType*)>
- func_;
- // The class the above handler function lives in.
- ServiceType* service_;
-};
-
-/// A wrapper class of an application provided client streaming handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class ClientStreamingHandler : public MethodHandler {
- public:
- ClientStreamingHandler(
- std::function<Status(ServiceType*, ServerContext*,
- ServerReader<RequestType>*, ResponseType*)>
- func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) final {
- ServerReader<RequestType> reader(param.call, param.server_context);
- ResponseType rsp;
- Status status = CatchingFunctionHandler([this, &param, &reader, &rsp] {
- return func_(service_, param.server_context, &reader, &rsp);
- });
-
- GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
- CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
- CallOpServerSendStatus>
- ops;
- ops.SendInitialMetadata(param.server_context->initial_metadata_,
- param.server_context->initial_metadata_flags());
- if (param.server_context->compression_level_set()) {
- ops.set_compression_level(param.server_context->compression_level());
- }
- if (status.ok()) {
- status = ops.SendMessage(rsp);
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
- ResponseType*)>
- func_;
- ServiceType* service_;
-};
-
-/// A wrapper class of an application provided server streaming handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class ServerStreamingHandler : public MethodHandler {
- public:
- ServerStreamingHandler(
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ServerWriter<ResponseType>*)>
- func,
- ServiceType* service)
- : func_(func), service_(service) {}
-
- void RunHandler(const HandlerParameter& param) final {
- RequestType req;
- Status status = SerializationTraits<RequestType>::Deserialize(
- param.request.bbuf_ptr(), &req);
-
- if (status.ok()) {
- ServerWriter<ResponseType> writer(param.call, param.server_context);
- status = CatchingFunctionHandler([this, &param, &req, &writer] {
- return func_(service_, param.server_context, &req, &writer);
- });
- }
-
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
- if (!param.server_context->sent_initial_metadata_) {
- ops.SendInitialMetadata(param.server_context->initial_metadata_,
- param.server_context->initial_metadata_flags());
- if (param.server_context->compression_level_set()) {
- ops.set_compression_level(param.server_context->compression_level());
- }
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- if (param.server_context->has_pending_ops_) {
- param.call->cq()->Pluck(&param.server_context->pending_ops_);
- }
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- std::function<Status(ServiceType*, ServerContext*, const RequestType*,
- ServerWriter<ResponseType>*)>
- func_;
- ServiceType* service_;
-};
-
-/// A wrapper class of an application provided bidi-streaming handler.
-/// This also applies to server-streamed implementation of a unary method
-/// with the additional requirement that such methods must have done a
-/// write for status to be ok
-/// Since this is used by more than 1 class, the service is not passed in.
-/// Instead, it is expected to be an implicitly-captured argument of func
-/// (through bind or something along those lines)
-template <class Streamer, bool WriteNeeded>
-class TemplatedBidiStreamingHandler : public MethodHandler {
- public:
- TemplatedBidiStreamingHandler(
- std::function<Status(ServerContext*, Streamer*)> func)
- : func_(func), write_needed_(WriteNeeded) {}
-
- void RunHandler(const HandlerParameter& param) final {
- Streamer stream(param.call, param.server_context);
- Status status = CatchingFunctionHandler([this, &param, &stream] {
- return func_(param.server_context, &stream);
- });
-
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
- if (!param.server_context->sent_initial_metadata_) {
- ops.SendInitialMetadata(param.server_context->initial_metadata_,
- param.server_context->initial_metadata_flags());
- if (param.server_context->compression_level_set()) {
- ops.set_compression_level(param.server_context->compression_level());
- }
- if (write_needed_ && status.ok()) {
- // If we needed a write but never did one, we need to mark the
- // status as a fail
- status = Status(StatusCode::INTERNAL,
- "Service did not provide response message");
- }
- }
- ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
- param.call->PerformOps(&ops);
- if (param.server_context->has_pending_ops_) {
- param.call->cq()->Pluck(&param.server_context->pending_ops_);
- }
- param.call->cq()->Pluck(&ops);
- }
-
- private:
- std::function<Status(ServerContext*, Streamer*)> func_;
- const bool write_needed_;
-};
-
-template <class ServiceType, class RequestType, class ResponseType>
-class BidiStreamingHandler
- : public TemplatedBidiStreamingHandler<
- ServerReaderWriter<ResponseType, RequestType>, false> {
- public:
- BidiStreamingHandler(
- std::function<Status(ServiceType*, ServerContext*,
- ServerReaderWriter<ResponseType, RequestType>*)>
- func,
- ServiceType* service)
- : TemplatedBidiStreamingHandler<
- ServerReaderWriter<ResponseType, RequestType>, false>(std::bind(
- func, service, std::placeholders::_1, std::placeholders::_2)) {}
-};
-
-template <class RequestType, class ResponseType>
-class StreamedUnaryHandler
- : public TemplatedBidiStreamingHandler<
- ServerUnaryStreamer<RequestType, ResponseType>, true> {
- public:
- explicit StreamedUnaryHandler(
- std::function<Status(ServerContext*,
- ServerUnaryStreamer<RequestType, ResponseType>*)>
- func)
- : TemplatedBidiStreamingHandler<
- ServerUnaryStreamer<RequestType, ResponseType>, true>(func) {}
-};
-
-template <class RequestType, class ResponseType>
-class SplitServerStreamingHandler
- : public TemplatedBidiStreamingHandler<
- ServerSplitStreamer<RequestType, ResponseType>, false> {
- public:
- explicit SplitServerStreamingHandler(
- std::function<Status(ServerContext*,
- ServerSplitStreamer<RequestType, ResponseType>*)>
- func)
- : TemplatedBidiStreamingHandler<
- ServerSplitStreamer<RequestType, ResponseType>, false>(func) {}
-};
-
-/// Handle unknown method by returning UNIMPLEMENTED error.
-class UnknownMethodHandler : public MethodHandler {
- public:
- template <class T>
- static void FillOps(ServerContext* context, T* ops) {
- Status status(StatusCode::UNIMPLEMENTED, "");
- if (!context->sent_initial_metadata_) {
- ops->SendInitialMetadata(context->initial_metadata_,
- context->initial_metadata_flags());
- if (context->compression_level_set()) {
- ops->set_compression_level(context->compression_level());
- }
- context->sent_initial_metadata_ = true;
- }
- ops->ServerSendStatus(context->trailing_metadata_, status);
- }
-
- void RunHandler(const HandlerParameter& param) final {
- CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
- FillOps(param.server_context, &ops);
- param.call->PerformOps(&ops);
- param.call->cq()->Pluck(&ops);
- }
-};
-
-} // namespace internal
-} // namespace grpc
+#include <grpcpp/impl/codegen/method_handler_impl.h>
#endif // GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index 209250bba2..1f47884abc 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,253 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_PROTO_UTILS_H
#define GRPCXX_IMPL_CODEGEN_PROTO_UTILS_H
-#include <type_traits>
-
-#include <grpc++/impl/codegen/config_protobuf.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc/impl/codegen/byte_buffer_reader.h>
-#include <grpc/impl/codegen/grpc_types.h>
-#include <grpc/impl/codegen/slice.h>
-
-namespace grpc {
-
-extern CoreCodegenInterface* g_core_codegen_interface;
-
-namespace internal {
-
-class GrpcBufferWriterPeer;
-
-const int kGrpcBufferWriterMaxBufferLength = 1024 * 1024;
-
-class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
- public:
- GrpcBufferWriter(grpc_byte_buffer** bp, int block_size, int total_size)
- : block_size_(block_size),
- total_size_(total_size),
- byte_count_(0),
- have_backup_(false) {
- *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
- slice_buffer_ = &(*bp)->data.raw.slice_buffer;
- }
-
- ~GrpcBufferWriter() override {
- if (have_backup_) {
- g_core_codegen_interface->grpc_slice_unref(backup_slice_);
- }
- }
-
- bool Next(void** data, int* size) override {
- // Protobuf should not ask for more memory than total_size_.
- GPR_CODEGEN_ASSERT(byte_count_ < total_size_);
- size_t remain = total_size_ - byte_count_;
- if (have_backup_) {
- slice_ = backup_slice_;
- have_backup_ = false;
- if (GRPC_SLICE_LENGTH(slice_) > remain) {
- GRPC_SLICE_SET_LENGTH(slice_, remain);
- }
- } else {
- // When less than a whole block is needed, only allocate that much.
- // But make sure the allocated slice is not inlined.
- size_t allocate_length =
- remain > static_cast<size_t>(block_size_) ? block_size_ : remain;
- slice_ = g_core_codegen_interface->grpc_slice_malloc(
- allocate_length > GRPC_SLICE_INLINED_SIZE
- ? allocate_length
- : GRPC_SLICE_INLINED_SIZE + 1);
- }
- *data = GRPC_SLICE_START_PTR(slice_);
- // On win x64, int is only 32bit
- GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
- byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
- g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
- return true;
- }
-
- void BackUp(int count) override {
- g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_);
- if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) {
- backup_slice_ = slice_;
- } else {
- backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail(
- &slice_, GRPC_SLICE_LENGTH(slice_) - count);
- g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
- }
- // It's dangerous to keep an inlined grpc_slice as the backup slice, since
- // on a following Next() call, a reference will be returned to this slice
- // via GRPC_SLICE_START_PTR, which will not be an adddress held by
- // slice_buffer_.
- have_backup_ = backup_slice_.refcount != NULL;
- byte_count_ -= count;
- }
-
- grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
-
- protected:
- friend class GrpcBufferWriterPeer;
- const int block_size_;
- const int total_size_;
- int64_t byte_count_;
- grpc_slice_buffer* slice_buffer_;
- bool have_backup_;
- grpc_slice backup_slice_;
- grpc_slice slice_;
-};
-
-class GrpcBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
- public:
- explicit GrpcBufferReader(grpc_byte_buffer* buffer)
- : byte_count_(0), backup_count_(0), status_() {
- if (!g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader_,
- buffer)) {
- status_ = Status(StatusCode::INTERNAL,
- "Couldn't initialize byte buffer reader");
- }
- }
- ~GrpcBufferReader() override {
- g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
- }
-
- bool Next(const void** data, int* size) override {
- if (!status_.ok()) {
- return false;
- }
- if (backup_count_ > 0) {
- *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) -
- backup_count_;
- GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
- *size = (int)backup_count_;
- backup_count_ = 0;
- return true;
- }
- if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_,
- &slice_)) {
- return false;
- }
- g_core_codegen_interface->grpc_slice_unref(slice_);
- *data = GRPC_SLICE_START_PTR(slice_);
- // On win x64, int is only 32bit
- GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
- byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
- return true;
- }
-
- Status status() const { return status_; }
-
- void BackUp(int count) override { backup_count_ = count; }
-
- bool Skip(int count) override {
- const void* data;
- int size;
- while (Next(&data, &size)) {
- if (size >= count) {
- BackUp(size - count);
- return true;
- }
- // size < count;
- count -= size;
- }
- // error or we have too large count;
- return false;
- }
-
- grpc::protobuf::int64 ByteCount() const override {
- return byte_count_ - backup_count_;
- }
-
- protected:
- int64_t byte_count_;
- int64_t backup_count_;
- grpc_byte_buffer_reader reader_;
- grpc_slice slice_;
- Status status_;
-};
-
-// BufferWriter must be a subclass of io::ZeroCopyOutputStream.
-template <class BufferWriter, class T>
-Status GenericSerialize(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp, bool* own_buffer) {
- static_assert(
- std::is_base_of<protobuf::io::ZeroCopyOutputStream, BufferWriter>::value,
- "BufferWriter must be a subclass of io::ZeroCopyOutputStream");
- *own_buffer = true;
- int byte_size = msg.ByteSize();
- if ((size_t)byte_size <= GRPC_SLICE_INLINED_SIZE) {
- grpc_slice slice = g_core_codegen_interface->grpc_slice_malloc(byte_size);
- GPR_CODEGEN_ASSERT(
- GRPC_SLICE_END_PTR(slice) ==
- msg.SerializeWithCachedSizesToArray(GRPC_SLICE_START_PTR(slice)));
- *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1);
- g_core_codegen_interface->grpc_slice_unref(slice);
-
- return g_core_codegen_interface->ok();
- }
- BufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength, byte_size);
- return msg.SerializeToZeroCopyStream(&writer)
- ? g_core_codegen_interface->ok()
- : Status(StatusCode::INTERNAL, "Failed to serialize message");
-}
-
-// BufferReader must be a subclass of io::ZeroCopyInputStream.
-template <class BufferReader, class T>
-Status GenericDeserialize(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg) {
- static_assert(
- std::is_base_of<protobuf::io::ZeroCopyInputStream, BufferReader>::value,
- "BufferReader must be a subclass of io::ZeroCopyInputStream");
- if (buffer == nullptr) {
- return Status(StatusCode::INTERNAL, "No payload");
- }
- Status result = g_core_codegen_interface->ok();
- {
- BufferReader reader(buffer);
- if (!reader.status().ok()) {
- return reader.status();
- }
- ::grpc::protobuf::io::CodedInputStream decoder(&reader);
- decoder.SetTotalBytesLimit(INT_MAX, INT_MAX);
- if (!msg->ParseFromCodedStream(&decoder)) {
- result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
- }
- if (!decoder.ConsumedEntireMessage()) {
- result = Status(StatusCode::INTERNAL, "Did not read entire message");
- }
- }
- g_core_codegen_interface->grpc_byte_buffer_destroy(buffer);
- return result;
-}
-
-} // namespace internal
-
-// this is needed so the following class does not conflict with protobuf
-// serializers that utilize internal-only tools.
-#ifdef GRPC_OPEN_SOURCE_PROTO
-// This class provides a protobuf serializer. It translates between protobuf
-// objects and grpc_byte_buffers. More information about SerializationTraits can
-// be found in include/grpc++/impl/codegen/serialization_traits.h.
-template <class T>
-class SerializationTraits<T, typename std::enable_if<std::is_base_of<
- grpc::protobuf::Message, T>::value>::type> {
- public:
- static Status Serialize(const grpc::protobuf::Message& msg,
- grpc_byte_buffer** bp, bool* own_buffer) {
- return internal::GenericSerialize<internal::GrpcBufferWriter, T>(
- msg, bp, own_buffer);
- }
-
- static Status Deserialize(grpc_byte_buffer* buffer,
- grpc::protobuf::Message* msg) {
- return internal::GenericDeserialize<internal::GrpcBufferReader, T>(buffer,
- msg);
- }
-};
-#endif
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/proto_utils.h>
#endif // GRPCXX_IMPL_CODEGEN_PROTO_UTILS_H
diff --git a/include/grpc++/impl/codegen/rpc_method.h b/include/grpc++/impl/codegen/rpc_method.h
index 54e52364ef..2906c74dda 100644
--- a/include/grpc++/impl/codegen/rpc_method.h
+++ b/include/grpc++/impl/codegen/rpc_method.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,46 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
#define GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
-#include <memory>
-
-#include <grpc++/impl/codegen/channel_interface.h>
-
-namespace grpc {
-namespace internal {
-/// Descriptor of an RPC method
-class RpcMethod {
- public:
- enum RpcType {
- NORMAL_RPC = 0,
- CLIENT_STREAMING, // request streaming
- SERVER_STREAMING, // response streaming
- BIDI_STREAMING
- };
-
- RpcMethod(const char* name, RpcType type)
- : name_(name), method_type_(type), channel_tag_(NULL) {}
-
- RpcMethod(const char* name, RpcType type,
- const std::shared_ptr<ChannelInterface>& channel)
- : name_(name),
- method_type_(type),
- channel_tag_(channel->RegisterMethod(name)) {}
-
- const char* name() const { return name_; }
- RpcType method_type() const { return method_type_; }
- void SetMethodType(RpcType type) { method_type_ = type; }
- void* channel_tag() const { return channel_tag_; }
-
- private:
- const char* const name_;
- RpcType method_type_;
- void* const channel_tag_;
-};
-
-} // namespace internal
-} // namespace grpc
+#include <grpcpp/impl/codegen/rpc_method.h>
#endif // GRPCXX_IMPL_CODEGEN_RPC_METHOD_H
diff --git a/include/grpc++/impl/codegen/rpc_service_method.h b/include/grpc++/impl/codegen/rpc_service_method.h
index 5ba11e8559..999c0d5e93 100644
--- a/include/grpc++/impl/codegen/rpc_service_method.h
+++ b/include/grpc++/impl/codegen/rpc_service_method.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,63 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
#define GRPCXX_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
-#include <climits>
-#include <functional>
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <grpc++/impl/codegen/byte_buffer.h>
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/rpc_method.h>
-#include <grpc++/impl/codegen/status.h>
-
-namespace grpc {
-class ServerContext;
-
-namespace internal {
-/// Base class for running an RPC handler.
-class MethodHandler {
- public:
- virtual ~MethodHandler() {}
- struct HandlerParameter {
- HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req)
- : call(c), server_context(context) {
- request.set_buffer(req);
- }
- ~HandlerParameter() { request.Release(); }
- Call* call;
- ServerContext* server_context;
- // Handler required to destroy these contents
- ByteBuffer request;
- };
- virtual void RunHandler(const HandlerParameter& param) = 0;
-};
-
-/// Server side rpc method class
-class RpcServiceMethod : public RpcMethod {
- public:
- /// Takes ownership of the handler
- RpcServiceMethod(const char* name, RpcMethod::RpcType type,
- MethodHandler* handler)
- : RpcMethod(name, type), server_tag_(nullptr), handler_(handler) {}
-
- void set_server_tag(void* tag) { server_tag_ = tag; }
- void* server_tag() const { return server_tag_; }
- /// if MethodHandler is nullptr, then this is an async method
- MethodHandler* handler() const { return handler_.get(); }
- void ResetHandler() { handler_.reset(); }
- void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
-
- private:
- void* server_tag_;
- std::unique_ptr<MethodHandler> handler_;
-};
-} // namespace internal
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/rpc_service_method.h>
#endif // GRPCXX_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
diff --git a/include/grpc++/impl/codegen/security/auth_context.h b/include/grpc++/impl/codegen/security/auth_context.h
index 337da91347..b4663739a6 100644
--- a/include/grpc++/impl/codegen/security/auth_context.h
+++ b/include/grpc++/impl/codegen/security/auth_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,80 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
-#include <iterator>
-#include <vector>
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/string_ref.h>
-
-struct grpc_auth_context;
-struct grpc_auth_property;
-struct grpc_auth_property_iterator;
-
-namespace grpc {
-class SecureAuthContext;
-
-typedef std::pair<grpc::string_ref, grpc::string_ref> AuthProperty;
-
-class AuthPropertyIterator
- : public std::iterator<std::input_iterator_tag, const AuthProperty> {
- public:
- ~AuthPropertyIterator();
- AuthPropertyIterator& operator++();
- AuthPropertyIterator operator++(int);
- bool operator==(const AuthPropertyIterator& rhs) const;
- bool operator!=(const AuthPropertyIterator& rhs) const;
- const AuthProperty operator*();
-
- protected:
- AuthPropertyIterator();
- AuthPropertyIterator(const grpc_auth_property* property,
- const grpc_auth_property_iterator* iter);
-
- private:
- friend class SecureAuthContext;
- const grpc_auth_property* property_;
- // The following items form a grpc_auth_property_iterator.
- const grpc_auth_context* ctx_;
- size_t index_;
- const char* name_;
-};
-
-/// Class encapsulating the Authentication Information.
-///
-/// It includes the secure identity of the peer, the type of secure transport
-/// used as well as any other properties required by the authorization layer.
-class AuthContext {
- public:
- virtual ~AuthContext() {}
-
- /// Returns true if the peer is authenticated.
- virtual bool IsPeerAuthenticated() const = 0;
-
- /// A peer identity.
- ///
- /// It is, in general, comprised of one or more properties (in which case they
- /// have the same name).
- virtual std::vector<grpc::string_ref> GetPeerIdentity() const = 0;
- virtual grpc::string GetPeerIdentityPropertyName() const = 0;
-
- /// Returns all the property values with the given name.
- virtual std::vector<grpc::string_ref> FindPropertyValues(
- const grpc::string& name) const = 0;
-
- /// Iteration over all the properties.
- virtual AuthPropertyIterator begin() const = 0;
- virtual AuthPropertyIterator end() const = 0;
-
- /// Mutation functions: should only be used by an AuthMetadataProcessor.
- virtual void AddProperty(const grpc::string& key,
- const grpc::string_ref& value) = 0;
- virtual bool SetPeerIdentityPropertyName(const grpc::string& name) = 0;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/security/auth_context.h>
#endif // GRPCXX_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
diff --git a/include/grpc++/impl/codegen/serialization_traits.h b/include/grpc++/impl/codegen/serialization_traits.h
index 4d91739cc4..480575d109 100644
--- a/include/grpc++/impl/codegen/serialization_traits.h
+++ b/include/grpc++/impl/codegen/serialization_traits.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,47 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
#define GRPCXX_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
-namespace grpc {
-
-/// Defines how to serialize and deserialize some type.
-///
-/// Used for hooking different message serialization API's into GRPC.
-/// Each SerializationTraits<Message> implementation must provide the
-/// following functions:
-/// 1. static Status Serialize(const Message& msg,
-/// ByteBuffer* buffer,
-/// bool* own_buffer);
-/// OR
-/// static Status Serialize(const Message& msg,
-/// grpc_byte_buffer** buffer,
-/// bool* own_buffer);
-/// The former is preferred; the latter is deprecated
-///
-/// 2. static Status Deserialize(ByteBuffer* buffer,
-/// Message* msg);
-/// OR
-/// static Status Deserialize(grpc_byte_buffer* buffer,
-/// Message* msg);
-/// The former is preferred; the latter is deprecated
-///
-/// Serialize is required to convert message to a ByteBuffer, and
-/// return that byte buffer through *buffer. *own_buffer should
-/// be set to true if the caller owns said byte buffer, or false if
-/// ownership is retained elsewhere.
-///
-/// Deserialize is required to convert buffer into the message stored at
-/// msg. max_receive_message_size is passed in as a bound on the maximum
-/// number of message bytes Deserialize should accept.
-///
-/// Both functions return a Status, allowing them to explain what went
-/// wrong if required.
-template <class Message,
- class UnusedButHereForPartialTemplateSpecialization = void>
-class SerializationTraits;
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/serialization_traits.h>
#endif // GRPCXX_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index 57347f4fcd..1c3342d5d4 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,294 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SERVER_CONTEXT_H
#define GRPCXX_IMPL_CODEGEN_SERVER_CONTEXT_H
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <grpc/impl/codegen/compression_types.h>
-
-#include <grpc++/impl/codegen/call.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/create_auth_context.h>
-#include <grpc++/impl/codegen/metadata_map.h>
-#include <grpc++/impl/codegen/security/auth_context.h>
-#include <grpc++/impl/codegen/string_ref.h>
-#include <grpc++/impl/codegen/time.h>
-
-struct grpc_metadata;
-struct grpc_call;
-struct census_context;
-
-namespace grpc {
-class ClientContext;
-template <class W, class R>
-class ServerAsyncReader;
-template <class W>
-class ServerAsyncWriter;
-template <class W>
-class ServerAsyncResponseWriter;
-template <class W, class R>
-class ServerAsyncReaderWriter;
-template <class R>
-class ServerReader;
-template <class W>
-class ServerWriter;
-namespace internal {
-template <class W, class R>
-class ServerReaderWriterBody;
-template <class ServiceType, class RequestType, class ResponseType>
-class RpcMethodHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class ClientStreamingHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class ServerStreamingHandler;
-template <class ServiceType, class RequestType, class ResponseType>
-class BidiStreamingHandler;
-class UnknownMethodHandler;
-template <class Streamer, bool WriteNeeded>
-class TemplatedBidiStreamingHandler;
-class Call;
-} // namespace internal
-
-class CompletionQueue;
-class Server;
-class ServerInterface;
-
-namespace testing {
-class InteropServerContextInspector;
-class ServerContextTestSpouse;
-} // namespace testing
-
-/// A ServerContext allows the person implementing a service handler to:
-///
-/// - Add custom initial and trailing metadata key-value pairs that will
-/// propagated to the client side.
-/// - Control call settings such as compression and authentication.
-/// - Access metadata coming from the client.
-/// - Get performance metrics (ie, census).
-///
-/// Context settings are only relevant to the call handler they are supplied to,
-/// that is to say, they aren't sticky across multiple calls. Some of these
-/// settings, such as the compression options, can be made persistant at server
-/// construction time by specifying the approriate \a ChannelArguments
-/// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument.
-///
-/// \warning ServerContext instances should \em not be reused across rpcs.
-class ServerContext {
- public:
- ServerContext(); // for async calls
- ~ServerContext();
-
- /// Return the deadline for the server call.
- std::chrono::system_clock::time_point deadline() const {
- return Timespec2Timepoint(deadline_);
- }
-
- /// Return a \a gpr_timespec representation of the server call's deadline.
- gpr_timespec raw_deadline() const { return deadline_; }
-
- /// Add the (\a meta_key, \a meta_value) pair to the initial metadata
- /// associated with a server call. These are made available at the client side
- /// by the \a grpc::ClientContext::GetServerInitialMetadata() method.
- ///
- /// \warning This method should only be called before sending initial metadata
- /// to the client (which can happen explicitly, or implicitly when sending a
- /// a response message or status to the client).
- ///
- /// \param meta_key The metadata key. If \a meta_value is binary data, it must
- /// end in "-bin".
- /// \param meta_value The metadata value. If its value is binary, the key name
- /// must end in "-bin".
- void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
-
- /// Add the (\a meta_key, \a meta_value) pair to the initial metadata
- /// associated with a server call. These are made available at the client
- /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method.
- ///
- /// \warning This method should only be called before sending trailing
- /// metadata to the client (which happens when the call is finished and a
- /// status is sent to the client).
- ///
- /// \param meta_key The metadata key. If \a meta_value is binary data,
- /// it must end in "-bin".
- /// \param meta_value The metadata value. If its value is binary, the key name
- /// must end in "-bin".
- void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
-
- /// IsCancelled is always safe to call when using sync API.
- /// When using async API, it is only safe to call IsCancelled after
- /// the AsyncNotifyWhenDone tag has been delivered.
- bool IsCancelled() const;
-
- /// Cancel the Call from the server. This is a best-effort API and
- /// depending on when it is called, the RPC may still appear successful to
- /// the client.
- /// For example, if TryCancel() is called on a separate thread, it might race
- /// with the server handler which might return success to the client before
- /// TryCancel() was even started by the thread.
- ///
- /// It is the caller's responsibility to prevent such races and ensure that if
- /// TryCancel() is called, the serverhandler must return Status::CANCELLED.
- /// The only exception is that if the serverhandler is already returning an
- /// error status code, it is ok to not return Status::CANCELLED even if
- /// TryCancel() was called.
- ///
- /// Note that TryCancel() does not change any of the tags that are pending
- /// on the completion queue. All pending tags will still be delivered
- /// (though their ok result may reflect the effect of cancellation).
- void TryCancel() const;
-
- /// Return a collection of initial metadata key-value pairs sent from the
- /// client. Note that keys may happen more than
- /// once (ie, a \a std::multimap is returned).
- ///
- /// It is safe to use this method after initial metadata has been received,
- /// Calls always begin with the client sending initial metadata, so this is
- /// safe to access as soon as the call has begun on the server side.
- ///
- /// \return A multimap of initial metadata key-value pairs from the server.
- const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata()
- const {
- return *client_metadata_.map();
- }
-
- /// Return the compression algorithm to be used by the server call.
- grpc_compression_level compression_level() const {
- return compression_level_;
- }
-
- /// Set \a algorithm to be the compression algorithm used for the server call.
- ///
- /// \param algorithm The compression algorithm used for the server call.
- void set_compression_level(grpc_compression_level level) {
- compression_level_set_ = true;
- compression_level_ = level;
- }
-
- /// Return a bool indicating whether the compression level for this call
- /// has been set (either implicitly or through a previous call to
- /// \a set_compression_level.
- bool compression_level_set() const { return compression_level_set_; }
-
- /// Return the compression algorithm the server call will request be used.
- /// Note that the gRPC runtime may decide to ignore this request, for example,
- /// due to resource constraints, or if the server is aware the client doesn't
- /// support the requested algorithm.
- grpc_compression_algorithm compression_algorithm() const {
- return compression_algorithm_;
- }
- /// Set \a algorithm to be the compression algorithm used for the server call.
- ///
- /// \param algorithm The compression algorithm used for the server call.
- void set_compression_algorithm(grpc_compression_algorithm algorithm);
-
- /// Set the load reporting costs in \a cost_data for the call.
- void SetLoadReportingCosts(const std::vector<grpc::string>& cost_data);
-
- /// Return the authentication context for this server call.
- ///
- /// \see grpc::AuthContext.
- std::shared_ptr<const AuthContext> auth_context() const {
- if (auth_context_.get() == nullptr) {
- auth_context_ = CreateAuthContext(call_);
- }
- return auth_context_;
- }
-
- /// Return the peer uri in a string.
- /// WARNING: this value is never authenticated or subject to any security
- /// related code. It must not be used for any authentication related
- /// functionality. Instead, use auth_context.
- grpc::string peer() const;
-
- /// Get the census context associated with this server call.
- const struct census_context* census_context() const;
-
- /// Async only. Has to be called before the rpc starts.
- /// Returns the tag in completion queue when the rpc finishes.
- /// IsCancelled() can then be called to check whether the rpc was cancelled.
- void AsyncNotifyWhenDone(void* tag) {
- has_notify_when_done_tag_ = true;
- async_notify_when_done_tag_ = tag;
- }
-
- /// Should be used for framework-level extensions only.
- /// Applications never need to call this method.
- grpc_call* c_call() { return call_; }
-
- private:
- friend class ::grpc::testing::InteropServerContextInspector;
- friend class ::grpc::testing::ServerContextTestSpouse;
- friend class ::grpc::ServerInterface;
- friend class ::grpc::Server;
- template <class W, class R>
- friend class ::grpc::ServerAsyncReader;
- template <class W>
- friend class ::grpc::ServerAsyncWriter;
- template <class W>
- friend class ::grpc::ServerAsyncResponseWriter;
- template <class W, class R>
- friend class ::grpc::ServerAsyncReaderWriter;
- template <class R>
- friend class ::grpc::ServerReader;
- template <class W>
- friend class ::grpc::ServerWriter;
- template <class W, class R>
- friend class ::grpc::internal::ServerReaderWriterBody;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class ::grpc::internal::RpcMethodHandler;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class ::grpc::internal::ClientStreamingHandler;
- template <class ServiceType, class RequestType, class ResponseType>
- friend class ::grpc::internal::ServerStreamingHandler;
- template <class Streamer, bool WriteNeeded>
- friend class ::grpc::internal::TemplatedBidiStreamingHandler;
- friend class ::grpc::internal::UnknownMethodHandler;
- friend class ::grpc::ClientContext;
-
- /// Prevent copying.
- ServerContext(const ServerContext&);
- ServerContext& operator=(const ServerContext&);
-
- class CompletionOp;
-
- void BeginCompletionOp(internal::Call* call);
- /// Return the tag queued by BeginCompletionOp()
- internal::CompletionQueueTag* GetCompletionOpTag();
-
- ServerContext(gpr_timespec deadline, grpc_metadata_array* arr);
-
- void set_call(grpc_call* call) { call_ = call; }
-
- uint32_t initial_metadata_flags() const { return 0; }
-
- CompletionOp* completion_op_;
- bool has_notify_when_done_tag_;
- void* async_notify_when_done_tag_;
-
- gpr_timespec deadline_;
- grpc_call* call_;
- CompletionQueue* cq_;
- bool sent_initial_metadata_;
- mutable std::shared_ptr<const AuthContext> auth_context_;
- internal::MetadataMap client_metadata_;
- std::multimap<grpc::string, grpc::string> initial_metadata_;
- std::multimap<grpc::string, grpc::string> trailing_metadata_;
-
- bool compression_level_set_;
- grpc_compression_level compression_level_;
- grpc_compression_algorithm compression_algorithm_;
-
- internal::CallOpSet<internal::CallOpSendInitialMetadata,
- internal::CallOpSendMessage>
- pending_ops_;
- bool has_pending_ops_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/server_context.h>
#endif // GRPCXX_IMPL_CODEGEN_SERVER_CONTEXT_H
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index 3bcf4c87e7..ceea44c50c 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,259 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
#define GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
-#include <grpc++/impl/codegen/call_hook.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/rpc_service_method.h>
-#include <grpc/impl/codegen/grpc_types.h>
-
-namespace grpc {
-
-class AsyncGenericService;
-class Channel;
-class GenericServerContext;
-class ServerCompletionQueue;
-class ServerContext;
-class ServerCredentials;
-class Service;
-
-extern CoreCodegenInterface* g_core_codegen_interface;
-
-/// Models a gRPC server.
-///
-/// Servers are configured and started via \a grpc::ServerBuilder.
-namespace internal {
-class ServerAsyncStreamingInterface;
-} // namespace internal
-
-class ServerInterface : public internal::CallHook {
- public:
- virtual ~ServerInterface() {}
-
- /// Shutdown the server, blocking until all rpc processing finishes.
- /// Forcefully terminate pending calls after \a deadline expires.
- ///
- /// All completion queue associated with the server (for example, for async
- /// serving) must be shutdown *after* this method has returned:
- /// See \a ServerBuilder::AddCompletionQueue for details.
- ///
- /// \param deadline How long to wait until pending rpcs are forcefully
- /// terminated.
- template <class T>
- void Shutdown(const T& deadline) {
- ShutdownInternal(TimePoint<T>(deadline).raw_time());
- }
-
- /// Shutdown the server, waiting for all rpc processing to finish.
- ///
- /// All completion queue associated with the server (for example, for async
- /// serving) must be shutdown *after* this method has returned:
- /// See \a ServerBuilder::AddCompletionQueue for details.
- void Shutdown() {
- ShutdownInternal(
- g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_MONOTONIC));
- }
-
- /// Block waiting for all work to complete.
- ///
- /// \warning The server must be either shutting down or some other thread must
- /// call \a Shutdown for this function to ever return.
- virtual void Wait() = 0;
-
- protected:
- friend class ::grpc::Service;
-
- /// Register a service. This call does not take ownership of the service.
- /// The service must exist for the lifetime of the Server instance.
- virtual bool RegisterService(const grpc::string* host, Service* service) = 0;
-
- /// Register a generic service. This call does not take ownership of the
- /// service. The service must exist for the lifetime of the Server instance.
- virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
-
- /// Tries to bind \a server to the given \a addr.
- ///
- /// It can be invoked multiple times.
- ///
- /// \param addr The address to try to bind to the server (eg, localhost:1234,
- /// 192.168.1.1:31416, [::1]:27182, etc.).
- /// \params creds The credentials associated with the server.
- ///
- /// \return bound port number on sucess, 0 on failure.
- ///
- /// \warning It's an error to call this method on an already started server.
- virtual int AddListeningPort(const grpc::string& addr,
- ServerCredentials* creds) = 0;
-
- /// Start the server.
- ///
- /// \param cqs Completion queues for handling asynchronous services. The
- /// caller is required to keep all completion queues live until the server is
- /// destroyed.
- /// \param num_cqs How many completion queues does \a cqs hold.
- virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
-
- virtual void ShutdownInternal(gpr_timespec deadline) = 0;
-
- virtual int max_receive_message_size() const = 0;
-
- virtual grpc_server* server() = 0;
-
- virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
- internal::Call* call) = 0;
-
- class BaseAsyncRequest : public internal::CompletionQueueTag {
- public:
- BaseAsyncRequest(ServerInterface* server, ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq, void* tag,
- bool delete_on_finalize);
- virtual ~BaseAsyncRequest();
-
- bool FinalizeResult(void** tag, bool* status) override;
-
- protected:
- ServerInterface* const server_;
- ServerContext* const context_;
- internal::ServerAsyncStreamingInterface* const stream_;
- CompletionQueue* const call_cq_;
- void* const tag_;
- const bool delete_on_finalize_;
- grpc_call* call_;
- };
-
- class RegisteredAsyncRequest : public BaseAsyncRequest {
- public:
- RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq, void* tag);
-
- // uses BaseAsyncRequest::FinalizeResult
-
- protected:
- void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
- ServerCompletionQueue* notification_cq);
- };
-
- class NoPayloadAsyncRequest final : public RegisteredAsyncRequest {
- public:
- NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
- ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag)
- : RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
- IssueRequest(registered_method, nullptr, notification_cq);
- }
-
- // uses RegisteredAsyncRequest::FinalizeResult
- };
-
- template <class Message>
- class PayloadAsyncRequest final : public RegisteredAsyncRequest {
- public:
- PayloadAsyncRequest(void* registered_method, ServerInterface* server,
- ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag,
- Message* request)
- : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
- registered_method_(registered_method),
- server_(server),
- context_(context),
- stream_(stream),
- call_cq_(call_cq),
- notification_cq_(notification_cq),
- tag_(tag),
- request_(request) {
- IssueRequest(registered_method, &payload_, notification_cq);
- }
-
- bool FinalizeResult(void** tag, bool* status) override {
- if (*status) {
- if (payload_ == nullptr ||
- !SerializationTraits<Message>::Deserialize(payload_, request_)
- .ok()) {
- // If deserialization fails, we cancel the call and instantiate
- // a new instance of ourselves to request another call. We then
- // return false, which prevents the call from being returned to
- // the application.
- g_core_codegen_interface->grpc_call_cancel_with_status(
- call_, GRPC_STATUS_INTERNAL, "Unable to parse request", nullptr);
- g_core_codegen_interface->grpc_call_unref(call_);
- new PayloadAsyncRequest(registered_method_, server_, context_,
- stream_, call_cq_, notification_cq_, tag_,
- request_);
- delete this;
- return false;
- }
- }
- return RegisteredAsyncRequest::FinalizeResult(tag, status);
- }
-
- private:
- void* const registered_method_;
- ServerInterface* const server_;
- ServerContext* const context_;
- internal::ServerAsyncStreamingInterface* const stream_;
- CompletionQueue* const call_cq_;
- ServerCompletionQueue* const notification_cq_;
- void* const tag_;
- Message* const request_;
- grpc_byte_buffer* payload_;
- };
-
- class GenericAsyncRequest : public BaseAsyncRequest {
- public:
- GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag,
- bool delete_on_finalize);
-
- bool FinalizeResult(void** tag, bool* status) override;
-
- private:
- grpc_call_details call_details_;
- };
-
- template <class Message>
- void RequestAsyncCall(internal::RpcServiceMethod* method,
- ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag,
- Message* message) {
- GPR_CODEGEN_ASSERT(method);
- new PayloadAsyncRequest<Message>(method->server_tag(), this, context,
- stream, call_cq, notification_cq, tag,
- message);
- }
-
- void RequestAsyncCall(internal::RpcServiceMethod* method,
- ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- GPR_CODEGEN_ASSERT(method);
- new NoPayloadAsyncRequest(method->server_tag(), this, context, stream,
- call_cq, notification_cq, tag);
- }
-
- void RequestAsyncGenericCall(GenericServerContext* context,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq,
- void* tag) {
- new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
- tag, true);
- }
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/server_interface.h>
#endif // GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/service_type.h b/include/grpc++/impl/codegen/service_type.h
index 71c3d99d5c..be02b75bae 100644
--- a/include/grpc++/impl/codegen/service_type.h
+++ b/include/grpc++/impl/codegen/service_type.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,148 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H
#define GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/rpc_service_method.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
-#include <grpc++/impl/codegen/server_interface.h>
-#include <grpc++/impl/codegen/status.h>
-
-namespace grpc {
-
-class CompletionQueue;
-class Server;
-class ServerInterface;
-class ServerCompletionQueue;
-class ServerContext;
-
-namespace internal {
-class Call;
-class ServerAsyncStreamingInterface {
- public:
- virtual ~ServerAsyncStreamingInterface() {}
-
- /// Request notification of the sending of initial metadata to the client.
- /// Completion will be notified by \a tag on the associated completion
- /// queue. This call is optional, but if it is used, it cannot be used
- /// concurrently with or after the \a Finish method.
- ///
- /// \param[in] tag Tag identifying this request.
- virtual void SendInitialMetadata(void* tag) = 0;
-
- private:
- friend class ::grpc::ServerInterface;
- virtual void BindCall(Call* call) = 0;
-};
-} // namespace internal
-
-/// Desriptor of an RPC service and its various RPC methods
-class Service {
- public:
- Service() : server_(nullptr) {}
- virtual ~Service() {}
-
- bool has_async_methods() const {
- for (auto it = methods_.begin(); it != methods_.end(); ++it) {
- if (*it && (*it)->handler() == nullptr) {
- return true;
- }
- }
- return false;
- }
-
- bool has_synchronous_methods() const {
- for (auto it = methods_.begin(); it != methods_.end(); ++it) {
- if (*it && (*it)->handler() != nullptr) {
- return true;
- }
- }
- return false;
- }
-
- bool has_generic_methods() const {
- for (auto it = methods_.begin(); it != methods_.end(); ++it) {
- if (it->get() == nullptr) {
- return true;
- }
- }
- return false;
- }
-
- protected:
- template <class Message>
- void RequestAsyncUnary(int index, ServerContext* context, Message* request,
- internal::ServerAsyncStreamingInterface* stream,
- CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
- notification_cq, tag, request);
- }
- void RequestAsyncClientStreaming(
- int index, ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
- notification_cq, tag);
- }
- template <class Message>
- void RequestAsyncServerStreaming(
- int index, ServerContext* context, Message* request,
- internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
- notification_cq, tag, request);
- }
- void RequestAsyncBidiStreaming(
- int index, ServerContext* context,
- internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag) {
- server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
- notification_cq, tag);
- }
-
- void AddMethod(internal::RpcServiceMethod* method) {
- methods_.emplace_back(method);
- }
-
- void MarkMethodAsync(int index) {
- GPR_CODEGEN_ASSERT(
- methods_[index].get() != nullptr &&
- "Cannot mark the method as 'async' because it has already been "
- "marked as 'generic'.");
- methods_[index]->ResetHandler();
- }
-
- void MarkMethodGeneric(int index) {
- GPR_CODEGEN_ASSERT(
- methods_[index]->handler() != nullptr &&
- "Cannot mark the method as 'generic' because it has already been "
- "marked as 'async'.");
- methods_[index].reset();
- }
-
- void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
- GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
- "Cannot mark an async or generic method Streamed");
- methods_[index]->SetHandler(streamed_method);
-
- // From the server's point of view, streamed unary is a special
- // case of BIDI_STREAMING that has 1 read and 1 write, in that order,
- // and split server-side streaming is BIDI_STREAMING with 1 read and
- // any number of writes, in that order.
- methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
- }
-
- private:
- friend class Server;
- friend class ServerInterface;
- ServerInterface* server_;
- std::vector<std::unique_ptr<internal::RpcServiceMethod>> methods_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/service_type.h>
#endif // GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H
diff --git a/include/grpc++/impl/codegen/slice.h b/include/grpc++/impl/codegen/slice.h
index c185bf4fd0..6714badc37 100644
--- a/include/grpc++/impl/codegen/slice.h
+++ b/include/grpc++/impl/codegen/slice.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,113 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SLICE_H
#define GRPCXX_IMPL_CODEGEN_SLICE_H
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/string_ref.h>
-
-#include <grpc/impl/codegen/slice.h>
-
-namespace grpc {
-
-/// A wrapper around \a grpc_slice.
-///
-/// A slice represents a contiguous reference counted array of bytes.
-/// It is cheap to take references to a slice, and it is cheap to create a
-/// slice pointing to a subset of another slice.
-class Slice final {
- public:
- /// Construct an empty slice.
- Slice();
- /// Destructor - drops one reference.
- ~Slice();
-
- enum AddRef { ADD_REF };
- /// Construct a slice from \a slice, adding a reference.
- Slice(grpc_slice slice, AddRef);
-
- enum StealRef { STEAL_REF };
- /// Construct a slice from \a slice, stealing a reference.
- Slice(grpc_slice slice, StealRef);
-
- /// Allocate a slice of specified size
- Slice(size_t len);
-
- /// Construct a slice from a copied buffer
- Slice(const void* buf, size_t len);
-
- /// Construct a slice from a copied string
- Slice(const grpc::string& str);
-
- enum StaticSlice { STATIC_SLICE };
-
- /// Construct a slice from a static buffer
- Slice(const void* buf, size_t len, StaticSlice);
-
- /// Copy constructor, adds a reference.
- Slice(const Slice& other);
-
- /// Assignment, reference count is unchanged.
- Slice& operator=(Slice other) {
- std::swap(slice_, other.slice_);
- return *this;
- }
-
- /// Create a slice pointing at some data. Calls malloc to allocate a refcount
- /// for the object, and arranges that destroy will be called with the
- /// user data pointer passed in at destruction. Can be the same as buf or
- /// different (e.g., if data is part of a larger structure that must be
- /// destroyed when the data is no longer needed)
- Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data);
-
- /// Specialization of above for common case where buf == user_data
- Slice(void* buf, size_t len, void (*destroy)(void*))
- : Slice(buf, len, destroy, buf) {}
-
- /// Similar to the above but has a destroy that also takes slice length
- Slice(void* buf, size_t len, void (*destroy)(void*, size_t));
-
- /// Byte size.
- size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
-
- /// Raw pointer to the beginning (first element) of the slice.
- const uint8_t* begin() const { return GRPC_SLICE_START_PTR(slice_); }
-
- /// Raw pointer to the end (one byte \em past the last element) of the slice.
- const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); }
-
- /// Raw C slice. Caller needs to call grpc_slice_unref when done.
- grpc_slice c_slice() const;
-
- private:
- friend class ByteBuffer;
-
- grpc_slice slice_;
-};
-
-inline grpc::string_ref StringRefFromSlice(const grpc_slice* slice) {
- return grpc::string_ref(
- reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(*slice)),
- GRPC_SLICE_LENGTH(*slice));
-}
-
-inline grpc::string StringFromCopiedSlice(grpc_slice slice) {
- return grpc::string(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)),
- GRPC_SLICE_LENGTH(slice));
-}
-
-inline grpc_slice SliceReferencingString(const grpc::string& str) {
- return g_core_codegen_interface->grpc_slice_from_static_buffer(str.data(),
- str.length());
-}
-
-inline grpc_slice SliceFromCopiedString(const grpc::string& str) {
- return g_core_codegen_interface->grpc_slice_from_copied_buffer(str.data(),
- str.length());
-}
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/slice.h>
#endif // GRPCXX_IMPL_CODEGEN_SLICE_H
diff --git a/include/grpc++/impl/codegen/status.h b/include/grpc++/impl/codegen/status.h
index 6f013cf0ca..6cf9459fff 100644
--- a/include/grpc++/impl/codegen/status.h
+++ b/include/grpc++/impl/codegen/status.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,64 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_STATUS_H
#define GRPCXX_IMPL_CODEGEN_STATUS_H
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/status_code_enum.h>
-
-namespace grpc {
-
-/// Did it work? If it didn't, why?
-///
-/// See \a grpc::StatusCode for details on the available code and their meaning.
-class Status {
- public:
- /// Construct an OK instance.
- Status() : code_(StatusCode::OK) {}
-
- /// Construct an instance with associated \a code and \a error_message.
- /// It is an error to construct an OK status with non-empty \a error_message.
- Status(StatusCode code, const grpc::string& error_message)
- : code_(code), error_message_(error_message) {}
-
- /// Construct an instance with \a code, \a error_message and
- /// \a error_details. It is an error to construct an OK status with non-empty
- /// \a error_message and/or \a error_details.
- Status(StatusCode code, const grpc::string& error_message,
- const grpc::string& error_details)
- : code_(code),
- error_message_(error_message),
- binary_error_details_(error_details) {}
-
- // Pre-defined special status objects.
- /// An OK pre-defined instance.
- static const Status& OK;
- /// A CANCELLED pre-defined instance.
- static const Status& CANCELLED;
-
- /// Return the instance's error code.
- StatusCode error_code() const { return code_; }
- /// Return the instance's error message.
- grpc::string error_message() const { return error_message_; }
- /// Return the (binary) error details.
- // Usually it contains a serialized google.rpc.Status proto.
- grpc::string error_details() const { return binary_error_details_; }
-
- /// Is the status OK?
- bool ok() const { return code_ == StatusCode::OK; }
-
- // Ignores any errors. This method does nothing except potentially suppress
- // complaints from any tools that are checking that errors are not dropped on
- // the floor.
- void IgnoreError() const {}
-
- private:
- StatusCode code_;
- grpc::string error_message_;
- grpc::string binary_error_details_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/status.h>
#endif // GRPCXX_IMPL_CODEGEN_STATUS_H
diff --git a/include/grpc++/impl/codegen/status_code_enum.h b/include/grpc++/impl/codegen/status_code_enum.h
index 68da185c9e..7503eaeeca 100644
--- a/include/grpc++/impl/codegen/status_code_enum.h
+++ b/include/grpc++/impl/codegen/status_code_enum.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,127 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
#define GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
-namespace grpc {
-
-enum StatusCode {
- /// Not an error; returned on success.
- OK = 0,
-
- /// The operation was cancelled (typically by the caller).
- CANCELLED = 1,
-
- /// Unknown error. An example of where this error may be returned is if a
- /// Status value received from another address space belongs to an error-space
- /// that is not known in this address space. Also errors raised by APIs that
- /// do not return enough error information may be converted to this error.
- UNKNOWN = 2,
-
- /// Client specified an invalid argument. Note that this differs from
- /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
- /// problematic regardless of the state of the system (e.g., a malformed file
- /// name).
- INVALID_ARGUMENT = 3,
-
- /// Deadline expired before operation could complete. For operations that
- /// change the state of the system, this error may be returned even if the
- /// operation has completed successfully. For example, a successful response
- /// from a server could have been delayed long enough for the deadline to
- /// expire.
- DEADLINE_EXCEEDED = 4,
-
- /// Some requested entity (e.g., file or directory) was not found.
- NOT_FOUND = 5,
-
- /// Some entity that we attempted to create (e.g., file or directory) already
- /// exists.
- ALREADY_EXISTS = 6,
-
- /// The caller does not have permission to execute the specified operation.
- /// PERMISSION_DENIED must not be used for rejections caused by exhausting
- /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
- /// PERMISSION_DENIED must not be used if the caller can not be identified
- /// (use UNAUTHENTICATED instead for those errors).
- PERMISSION_DENIED = 7,
-
- /// The request does not have valid authentication credentials for the
- /// operation.
- UNAUTHENTICATED = 16,
-
- /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
- /// entire file system is out of space.
- RESOURCE_EXHAUSTED = 8,
-
- /// Operation was rejected because the system is not in a state required for
- /// the operation's execution. For example, directory to be deleted may be
- /// non-empty, an rmdir operation is applied to a non-directory, etc.
- ///
- /// A litmus test that may help a service implementor in deciding
- /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
- /// (a) Use UNAVAILABLE if the client can retry just the failing call.
- /// (b) Use ABORTED if the client should retry at a higher-level
- /// (e.g., restarting a read-modify-write sequence).
- /// (c) Use FAILED_PRECONDITION if the client should not retry until
- /// the system state has been explicitly fixed. E.g., if an "rmdir"
- /// fails because the directory is non-empty, FAILED_PRECONDITION
- /// should be returned since the client should not retry unless
- /// they have first fixed up the directory by deleting files from it.
- /// (d) Use FAILED_PRECONDITION if the client performs conditional
- /// REST Get/Update/Delete on a resource and the resource on the
- /// server does not match the condition. E.g., conflicting
- /// read-modify-write on the same resource.
- FAILED_PRECONDITION = 9,
-
- /// The operation was aborted, typically due to a concurrency issue like
- /// sequencer check failures, transaction aborts, etc.
- ///
- /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
- /// and UNAVAILABLE.
- ABORTED = 10,
-
- /// Operation was attempted past the valid range. E.g., seeking or reading
- /// past end of file.
- ///
- /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
- /// if the system state changes. For example, a 32-bit file system will
- /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
- /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
- /// an offset past the current file size.
- ///
- /// There is a fair bit of overlap between FAILED_PRECONDITION and
- /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
- /// when it applies so that callers who are iterating through a space can
- /// easily look for an OUT_OF_RANGE error to detect when they are done.
- OUT_OF_RANGE = 11,
-
- /// Operation is not implemented or not supported/enabled in this service.
- UNIMPLEMENTED = 12,
-
- /// Internal errors. Means some invariants expected by underlying System has
- /// been broken. If you see one of these errors, Something is very broken.
- INTERNAL = 13,
-
- /// The service is currently unavailable. This is a most likely a transient
- /// condition and may be corrected by retrying with a backoff.
- ///
- /// \warning Although data MIGHT not have been transmitted when this
- /// status occurs, there is NOT A GUARANTEE that the server has not seen
- /// anything. So in general it is unsafe to retry on this status code
- /// if the call is non-idempotent.
- ///
- /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
- /// and UNAVAILABLE.
- UNAVAILABLE = 14,
-
- /// Unrecoverable data loss or corruption.
- DATA_LOSS = 15,
-
- /// Force users to include a default branch:
- DO_NOT_USE = -1
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/status_code_enum.h>
#endif // GRPCXX_IMPL_CODEGEN_STATUS_CODE_ENUM_H
diff --git a/include/grpc++/impl/codegen/string_ref.h b/include/grpc++/impl/codegen/string_ref.h
index dbe3f197a9..66e250efdd 100644
--- a/include/grpc++/impl/codegen/string_ref.h
+++ b/include/grpc++/impl/codegen/string_ref.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,131 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_STRING_REF_H
#define GRPCXX_IMPL_CODEGEN_STRING_REF_H
-#include <string.h>
-
-#include <algorithm>
-#include <iosfwd>
-#include <iostream>
-#include <iterator>
-
-#include <grpc++/impl/codegen/config.h>
-
-namespace grpc {
-
-/// This class is a non owning reference to a string.
-///
-/// It should be a strict subset of the upcoming std::string_ref.
-///
-/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
-///
-/// The constexpr is dropped or replaced with const for legacy compiler
-/// compatibility.
-class string_ref {
- public:
- /// types
- typedef const char* const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
-
- /// constants
- const static size_t npos;
-
- /// construct/copy.
- string_ref() : data_(nullptr), length_(0) {}
- string_ref(const string_ref& other)
- : data_(other.data_), length_(other.length_) {}
- string_ref& operator=(const string_ref& rhs) {
- data_ = rhs.data_;
- length_ = rhs.length_;
- return *this;
- }
-
- string_ref(const char* s) : data_(s), length_(strlen(s)) {}
- string_ref(const char* s, size_t l) : data_(s), length_(l) {}
- string_ref(const grpc::string& s) : data_(s.data()), length_(s.length()) {}
-
- /// iterators
- const_iterator begin() const { return data_; }
- const_iterator end() const { return data_ + length_; }
- const_iterator cbegin() const { return data_; }
- const_iterator cend() const { return data_ + length_; }
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(end());
- }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(begin());
- }
- const_reverse_iterator crbegin() const {
- return const_reverse_iterator(end());
- }
- const_reverse_iterator crend() const {
- return const_reverse_iterator(begin());
- }
-
- /// capacity
- size_t size() const { return length_; }
- size_t length() const { return length_; }
- size_t max_size() const { return length_; }
- bool empty() const { return length_ == 0; }
-
- /// element access
- const char* data() const { return data_; }
-
- /// string operations
- int compare(string_ref x) const {
- size_t min_size = length_ < x.length_ ? length_ : x.length_;
- int r = memcmp(data_, x.data_, min_size);
- if (r < 0) return -1;
- if (r > 0) return 1;
- if (length_ < x.length_) return -1;
- if (length_ > x.length_) return 1;
- return 0;
- }
-
- bool starts_with(string_ref x) const {
- return length_ >= x.length_ && (memcmp(data_, x.data_, x.length_) == 0);
- }
-
- bool ends_with(string_ref x) const {
- return length_ >= x.length_ &&
- (memcmp(data_ + (length_ - x.length_), x.data_, x.length_) == 0);
- }
-
- size_t find(string_ref s) const {
- auto it = std::search(cbegin(), cend(), s.cbegin(), s.cend());
- return it == cend() ? npos : std::distance(cbegin(), it);
- }
-
- size_t find(char c) const {
- auto it = std::find(cbegin(), cend(), c);
- return it == cend() ? npos : std::distance(cbegin(), it);
- }
-
- string_ref substr(size_t pos, size_t n = npos) const {
- if (pos > length_) pos = length_;
- if (n > (length_ - pos)) n = length_ - pos;
- return string_ref(data_ + pos, n);
- }
-
- private:
- const char* data_;
- size_t length_;
-};
-
-/// Comparison operators
-inline bool operator==(string_ref x, string_ref y) { return x.compare(y) == 0; }
-inline bool operator!=(string_ref x, string_ref y) { return x.compare(y) != 0; }
-inline bool operator<(string_ref x, string_ref y) { return x.compare(y) < 0; }
-inline bool operator<=(string_ref x, string_ref y) { return x.compare(y) <= 0; }
-inline bool operator>(string_ref x, string_ref y) { return x.compare(y) > 0; }
-inline bool operator>=(string_ref x, string_ref y) { return x.compare(y) >= 0; }
-
-inline std::ostream& operator<<(std::ostream& out, const string_ref& string) {
- return out << grpc::string(string.begin(), string.end());
-}
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/string_ref.h>
#endif // GRPCXX_IMPL_CODEGEN_STRING_REF_H
diff --git a/include/grpc++/impl/codegen/stub_options.h b/include/grpc++/impl/codegen/stub_options.h
index 380d052a6a..07cb4417b7 100644
--- a/include/grpc++/impl/codegen/stub_options.h
+++ b/include/grpc++/impl/codegen/stub_options.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,14 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_STUB_OPTIONS_H
#define GRPCXX_IMPL_CODEGEN_STUB_OPTIONS_H
-namespace grpc {
-
-/// Useful interface for generated stubs
-class StubOptions {};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/stub_options.h>
#endif // GRPCXX_IMPL_CODEGEN_STUB_OPTIONS_H
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index a6dd26fb00..1e6ba27bf5 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,919 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_SYNC_STREAM_H
#define GRPCXX_IMPL_CODEGEN_SYNC_STREAM_H
-#include <grpc++/impl/codegen/call.h>
-#include <grpc++/impl/codegen/channel_interface.h>
-#include <grpc++/impl/codegen/client_context.h>
-#include <grpc++/impl/codegen/completion_queue.h>
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/server_context.h>
-#include <grpc++/impl/codegen/service_type.h>
-#include <grpc++/impl/codegen/status.h>
-
-namespace grpc {
-
-namespace internal {
-/// Common interface for all synchronous client side streaming.
-class ClientStreamingInterface {
- public:
- virtual ~ClientStreamingInterface() {}
-
- /// Block waiting until the stream finishes and a final status of the call is
- /// available.
- ///
- /// It is appropriate to call this method when both:
- /// * the calling code (client-side) has no more message to send
- /// (this can be declared implicitly by calling this method, or
- /// explicitly through an earlier call to <i>WritesDone</i> method of the
- /// class in use, e.g. \a ClientWriterInterface::WritesDone or
- /// \a ClientReaderWriterInterface::WritesDone).
- /// * there are no more messages to be received from the server (which can
- /// be known implicitly, or explicitly from an earlier call to \a
- /// ReaderInterface::Read that returned "false").
- ///
- /// This function will return either:
- /// - when all incoming messages have been read and the server has
- /// returned status.
- /// - when the server has returned a non-OK status.
- /// - OR when the call failed for some reason and the library generated a
- /// status.
- ///
- /// Return values:
- /// - \a Status contains the status code, message and details for the call
- /// - the \a ClientContext associated with this call is updated with
- /// possible trailing metadata sent from the server.
- virtual Status Finish() = 0;
-};
-
-/// Common interface for all synchronous server side streaming.
-class ServerStreamingInterface {
- public:
- virtual ~ServerStreamingInterface() {}
-
- /// Block to send initial metadata to client.
- /// This call is optional, but if it is used, it cannot be used concurrently
- /// with or after the \a Finish method.
- ///
- /// The initial metadata that will be sent to the client will be
- /// taken from the \a ServerContext associated with the call.
- virtual void SendInitialMetadata() = 0;
-};
-
-/// An interface that yields a sequence of messages of type \a R.
-template <class R>
-class ReaderInterface {
- public:
- virtual ~ReaderInterface() {}
-
- /// Get an upper bound on the next message size available for reading on this
- /// stream.
- virtual bool NextMessageSize(uint32_t* sz) = 0;
-
- /// Block to read a message and parse to \a msg. Returns \a true on success.
- /// This is thread-safe with respect to \a Write or \WritesDone methods on
- /// the same stream. It should not be called concurrently with another \a
- /// Read on the same stream as the order of delivery will not be defined.
- ///
- /// \param[out] msg The read message.
- ///
- /// \return \a false when there will be no more incoming messages, either
- /// because the other side has called \a WritesDone() or the stream has failed
- /// (or been cancelled).
- virtual bool Read(R* msg) = 0;
-};
-
-/// An interface that can be fed a sequence of messages of type \a W.
-template <class W>
-class WriterInterface {
- public:
- virtual ~WriterInterface() {}
-
- /// Block to write \a msg to the stream with WriteOptions \a options.
- /// This is thread-safe with respect to \a ReaderInterface::Read
- ///
- /// \param msg The message to be written to the stream.
- /// \param options The WriteOptions affecting the write operation.
- ///
- /// \return \a true on success, \a false when the stream has been closed.
- virtual bool Write(const W& msg, WriteOptions options) = 0;
-
- /// Block to write \a msg to the stream with default write options.
- /// This is thread-safe with respect to \a ReaderInterface::Read
- ///
- /// \param msg The message to be written to the stream.
- ///
- /// \return \a true on success, \a false when the stream has been closed.
- inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
-
- /// Write \a msg and coalesce it with the writing of trailing metadata, using
- /// WriteOptions \a options.
- ///
- /// For client, WriteLast is equivalent of performing Write and WritesDone in
- /// a single step. \a msg and trailing metadata are coalesced and sent on wire
- /// by calling this function. For server, WriteLast buffers the \a msg.
- /// The writing of \a msg is held until the service handler returns,
- /// where \a msg and trailing metadata are coalesced and sent on wire.
- /// Note that WriteLast can only buffer \a msg up to the flow control window
- /// size. If \a msg size is larger than the window size, it will be sent on
- /// wire without buffering.
- ///
- /// \param[in] msg The message to be written to the stream.
- /// \param[in] options The WriteOptions to be used to write this message.
- void WriteLast(const W& msg, WriteOptions options) {
- Write(msg, options.set_last_message());
- }
-};
-
-} // namespace internal
-
-/// Client-side interface for streaming reads of message of type \a R.
-template <class R>
-class ClientReaderInterface : public internal::ClientStreamingInterface,
- public internal::ReaderInterface<R> {
- public:
- /// Block to wait for initial metadata from server. The received metadata
- /// can only be accessed after this call returns. Should only be called before
- /// the first read. Calling this method is optional, and if it is not called
- /// the metadata will be available in ClientContext after the first read.
- virtual void WaitForInitialMetadata() = 0;
-};
-
-namespace internal {
-template <class R>
-class ClientReaderFactory {
- public:
- template <class W>
- static ClientReader<R>* Create(ChannelInterface* channel,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context, const W& request) {
- return new ClientReader<R>(channel, method, context, request);
- }
-};
-} // namespace internal
-
-/// Synchronous (blocking) client-side API for doing server-streaming RPCs,
-/// where the stream of messages coming from the server has messages
-/// of type \a R.
-template <class R>
-class ClientReader final : public ClientReaderInterface<R> {
- public:
- /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
- /// semantics.
- ///
- // Side effect:
- /// Once complete, the initial metadata read from
- /// the server will be accessable through the \a ClientContext used to
- /// construct this object.
- void WaitForInitialMetadata() override {
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- ops;
- ops.RecvInitialMetadata(context_);
- call_.PerformOps(&ops);
- cq_.Pluck(&ops); /// status ignored
- }
-
- bool NextMessageSize(uint32_t* sz) override {
- *sz = call_.max_receive_message_size();
- return true;
- }
-
- /// See the \a ReaderInterface.Read method for semantics.
- /// Side effect:
- /// This also receives initial metadata from the server, if not
- /// already received (if initial metadata is received, it can be then
- /// accessed through the \a ClientContext associated with this call).
- bool Read(R* msg) override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpRecvMessage<R>>
- ops;
- if (!context_->initial_metadata_received_) {
- ops.RecvInitialMetadata(context_);
- }
- ops.RecvMessage(msg);
- call_.PerformOps(&ops);
- return cq_.Pluck(&ops) && ops.got_message;
- }
-
- /// See the \a ClientStreamingInterface.Finish method for semantics.
- ///
- /// Side effect:
- /// The \a ClientContext associated with this call is updated with
- /// possible metadata received from the server.
- Status Finish() override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops;
- Status status;
- ops.ClientRecvStatus(context_, &status);
- call_.PerformOps(&ops);
- GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
- return status;
- }
-
- private:
- friend class internal::ClientReaderFactory<R>;
- ClientContext* context_;
- CompletionQueue cq_;
- ::grpc::internal::Call call_;
-
- /// Block to create a stream and write the initial metadata and \a request
- /// out. Note that \a context will be used to fill in custom initial
- /// metadata used to send to the server when starting the call.
- template <class W>
- ClientReader(::grpc::ChannelInterface* channel,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context, const W& request)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- // TODO(ctiller): don't assert
- GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
- ops.ClientSendClose();
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
-};
-
-/// Client-side interface for streaming writes of message type \a W.
-template <class W>
-class ClientWriterInterface : public internal::ClientStreamingInterface,
- public internal::WriterInterface<W> {
- public:
- /// Half close writing from the client. (signal that the stream of messages
- /// coming from the client is complete).
- /// Blocks until currently-pending writes are completed.
- /// Thread safe with respect to \a ReaderInterface::Read operations only
- ///
- /// \return Whether the writes were successful.
- virtual bool WritesDone() = 0;
-};
-
-namespace internal {
-template <class W>
-class ClientWriterFactory {
- public:
- template <class R>
- static ClientWriter<W>* Create(::grpc::ChannelInterface* channel,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context, R* response) {
- return new ClientWriter<W>(channel, method, context, response);
- }
-};
-} // namespace internal
-
-/// Synchronous (blocking) client-side API for doing client-streaming RPCs,
-/// where the outgoing message stream coming from the client has messages of
-/// type \a W.
-template <class W>
-class ClientWriter : public ClientWriterInterface<W> {
- public:
- /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
- /// semantics.
- ///
- // Side effect:
- /// Once complete, the initial metadata read from the server will be
- /// accessable through the \a ClientContext used to construct this object.
- void WaitForInitialMetadata() {
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- ops;
- ops.RecvInitialMetadata(context_);
- call_.PerformOps(&ops);
- cq_.Pluck(&ops); // status ignored
- }
-
- /// See the WriterInterface.Write(const W& msg, WriteOptions options) method
- /// for semantics.
- ///
- /// Side effect:
- /// Also sends initial metadata if not already sent (using the
- /// \a ClientContext associated with this call).
- using ::grpc::internal::WriterInterface<W>::Write;
- bool Write(const W& msg, WriteOptions options) override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- ops;
-
- if (options.is_last_message()) {
- options.set_buffer_hint();
- ops.ClientSendClose();
- }
- if (context_->initial_metadata_corked_) {
- ops.SendInitialMetadata(context_->send_initial_metadata_,
- context_->initial_metadata_flags());
- context_->set_initial_metadata_corked(false);
- }
- if (!ops.SendMessage(msg, options).ok()) {
- return false;
- }
-
- call_.PerformOps(&ops);
- return cq_.Pluck(&ops);
- }
-
- bool WritesDone() override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
- ops.ClientSendClose();
- call_.PerformOps(&ops);
- return cq_.Pluck(&ops);
- }
-
- /// See the ClientStreamingInterface.Finish method for semantics.
- /// Side effects:
- /// - Also receives initial metadata if not already received.
- /// - Attempts to fill in the \a response parameter passed
- /// to the constructor of this instance with the response
- /// message from the server.
- Status Finish() override {
- Status status;
- if (!context_->initial_metadata_received_) {
- finish_ops_.RecvInitialMetadata(context_);
- }
- finish_ops_.ClientRecvStatus(context_, &status);
- call_.PerformOps(&finish_ops_);
- GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_));
- return status;
- }
-
- private:
- friend class internal::ClientWriterFactory<W>;
-
- /// Block to create a stream (i.e. send request headers and other initial
- /// metadata to the server). Note that \a context will be used to fill
- /// in custom initial metadata. \a response will be filled in with the
- /// single expected response message from the server upon a successful
- /// call to the \a Finish method of this instance.
- template <class R>
- ClientWriter(ChannelInterface* channel,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context, R* response)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- finish_ops_.RecvMessage(response);
- finish_ops_.AllowNoMessage();
-
- if (!context_->initial_metadata_corked_) {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
- ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
- }
-
- ClientContext* context_;
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpGenericRecvMessage,
- ::grpc::internal::CallOpClientRecvStatus>
- finish_ops_;
- CompletionQueue cq_;
- ::grpc::internal::Call call_;
-};
-
-/// Client-side interface for bi-directional streaming with
-/// client-to-server stream messages of type \a W and
-/// server-to-client stream messages of type \a R.
-template <class W, class R>
-class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
- public internal::WriterInterface<W>,
- public internal::ReaderInterface<R> {
- public:
- /// Block to wait for initial metadata from server. The received metadata
- /// can only be accessed after this call returns. Should only be called before
- /// the first read. Calling this method is optional, and if it is not called
- /// the metadata will be available in ClientContext after the first read.
- virtual void WaitForInitialMetadata() = 0;
-
- /// Half close writing from the client. (signal that the stream of messages
- /// coming from the clinet is complete).
- /// Blocks until currently-pending writes are completed.
- /// Thread-safe with respect to \a ReaderInterface::Read
- ///
- /// \return Whether the writes were successful.
- virtual bool WritesDone() = 0;
-};
-
-namespace internal {
-template <class W, class R>
-class ClientReaderWriterFactory {
- public:
- static ClientReaderWriter<W, R>* Create(
- ::grpc::ChannelInterface* channel,
- const ::grpc::internal::RpcMethod& method, ClientContext* context) {
- return new ClientReaderWriter<W, R>(channel, method, context);
- }
-};
-} // namespace internal
-
-/// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
-/// where the outgoing message stream coming from the client has messages of
-/// type \a W, and the incoming messages stream coming from the server has
-/// messages of type \a R.
-template <class W, class R>
-class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
- public:
- /// Block waiting to read initial metadata from the server.
- /// This call is optional, but if it is used, it cannot be used concurrently
- /// with or after the \a Finish method.
- ///
- /// Once complete, the initial metadata read from the server will be
- /// accessable through the \a ClientContext used to construct this object.
- void WaitForInitialMetadata() override {
- GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
-
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
- ops;
- ops.RecvInitialMetadata(context_);
- call_.PerformOps(&ops);
- cq_.Pluck(&ops); // status ignored
- }
-
- bool NextMessageSize(uint32_t* sz) override {
- *sz = call_.max_receive_message_size();
- return true;
- }
-
- /// See the \a ReaderInterface.Read method for semantics.
- /// Side effect:
- /// Also receives initial metadata if not already received (updates the \a
- /// ClientContext associated with this call in that case).
- bool Read(R* msg) override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpRecvMessage<R>>
- ops;
- if (!context_->initial_metadata_received_) {
- ops.RecvInitialMetadata(context_);
- }
- ops.RecvMessage(msg);
- call_.PerformOps(&ops);
- return cq_.Pluck(&ops) && ops.got_message;
- }
-
- /// See the \a WriterInterface.Write method for semantics.
- ///
- /// Side effect:
- /// Also sends initial metadata if not already sent (using the
- /// \a ClientContext associated with this call to fill in values).
- using ::grpc::internal::WriterInterface<W>::Write;
- bool Write(const W& msg, WriteOptions options) override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
- ::grpc::internal::CallOpSendMessage,
- ::grpc::internal::CallOpClientSendClose>
- ops;
-
- if (options.is_last_message()) {
- options.set_buffer_hint();
- ops.ClientSendClose();
- }
- if (context_->initial_metadata_corked_) {
- ops.SendInitialMetadata(context_->send_initial_metadata_,
- context_->initial_metadata_flags());
- context_->set_initial_metadata_corked(false);
- }
- if (!ops.SendMessage(msg, options).ok()) {
- return false;
- }
-
- call_.PerformOps(&ops);
- return cq_.Pluck(&ops);
- }
-
- bool WritesDone() override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
- ops.ClientSendClose();
- call_.PerformOps(&ops);
- return cq_.Pluck(&ops);
- }
-
- /// See the ClientStreamingInterface.Finish method for semantics.
- ///
- /// Side effect:
- /// - the \a ClientContext associated with this call is updated with
- /// possible trailing metadata sent from the server.
- Status Finish() override {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
- ::grpc::internal::CallOpClientRecvStatus>
- ops;
- if (!context_->initial_metadata_received_) {
- ops.RecvInitialMetadata(context_);
- }
- Status status;
- ops.ClientRecvStatus(context_, &status);
- call_.PerformOps(&ops);
- GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
- return status;
- }
-
- private:
- friend class internal::ClientReaderWriterFactory<W, R>;
-
- ClientContext* context_;
- CompletionQueue cq_;
- ::grpc::internal::Call call_;
-
- /// Block to create a stream and write the initial metadata and \a request
- /// out. Note that \a context will be used to fill in custom initial metadata
- /// used to send to the server when starting the call.
- ClientReaderWriter(::grpc::ChannelInterface* channel,
- const ::grpc::internal::RpcMethod& method,
- ClientContext* context)
- : context_(context),
- cq_(grpc_completion_queue_attributes{
- GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
- GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
- call_(channel->CreateCall(method, context, &cq_)) {
- if (!context_->initial_metadata_corked_) {
- ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
- ops;
- ops.SendInitialMetadata(context->send_initial_metadata_,
- context->initial_metadata_flags());
- call_.PerformOps(&ops);
- cq_.Pluck(&ops);
- }
- }
-};
-
-/// Server-side interface for streaming reads of message of type \a R.
-template <class R>
-class ServerReaderInterface : public internal::ServerStreamingInterface,
- public internal::ReaderInterface<R> {};
-
-/// Synchronous (blocking) server-side API for doing client-streaming RPCs,
-/// where the incoming message stream coming from the client has messages of
-/// type \a R.
-template <class R>
-class ServerReader final : public ServerReaderInterface<R> {
- public:
- /// See the \a ServerStreamingInterface.SendInitialMetadata method
- /// for semantics. Note that initial metadata will be affected by the
- /// \a ServerContext associated with this call.
- void SendInitialMetadata() override {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ops.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_->PerformOps(&ops);
- call_->cq()->Pluck(&ops);
- }
-
- bool NextMessageSize(uint32_t* sz) override {
- *sz = call_->max_receive_message_size();
- return true;
- }
-
- bool Read(R* msg) override {
- internal::CallOpSet<internal::CallOpRecvMessage<R>> ops;
- ops.RecvMessage(msg);
- call_->PerformOps(&ops);
- return call_->cq()->Pluck(&ops) && ops.got_message;
- }
-
- private:
- internal::Call* const call_;
- ServerContext* const ctx_;
-
- template <class ServiceType, class RequestType, class ResponseType>
- friend class internal::ClientStreamingHandler;
-
- ServerReader(internal::Call* call, ServerContext* ctx)
- : call_(call), ctx_(ctx) {}
-};
-
-/// Server-side interface for streaming writes of message of type \a W.
-template <class W>
-class ServerWriterInterface : public internal::ServerStreamingInterface,
- public internal::WriterInterface<W> {};
-
-/// Synchronous (blocking) server-side API for doing for doing a
-/// server-streaming RPCs, where the outgoing message stream coming from the
-/// server has messages of type \a W.
-template <class W>
-class ServerWriter final : public ServerWriterInterface<W> {
- public:
- /// See the \a ServerStreamingInterface.SendInitialMetadata method
- /// for semantics.
- /// Note that initial metadata will be affected by the
- /// \a ServerContext associated with this call.
- void SendInitialMetadata() override {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ops.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_->PerformOps(&ops);
- call_->cq()->Pluck(&ops);
- }
-
- /// See the \a WriterInterface.Write method for semantics.
- ///
- /// Side effect:
- /// Also sends initial metadata if not already sent (using the
- /// \a ClientContext associated with this call to fill in values).
- using internal::WriterInterface<W>::Write;
- bool Write(const W& msg, WriteOptions options) override {
- if (options.is_last_message()) {
- options.set_buffer_hint();
- }
-
- if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) {
- return false;
- }
- if (!ctx_->sent_initial_metadata_) {
- ctx_->pending_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- call_->PerformOps(&ctx_->pending_ops_);
- // if this is the last message we defer the pluck until AFTER we start
- // the trailing md op. This prevents hangs. See
- // https://github.com/grpc/grpc/issues/11546
- if (options.is_last_message()) {
- ctx_->has_pending_ops_ = true;
- return true;
- }
- ctx_->has_pending_ops_ = false;
- return call_->cq()->Pluck(&ctx_->pending_ops_);
- }
-
- private:
- internal::Call* const call_;
- ServerContext* const ctx_;
-
- template <class ServiceType, class RequestType, class ResponseType>
- friend class internal::ServerStreamingHandler;
-
- ServerWriter(internal::Call* call, ServerContext* ctx)
- : call_(call), ctx_(ctx) {}
-};
-
-/// Server-side interface for bi-directional streaming.
-template <class W, class R>
-class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
- public internal::WriterInterface<W>,
- public internal::ReaderInterface<R> {};
-
-/// Actual implementation of bi-directional streaming
-namespace internal {
-template <class W, class R>
-class ServerReaderWriterBody final {
- public:
- ServerReaderWriterBody(Call* call, ServerContext* ctx)
- : call_(call), ctx_(ctx) {}
-
- void SendInitialMetadata() {
- GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- CallOpSet<CallOpSendInitialMetadata> ops;
- ops.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ops.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- call_->PerformOps(&ops);
- call_->cq()->Pluck(&ops);
- }
-
- bool NextMessageSize(uint32_t* sz) {
- *sz = call_->max_receive_message_size();
- return true;
- }
-
- bool Read(R* msg) {
- CallOpSet<CallOpRecvMessage<R>> ops;
- ops.RecvMessage(msg);
- call_->PerformOps(&ops);
- return call_->cq()->Pluck(&ops) && ops.got_message;
- }
-
- bool Write(const W& msg, WriteOptions options) {
- if (options.is_last_message()) {
- options.set_buffer_hint();
- }
- if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) {
- return false;
- }
- if (!ctx_->sent_initial_metadata_) {
- ctx_->pending_ops_.SendInitialMetadata(ctx_->initial_metadata_,
- ctx_->initial_metadata_flags());
- if (ctx_->compression_level_set()) {
- ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
- }
- ctx_->sent_initial_metadata_ = true;
- }
- call_->PerformOps(&ctx_->pending_ops_);
- // if this is the last message we defer the pluck until AFTER we start
- // the trailing md op. This prevents hangs. See
- // https://github.com/grpc/grpc/issues/11546
- if (options.is_last_message()) {
- ctx_->has_pending_ops_ = true;
- return true;
- }
- ctx_->has_pending_ops_ = false;
- return call_->cq()->Pluck(&ctx_->pending_ops_);
- }
-
- private:
- Call* const call_;
- ServerContext* const ctx_;
-};
-
-} // namespace internal
-
-/// Synchronous (blocking) server-side API for a bidirectional
-/// streaming call, where the incoming message stream coming from the client has
-/// messages of type \a R, and the outgoing message streaming coming from
-/// the server has messages of type \a W.
-template <class W, class R>
-class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
- public:
- /// See the \a ServerStreamingInterface.SendInitialMetadata method
- /// for semantics. Note that initial metadata will be affected by the
- /// \a ServerContext associated with this call.
- void SendInitialMetadata() override { body_.SendInitialMetadata(); }
-
- bool NextMessageSize(uint32_t* sz) override {
- return body_.NextMessageSize(sz);
- }
-
- bool Read(R* msg) override { return body_.Read(msg); }
-
- /// See the \a WriterInterface.Write(const W& msg, WriteOptions options)
- /// method for semantics.
- /// Side effect:
- /// Also sends initial metadata if not already sent (using the \a
- /// ServerContext associated with this call).
- using internal::WriterInterface<W>::Write;
- bool Write(const W& msg, WriteOptions options) override {
- return body_.Write(msg, options);
- }
-
- private:
- internal::ServerReaderWriterBody<W, R> body_;
-
- friend class internal::TemplatedBidiStreamingHandler<ServerReaderWriter<W, R>,
- false>;
- ServerReaderWriter(internal::Call* call, ServerContext* ctx)
- : body_(call, ctx) {}
-};
-
-/// A class to represent a flow-controlled unary call. This is something
-/// of a hybrid between conventional unary and streaming. This is invoked
-/// through a unary call on the client side, but the server responds to it
-/// as though it were a single-ping-pong streaming call. The server can use
-/// the \a NextMessageSize method to determine an upper-bound on the size of
-/// the message. A key difference relative to streaming: ServerUnaryStreamer
-/// must have exactly 1 Read and exactly 1 Write, in that order, to function
-/// correctly. Otherwise, the RPC is in error.
-template <class RequestType, class ResponseType>
-class ServerUnaryStreamer final
- : public ServerReaderWriterInterface<ResponseType, RequestType> {
- public:
- /// Block to send initial metadata to client.
- /// Implicit input parameter:
- /// - the \a ServerContext associated with this call will be used for
- /// sending initial metadata.
- void SendInitialMetadata() override { body_.SendInitialMetadata(); }
-
- /// Get an upper bound on the request message size from the client.
- bool NextMessageSize(uint32_t* sz) override {
- return body_.NextMessageSize(sz);
- }
-
- /// Read a message of type \a R into \a msg. Completion will be notified by \a
- /// tag on the associated completion queue.
- /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
- /// should not be called concurrently with other streaming APIs
- /// on the same stream. It is not meaningful to call it concurrently
- /// with another \a ReaderInterface::Read on the same stream since reads on
- /// the same stream are delivered in order.
- ///
- /// \param[out] msg Where to eventually store the read message.
- /// \param[in] tag The tag identifying the operation.
- bool Read(RequestType* request) override {
- if (read_done_) {
- return false;
- }
- read_done_ = true;
- return body_.Read(request);
- }
-
- /// Block to write \a msg to the stream with WriteOptions \a options.
- /// This is thread-safe with respect to \a ReaderInterface::Read
- ///
- /// \param msg The message to be written to the stream.
- /// \param options The WriteOptions affecting the write operation.
- ///
- /// \return \a true on success, \a false when the stream has been closed.
- using internal::WriterInterface<ResponseType>::Write;
- bool Write(const ResponseType& response, WriteOptions options) override {
- if (write_done_ || !read_done_) {
- return false;
- }
- write_done_ = true;
- return body_.Write(response, options);
- }
-
- private:
- internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
- bool read_done_;
- bool write_done_;
-
- friend class internal::TemplatedBidiStreamingHandler<
- ServerUnaryStreamer<RequestType, ResponseType>, true>;
- ServerUnaryStreamer(internal::Call* call, ServerContext* ctx)
- : body_(call, ctx), read_done_(false), write_done_(false) {}
-};
-
-/// A class to represent a flow-controlled server-side streaming call.
-/// This is something of a hybrid between server-side and bidi streaming.
-/// This is invoked through a server-side streaming call on the client side,
-/// but the server responds to it as though it were a bidi streaming call that
-/// must first have exactly 1 Read and then any number of Writes.
-template <class RequestType, class ResponseType>
-class ServerSplitStreamer final
- : public ServerReaderWriterInterface<ResponseType, RequestType> {
- public:
- /// Block to send initial metadata to client.
- /// Implicit input parameter:
- /// - the \a ServerContext associated with this call will be used for
- /// sending initial metadata.
- void SendInitialMetadata() override { body_.SendInitialMetadata(); }
-
- /// Get an upper bound on the request message size from the client.
- bool NextMessageSize(uint32_t* sz) override {
- return body_.NextMessageSize(sz);
- }
-
- /// Read a message of type \a R into \a msg. Completion will be notified by \a
- /// tag on the associated completion queue.
- /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
- /// should not be called concurrently with other streaming APIs
- /// on the same stream. It is not meaningful to call it concurrently
- /// with another \a ReaderInterface::Read on the same stream since reads on
- /// the same stream are delivered in order.
- ///
- /// \param[out] msg Where to eventually store the read message.
- /// \param[in] tag The tag identifying the operation.
- bool Read(RequestType* request) override {
- if (read_done_) {
- return false;
- }
- read_done_ = true;
- return body_.Read(request);
- }
-
- /// Block to write \a msg to the stream with WriteOptions \a options.
- /// This is thread-safe with respect to \a ReaderInterface::Read
- ///
- /// \param msg The message to be written to the stream.
- /// \param options The WriteOptions affecting the write operation.
- ///
- /// \return \a true on success, \a false when the stream has been closed.
- using internal::WriterInterface<ResponseType>::Write;
- bool Write(const ResponseType& response, WriteOptions options) override {
- return read_done_ && body_.Write(response, options);
- }
-
- private:
- internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
- bool read_done_;
-
- friend class internal::TemplatedBidiStreamingHandler<
- ServerSplitStreamer<RequestType, ResponseType>, false>;
- ServerSplitStreamer(internal::Call* call, ServerContext* ctx)
- : body_(call, ctx), read_done_(false) {}
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/sync_stream.h>
#endif // GRPCXX_IMPL_CODEGEN_SYNC_STREAM_H
diff --git a/include/grpc++/impl/codegen/time.h b/include/grpc++/impl/codegen/time.h
index d464d6ea13..f9b70f8313 100644
--- a/include/grpc++/impl/codegen/time.h
+++ b/include/grpc++/impl/codegen/time.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,74 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_CODEGEN_TIME_H
#define GRPCXX_IMPL_CODEGEN_TIME_H
-#include <chrono>
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc/impl/codegen/grpc_types.h>
-
-namespace grpc {
-
-/** If you are trying to use CompletionQueue::AsyncNext with a time class that
- isn't either gpr_timespec or std::chrono::system_clock::time_point, you
- will most likely be looking at this comment as your compiler will have
- fired an error below. In order to fix this issue, you have two potential
- solutions:
-
- 1. Use gpr_timespec or std::chrono::system_clock::time_point instead
- 2. Specialize the TimePoint class with whichever time class that you
- want to use here. See below for two examples of how to do this.
- */
-template <typename T>
-class TimePoint {
- public:
- TimePoint(const T& time) { you_need_a_specialization_of_TimePoint(); }
- gpr_timespec raw_time() {
- gpr_timespec t;
- return t;
- }
-
- private:
- void you_need_a_specialization_of_TimePoint();
-};
-
-template <>
-class TimePoint<gpr_timespec> {
- public:
- TimePoint(const gpr_timespec& time) : time_(time) {}
- gpr_timespec raw_time() { return time_; }
-
- private:
- gpr_timespec time_;
-};
-
-} // namespace grpc
-
-namespace grpc {
-
-// from and to should be absolute time.
-void Timepoint2Timespec(const std::chrono::system_clock::time_point& from,
- gpr_timespec* to);
-void TimepointHR2Timespec(
- const std::chrono::high_resolution_clock::time_point& from,
- gpr_timespec* to);
-
-std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
-
-template <>
-class TimePoint<std::chrono::system_clock::time_point> {
- public:
- TimePoint(const std::chrono::system_clock::time_point& time) {
- Timepoint2Timespec(time, &time_);
- }
- gpr_timespec raw_time() const { return time_; }
-
- private:
- gpr_timespec time_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/codegen/time.h>
#endif // GRPCXX_IMPL_CODEGEN_TIME_H
diff --git a/include/grpc++/impl/grpc_library.h b/include/grpc++/impl/grpc_library.h
index 55c867ddff..f34a281ac3 100644
--- a/include/grpc++/impl/grpc_library.h
+++ b/include/grpc++/impl/grpc_library.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,46 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_GRPC_LIBRARY_H
#define GRPCXX_IMPL_GRPC_LIBRARY_H
-#include <iostream>
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/core_codegen.h>
-#include <grpc++/impl/codegen/grpc_library.h>
-#include <grpc/grpc.h>
-
-namespace grpc {
-
-namespace internal {
-class GrpcLibrary final : public GrpcLibraryInterface {
- public:
- void init() override { grpc_init(); }
- void shutdown() override { grpc_shutdown(); }
-};
-
-static GrpcLibrary g_gli;
-static CoreCodegen g_core_codegen;
-
-/// Instantiating this class ensures the proper initialization of gRPC.
-class GrpcLibraryInitializer final {
- public:
- GrpcLibraryInitializer() {
- if (grpc::g_glip == nullptr) {
- grpc::g_glip = &g_gli;
- }
- if (grpc::g_core_codegen_interface == nullptr) {
- grpc::g_core_codegen_interface = &g_core_codegen;
- }
- }
-
- /// A no-op method to force the linker to reference this class, which will
- /// take care of initializing and shutting down the gRPC runtime.
- int summon() { return 0; }
-};
-
-} // namespace internal
-} // namespace grpc
+#include <grpcpp/impl/grpc_library.h>
#endif // GRPCXX_IMPL_GRPC_LIBRARY_H
diff --git a/include/grpc++/impl/method_handler_impl.h b/include/grpc++/impl/method_handler_impl.h
index 0b1ab027d9..3840f48742 100644
--- a/include/grpc++/impl/method_handler_impl.h
+++ b/include/grpc++/impl/method_handler_impl.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
#define GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
-#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpcpp/impl/method_handler_impl.h>
#endif // GRPCXX_IMPL_METHOD_HANDLER_IMPL_H
diff --git a/include/grpc++/impl/rpc_method.h b/include/grpc++/impl/rpc_method.h
index 51e95bb157..7cba7c40c4 100644
--- a/include/grpc++/impl/rpc_method.h
+++ b/include/grpc++/impl/rpc_method.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_RPC_METHOD_H
#define GRPCXX_IMPL_RPC_METHOD_H
-#include <grpc++/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/rpc_method.h>
#endif // GRPCXX_IMPL_RPC_METHOD_H
diff --git a/include/grpc++/impl/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h
index efde374e7e..2c75087b7c 100644
--- a/include/grpc++/impl/rpc_service_method.h
+++ b/include/grpc++/impl/rpc_service_method.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_RPC_SERVICE_METHOD_H
#define GRPCXX_IMPL_RPC_SERVICE_METHOD_H
-#include <grpc++/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/rpc_service_method.h>
#endif // GRPCXX_IMPL_RPC_SERVICE_METHOD_H
diff --git a/include/grpc++/impl/serialization_traits.h b/include/grpc++/impl/serialization_traits.h
index 91e894c98a..33b3a0bb31 100644
--- a/include/grpc++/impl/serialization_traits.h
+++ b/include/grpc++/impl/serialization_traits.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SERIALIZATION_TRAITS_H
#define GRPCXX_IMPL_SERIALIZATION_TRAITS_H
-#include <grpc++/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/serialization_traits.h>
#endif // GRPCXX_IMPL_SERIALIZATION_TRAITS_H
diff --git a/include/grpc++/impl/server_builder_option.h b/include/grpc++/impl/server_builder_option.h
index ab04a1c997..833f8db772 100644
--- a/include/grpc++/impl/server_builder_option.h
+++ b/include/grpc++/impl/server_builder_option.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,28 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
#define GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
-#include <map>
-#include <memory>
-
-#include <grpc++/impl/server_builder_plugin.h>
-#include <grpc++/support/channel_arguments.h>
-
-namespace grpc {
-
-/// Interface to pass an option to a \a ServerBuilder.
-class ServerBuilderOption {
- public:
- virtual ~ServerBuilderOption() {}
- /// Alter the \a ChannelArguments used to create the gRPC server.
- virtual void UpdateArguments(ChannelArguments* args) = 0;
- /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder.
- virtual void UpdatePlugins(
- std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) = 0;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/server_builder_option.h>
#endif // GRPCXX_IMPL_SERVER_BUILDER_OPTION_H
diff --git a/include/grpc++/impl/server_builder_plugin.h b/include/grpc++/impl/server_builder_plugin.h
index e15cd7b4c9..844d32c55f 100644
--- a/include/grpc++/impl/server_builder_plugin.h
+++ b/include/grpc++/impl/server_builder_plugin.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,50 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H
#define GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H
-#include <memory>
-
-#include <grpc++/support/config.h>
-
-namespace grpc {
-
-class ServerBuilder;
-class ServerInitializer;
-class ChannelArguments;
-
-/// This interface is meant for internal usage only. Implementations of this
-/// interface should add themselves to a \a ServerBuilder instance through the
-/// \a InternalAddPluginFactory method.
-class ServerBuilderPlugin {
- public:
- virtual ~ServerBuilderPlugin() {}
- virtual grpc::string name() = 0;
-
- /// UpdateServerBuilder will be called at the beginning of
- /// \a ServerBuilder::BuildAndStart().
- virtual void UpdateServerBuilder(ServerBuilder* builder) {}
-
- /// InitServer will be called in ServerBuilder::BuildAndStart(), after the
- /// Server instance is created.
- virtual void InitServer(ServerInitializer* si) = 0;
-
- /// Finish will be called at the end of ServerBuilder::BuildAndStart().
- virtual void Finish(ServerInitializer* si) = 0;
-
- /// ChangeArguments is an interface that can be used in
- /// ServerBuilderOption::UpdatePlugins
- virtual void ChangeArguments(const grpc::string& name, void* value) = 0;
-
- /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(),
- /// before the Server instance is created.
- virtual void UpdateChannelArguments(ChannelArguments* args) {}
-
- virtual bool has_sync_methods() const { return false; }
- virtual bool has_async_methods() const { return false; }
-};
-
-} // namespace grpc
+#include <grpcpp/impl/server_builder_plugin.h>
#endif // GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H
diff --git a/include/grpc++/impl/server_initializer.h b/include/grpc++/impl/server_initializer.h
index 873c46fb31..6a1669ccf5 100644
--- a/include/grpc++/impl/server_initializer.h
+++ b/include/grpc++/impl/server_initializer.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,40 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SERVER_INITIALIZER_H
#define GRPCXX_IMPL_SERVER_INITIALIZER_H
-#include <memory>
-#include <vector>
-
-#include <grpc++/server.h>
-
-namespace grpc {
-
-class Server;
-class Service;
-
-class ServerInitializer {
- public:
- ServerInitializer(Server* server) : server_(server) {}
-
- bool RegisterService(std::shared_ptr<Service> service) {
- if (!server_->RegisterService(nullptr, service.get())) {
- return false;
- }
- default_services_.push_back(service);
- return true;
- }
-
- const std::vector<grpc::string>* GetServiceList() {
- return &server_->services_;
- }
-
- private:
- Server* server_;
- std::vector<std::shared_ptr<Service> > default_services_;
-};
-
-} // namespace grpc
+#include <grpcpp/impl/server_initializer.h>
#endif // GRPCXX_IMPL_SERVER_INITIALIZER_H
diff --git a/include/grpc++/impl/service_type.h b/include/grpc++/impl/service_type.h
index 6a9e90a974..86422160d4 100644
--- a/include/grpc++/impl/service_type.h
+++ b/include/grpc++/impl/service_type.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SERVICE_TYPE_H
#define GRPCXX_IMPL_SERVICE_TYPE_H
-#include <grpc++/impl/codegen/service_type.h>
+#include <grpcpp/impl/service_type.h>
#endif // GRPCXX_IMPL_SERVICE_TYPE_H
diff --git a/include/grpc++/impl/sync_cxx11.h b/include/grpc++/impl/sync_cxx11.h
index 64d467f30d..8bcfb2ce81 100644
--- a/include/grpc++/impl/sync_cxx11.h
+++ b/include/grpc++/impl/sync_cxx11.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SYNC_CXX11_H
#define GRPCXX_IMPL_SYNC_CXX11_H
-#include <grpc++/impl/codegen/sync_cxx11.h>
+#include <grpcpp/impl/sync_cxx11.h>
#endif // GRPCXX_IMPL_SYNC_CXX11_H
diff --git a/include/grpc++/impl/sync_no_cxx11.h b/include/grpc++/impl/sync_no_cxx11.h
index cc0177ef76..5264567387 100644
--- a/include/grpc++/impl/sync_no_cxx11.h
+++ b/include/grpc++/impl/sync_no_cxx11.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_IMPL_SYNC_NO_CXX11_H
#define GRPCXX_IMPL_SYNC_NO_CXX11_H
-#include <grpc++/impl/codegen/sync_no_cxx11.h>
+#include <grpcpp/impl/sync_no_cxx11.h>
#endif // GRPCXX_IMPL_SYNC_NO_CXX11_H
diff --git a/include/grpc++/resource_quota.h b/include/grpc++/resource_quota.h
index ef214dba39..aad1b5659f 100644
--- a/include/grpc++/resource_quota.h
+++ b/include/grpc++/resource_quota.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,43 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_RESOURCE_QUOTA_H
#define GRPCXX_RESOURCE_QUOTA_H
-struct grpc_resource_quota;
-
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/grpc_library.h>
-
-namespace grpc {
-
-/// ResourceQuota represents a bound on memory usage by the gRPC library.
-/// A ResourceQuota can be attached to a server (via \a ServerBuilder),
-/// or a client channel (via \a ChannelArguments).
-/// gRPC will attempt to keep memory used by all attached entities
-/// below the ResourceQuota bound.
-class ResourceQuota final : private GrpcLibraryCodegen {
- public:
- /// \param name - a unique name for this ResourceQuota.
- explicit ResourceQuota(const grpc::string& name);
- ResourceQuota();
- ~ResourceQuota();
-
- /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller
- /// than the current size of the pool, memory usage will be monotonically
- /// decreased until it falls under \a new_size.
- /// No time bound is given for this to occur however.
- ResourceQuota& Resize(size_t new_size);
-
- grpc_resource_quota* c_resource_quota() const { return impl_; }
-
- private:
- ResourceQuota(const ResourceQuota& rhs);
- ResourceQuota& operator=(const ResourceQuota& rhs);
-
- grpc_resource_quota* const impl_;
-};
-
-} // namespace grpc
+#include <grpcpp/resource_quota.h>
#endif // GRPCXX_RESOURCE_QUOTA_H
diff --git a/include/grpc++/security/auth_context.h b/include/grpc++/security/auth_context.h
index 71f5d6e5b3..9fe59d448e 100644
--- a/include/grpc++/security/auth_context.h
+++ b/include/grpc++/security/auth_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SECURITY_AUTH_CONTEXT_H
#define GRPCXX_SECURITY_AUTH_CONTEXT_H
-#include <grpc++/impl/codegen/security/auth_context.h>
+#include <grpcpp/security/auth_context.h>
#endif // GRPCXX_SECURITY_AUTH_CONTEXT_H
diff --git a/include/grpc++/security/auth_metadata_processor.h b/include/grpc++/security/auth_metadata_processor.h
index a49e30f891..d045313965 100644
--- a/include/grpc++/security/auth_metadata_processor.h
+++ b/include/grpc++/security/auth_metadata_processor.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,46 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SECURITY_AUTH_METADATA_PROCESSOR_H
#define GRPCXX_SECURITY_AUTH_METADATA_PROCESSOR_H
-#include <map>
-
-#include <grpc++/security/auth_context.h>
-#include <grpc++/support/status.h>
-#include <grpc++/support/string_ref.h>
-
-namespace grpc {
-
-/// Interface allowing custom server-side authorization based on credentials
-/// encoded in metadata. Objects of this type can be passed to
-/// \a ServerCredentials::SetAuthMetadataProcessor().
-class AuthMetadataProcessor {
- public:
- typedef std::multimap<grpc::string_ref, grpc::string_ref> InputMetadata;
- typedef std::multimap<grpc::string, grpc::string> OutputMetadata;
-
- virtual ~AuthMetadataProcessor() {}
-
- /// If this method returns true, the \a Process function will be scheduled in
- /// a different thread from the one processing the call.
- virtual bool IsBlocking() const { return true; }
-
- /// context is read/write: it contains the properties of the channel peer and
- /// it is the job of the Process method to augment it with properties derived
- /// from the passed-in auth_metadata.
- /// consumed_auth_metadata needs to be filled with metadata that has been
- /// consumed by the processor and will be removed from the call.
- /// response_metadata is the metadata that will be sent as part of the
- /// response.
- /// If the return value is not Status::OK, the rpc call will be aborted with
- /// the error code and error message sent back to the client.
- virtual Status Process(const InputMetadata& auth_metadata,
- AuthContext* context,
- OutputMetadata* consumed_auth_metadata,
- OutputMetadata* response_metadata) = 0;
-};
-
-} // namespace grpc
+#include <grpcpp/security/auth_metadata_processor.h>
#endif // GRPCXX_SECURITY_AUTH_METADATA_PROCESSOR_H
diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h
index 92330d42c6..940441827d 100644
--- a/include/grpc++/security/credentials.h
+++ b/include/grpc++/security/credentials.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,209 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SECURITY_CREDENTIALS_H
#define GRPCXX_SECURITY_CREDENTIALS_H
-#include <map>
-#include <memory>
-
-#include <grpc++/impl/codegen/grpc_library.h>
-#include <grpc++/security/auth_context.h>
-#include <grpc++/support/status.h>
-#include <grpc++/support/string_ref.h>
-
-struct grpc_call;
-
-namespace grpc {
-class ChannelArguments;
-class Channel;
-class SecureChannelCredentials;
-class CallCredentials;
-class SecureCallCredentials;
-
-/// A channel credentials object encapsulates all the state needed by a client
-/// to authenticate with a server for a given channel.
-/// It can make various assertions, e.g., about the client’s identity, role
-/// for all the calls on that channel.
-///
-/// \see https://grpc.io/docs/guides/auth.html
-class ChannelCredentials : private GrpcLibraryCodegen {
- public:
- ChannelCredentials();
- ~ChannelCredentials();
-
- protected:
- friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
- const std::shared_ptr<ChannelCredentials>& channel_creds,
- const std::shared_ptr<CallCredentials>& call_creds);
-
- virtual SecureChannelCredentials* AsSecureCredentials() = 0;
-
- private:
- friend std::shared_ptr<Channel> CreateCustomChannel(
- const grpc::string& target,
- const std::shared_ptr<ChannelCredentials>& creds,
- const ChannelArguments& args);
-
- virtual std::shared_ptr<Channel> CreateChannel(
- const grpc::string& target, const ChannelArguments& args) = 0;
-};
-
-/// A call credentials object encapsulates the state needed by a client to
-/// authenticate with a server for a given call on a channel.
-///
-/// \see https://grpc.io/docs/guides/auth.html
-class CallCredentials : private GrpcLibraryCodegen {
- public:
- CallCredentials();
- ~CallCredentials();
-
- /// Apply this instance's credentials to \a call.
- virtual bool ApplyToCall(grpc_call* call) = 0;
-
- protected:
- friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
- const std::shared_ptr<ChannelCredentials>& channel_creds,
- const std::shared_ptr<CallCredentials>& call_creds);
-
- friend std::shared_ptr<CallCredentials> CompositeCallCredentials(
- const std::shared_ptr<CallCredentials>& creds1,
- const std::shared_ptr<CallCredentials>& creds2);
-
- virtual SecureCallCredentials* AsSecureCredentials() = 0;
-};
-
-/// Options used to build SslCredentials.
-struct SslCredentialsOptions {
- /// The buffer containing the PEM encoding of the server root certificates. If
- /// this parameter is empty, the default roots will be used. The default
- /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
- /// environment variable pointing to a file on the file system containing the
- /// roots.
- grpc::string pem_root_certs;
-
- /// The buffer containing the PEM encoding of the client's private key. This
- /// parameter can be empty if the client does not have a private key.
- grpc::string pem_private_key;
-
- /// The buffer containing the PEM encoding of the client's certificate chain.
- /// This parameter can be empty if the client does not have a certificate
- /// chain.
- grpc::string pem_cert_chain;
-};
-
-// Factories for building different types of Credentials The functions may
-// return empty shared_ptr when credentials cannot be created. If a
-// Credentials pointer is returned, it can still be invalid when used to create
-// a channel. A lame channel will be created then and all rpcs will fail on it.
-
-/// Builds credentials with reasonable defaults.
-///
-/// \warning Only use these credentials when connecting to a Google endpoint.
-/// Using these credentials to connect to any other service may result in this
-/// service being able to impersonate your client for requests to Google
-/// services.
-std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials();
-
-/// Builds SSL Credentials given SSL specific options
-std::shared_ptr<ChannelCredentials> SslCredentials(
- const SslCredentialsOptions& options);
-
-/// Builds credentials for use when running in GCE
-///
-/// \warning Only use these credentials when connecting to a Google endpoint.
-/// Using these credentials to connect to any other service may result in this
-/// service being able to impersonate your client for requests to Google
-/// services.
-std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials();
-
-/// Constant for maximum auth token lifetime.
-constexpr long kMaxAuthTokenLifetimeSecs = 3600;
-
-/// Builds Service Account JWT Access credentials.
-/// json_key is the JSON key string containing the client's private key.
-/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
-/// (JWT) created with this credentials. It should not exceed
-/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value.
-std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
- const grpc::string& json_key,
- long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs);
-
-/// Builds refresh token credentials.
-/// json_refresh_token is the JSON string containing the refresh token along
-/// with a client_id and client_secret.
-///
-/// \warning Only use these credentials when connecting to a Google endpoint.
-/// Using these credentials to connect to any other service may result in this
-/// service being able to impersonate your client for requests to Google
-/// services.
-std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
- const grpc::string& json_refresh_token);
-
-/// Builds access token credentials.
-/// access_token is an oauth2 access token that was fetched using an out of band
-/// mechanism.
-///
-/// \warning Only use these credentials when connecting to a Google endpoint.
-/// Using these credentials to connect to any other service may result in this
-/// service being able to impersonate your client for requests to Google
-/// services.
-std::shared_ptr<CallCredentials> AccessTokenCredentials(
- const grpc::string& access_token);
-
-/// Builds IAM credentials.
-///
-/// \warning Only use these credentials when connecting to a Google endpoint.
-/// Using these credentials to connect to any other service may result in this
-/// service being able to impersonate your client for requests to Google
-/// services.
-std::shared_ptr<CallCredentials> GoogleIAMCredentials(
- const grpc::string& authorization_token,
- const grpc::string& authority_selector);
-
-/// Combines a channel credentials and a call credentials into a composite
-/// channel credentials.
-std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
- const std::shared_ptr<ChannelCredentials>& channel_creds,
- const std::shared_ptr<CallCredentials>& call_creds);
-
-/// Combines two call credentials objects into a composite call credentials.
-std::shared_ptr<CallCredentials> CompositeCallCredentials(
- const std::shared_ptr<CallCredentials>& creds1,
- const std::shared_ptr<CallCredentials>& creds2);
-
-/// Credentials for an unencrypted, unauthenticated channel
-std::shared_ptr<ChannelCredentials> InsecureChannelCredentials();
-
-/// Credentials for a channel using Cronet.
-std::shared_ptr<ChannelCredentials> CronetChannelCredentials(void* engine);
-
-/// User defined metadata credentials.
-class MetadataCredentialsPlugin {
- public:
- virtual ~MetadataCredentialsPlugin() {}
-
- /// If this method returns true, the Process function will be scheduled in
- /// a different thread from the one processing the call.
- virtual bool IsBlocking() const { return true; }
-
- /// Type of credentials this plugin is implementing.
- virtual const char* GetType() const { return ""; }
-
- /// Gets the auth metatada produced by this plugin.
- /// The fully qualified method name is:
- /// service_url + "/" + method_name.
- /// The channel_auth_context contains (among other things), the identity of
- /// the server.
- virtual Status GetMetadata(
- grpc::string_ref service_url, grpc::string_ref method_name,
- const AuthContext& channel_auth_context,
- std::multimap<grpc::string, grpc::string>* metadata) = 0;
-};
-
-std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
- std::unique_ptr<MetadataCredentialsPlugin> plugin);
-
-} // namespace grpc
+#include <grpcpp/security/credentials.h>
#endif // GRPCXX_SECURITY_CREDENTIALS_H
diff --git a/include/grpc++/security/server_credentials.h b/include/grpc++/security/server_credentials.h
index 74a61b51e3..c6d1c4f0e4 100644
--- a/include/grpc++/security/server_credentials.h
+++ b/include/grpc++/security/server_credentials.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,76 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SECURITY_SERVER_CREDENTIALS_H
#define GRPCXX_SECURITY_SERVER_CREDENTIALS_H
-#include <memory>
-#include <vector>
-
-#include <grpc++/security/auth_metadata_processor.h>
-#include <grpc++/support/config.h>
-#include <grpc/grpc_security_constants.h>
-
-struct grpc_server;
-
-namespace grpc {
-class Server;
-
-/// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
-class ServerCredentials {
- public:
- virtual ~ServerCredentials();
-
- /// This method is not thread-safe and has to be called before the server is
- /// started. The last call to this function wins.
- virtual void SetAuthMetadataProcessor(
- const std::shared_ptr<AuthMetadataProcessor>& processor) = 0;
-
- private:
- friend class ::grpc::Server;
-
- /// Tries to bind \a server to the given \a addr (eg, localhost:1234,
- /// 192.168.1.1:31416, [::1]:27182, etc.)
- ///
- /// \return bound port number on sucess, 0 on failure.
- // TODO(dgq): the "port" part seems to be a misnomer.
- virtual int AddPortToServer(const grpc::string& addr,
- grpc_server* server) = 0;
-};
-
-/// Options to create ServerCredentials with SSL
-struct SslServerCredentialsOptions {
- /// \warning Deprecated
- SslServerCredentialsOptions()
- : force_client_auth(false),
- client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {}
- SslServerCredentialsOptions(
- grpc_ssl_client_certificate_request_type request_type)
- : force_client_auth(false), client_certificate_request(request_type) {}
-
- struct PemKeyCertPair {
- grpc::string private_key;
- grpc::string cert_chain;
- };
- grpc::string pem_root_certs;
- std::vector<PemKeyCertPair> pem_key_cert_pairs;
- /// \warning Deprecated
- bool force_client_auth;
-
- /// If both \a force_client_auth and \a client_certificate_request
- /// fields are set, \a force_client_auth takes effect, i.e.
- /// \a REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
- /// will be enforced.
- grpc_ssl_client_certificate_request_type client_certificate_request;
-};
-
-/// Builds SSL ServerCredentials given SSL specific options
-std::shared_ptr<ServerCredentials> SslServerCredentials(
- const SslServerCredentialsOptions& options);
-
-/// Builds insecure server credentials.
-std::shared_ptr<ServerCredentials> InsecureServerCredentials();
-
-} // namespace grpc
+#include <grpcpp/security/server_credentials.h>
#endif // GRPCXX_SECURITY_SERVER_CREDENTIALS_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 01c4a60d21..086c24cc69 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,212 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SERVER_H
#define GRPCXX_SERVER_H
-#include <condition_variable>
-#include <list>
-#include <memory>
-#include <mutex>
-#include <vector>
-
-#include <grpc++/completion_queue.h>
-#include <grpc++/impl/call.h>
-#include <grpc++/impl/codegen/grpc_library.h>
-#include <grpc++/impl/codegen/server_interface.h>
-#include <grpc++/impl/rpc_service_method.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/support/channel_arguments.h>
-#include <grpc++/support/config.h>
-#include <grpc++/support/status.h>
-#include <grpc/compression.h>
-
-struct grpc_server;
-
-namespace grpc {
-
-class AsyncGenericService;
-class HealthCheckServiceInterface;
-class ServerContext;
-class ServerInitializer;
-
-/// Represents a gRPC server.
-///
-/// Use a \a grpc::ServerBuilder to create, configure, and start
-/// \a Server instances.
-class Server final : public ServerInterface, private GrpcLibraryCodegen {
- public:
- ~Server();
-
- /// Block until the server shuts down.
- ///
- /// \warning The server must be either shutting down or some other thread must
- /// call \a Shutdown for this function to ever return.
- void Wait() override;
-
- /// Global callbacks are a set of hooks that are called when server
- /// events occur. \a SetGlobalCallbacks method is used to register
- /// the hooks with gRPC. Note that
- /// the \a GlobalCallbacks instance will be shared among all
- /// \a Server instances in an application and can be set exactly
- /// once per application.
- class GlobalCallbacks {
- public:
- virtual ~GlobalCallbacks() {}
- /// Called before server is created.
- virtual void UpdateArguments(ChannelArguments* args) {}
- /// Called before application callback for each synchronous server request
- virtual void PreSynchronousRequest(ServerContext* context) = 0;
- /// Called after application callback for each synchronous server request
- virtual void PostSynchronousRequest(ServerContext* context) = 0;
- /// Called before server is started.
- virtual void PreServerStart(Server* server) {}
- /// Called after a server port is added.
- virtual void AddPort(Server* server, const grpc::string& addr,
- ServerCredentials* creds, int port) {}
- };
- /// Set the global callback object. Can only be called once per application.
- /// Does not take ownership of callbacks, and expects the pointed to object
- /// to be alive until all server objects in the process have been destroyed.
- /// The same \a GlobalCallbacks object will be used throughout the
- /// application and is shared among all \a Server objects.
- static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
-
- // Returns a \em raw pointer to the underlying \a grpc_server instance.
- grpc_server* c_server();
-
- /// Returns the health check service.
- HealthCheckServiceInterface* GetHealthCheckService() const {
- return health_check_service_.get();
- }
-
- /// Establish a channel for in-process communication
- std::shared_ptr<Channel> InProcessChannel(const ChannelArguments& args);
-
- private:
- friend class AsyncGenericService;
- friend class ServerBuilder;
- friend class ServerInitializer;
-
- class SyncRequest;
- class AsyncRequest;
- class ShutdownRequest;
-
- /// SyncRequestThreadManager is an implementation of ThreadManager. This class
- /// is responsible for polling for incoming RPCs and calling the RPC handlers.
- /// This is only used in case of a Sync server (i.e a server exposing a sync
- /// interface)
- class SyncRequestThreadManager;
-
- class UnimplementedAsyncRequestContext;
- class UnimplementedAsyncRequest;
- class UnimplementedAsyncResponse;
-
- /// Server constructors. To be used by \a ServerBuilder only.
- ///
- /// \param max_message_size Maximum message length that the channel can
- /// receive.
- ///
- /// \param args The channel args
- ///
- /// \param sync_server_cqs The completion queues to use if the server is a
- /// synchronous server (or a hybrid server). The server polls for new RPCs on
- /// these queues
- ///
- /// \param min_pollers The minimum number of polling threads per server
- /// completion queue (in param sync_server_cqs) to use for listening to
- /// incoming requests (used only in case of sync server)
- ///
- /// \param max_pollers The maximum number of polling threads per server
- /// completion queue (in param sync_server_cqs) to use for listening to
- /// incoming requests (used only in case of sync server)
- ///
- /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on
- /// server completion queues passed via sync_server_cqs param.
- Server(int max_message_size, ChannelArguments* args,
- std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
- sync_server_cqs,
- int min_pollers, int max_pollers, int sync_cq_timeout_msec);
-
- /// Register a service. This call does not take ownership of the service.
- /// The service must exist for the lifetime of the Server instance.
- bool RegisterService(const grpc::string* host, Service* service) override;
-
- /// Register a generic service. This call does not take ownership of the
- /// service. The service must exist for the lifetime of the Server instance.
- void RegisterAsyncGenericService(AsyncGenericService* service) override;
-
- /// Try binding the server to the given \a addr endpoint
- /// (port, and optionally including IP address to bind to).
- ///
- /// It can be invoked multiple times. Should be used before
- /// starting the server.
- ///
- /// \param addr The address to try to bind to the server (eg, localhost:1234,
- /// 192.168.1.1:31416, [::1]:27182, etc.).
- /// \param creds The credentials associated with the server.
- ///
- /// \return bound port number on success, 0 on failure.
- ///
- /// \warning It is an error to call this method on an already started server.
- int AddListeningPort(const grpc::string& addr,
- ServerCredentials* creds) override;
-
- /// Start the server.
- ///
- /// \param cqs Completion queues for handling asynchronous services. The
- /// caller is required to keep all completion queues live until the server is
- /// destroyed.
- /// \param num_cqs How many completion queues does \a cqs hold.
- void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
-
- void PerformOpsOnCall(internal::CallOpSetInterface* ops,
- internal::Call* call) override;
-
- void ShutdownInternal(gpr_timespec deadline) override;
-
- int max_receive_message_size() const override {
- return max_receive_message_size_;
- };
-
- grpc_server* server() override { return server_; };
-
- ServerInitializer* initializer();
-
- const int max_receive_message_size_;
-
- /// The following completion queues are ONLY used in case of Sync API
- /// i.e. if the server has any services with sync methods. The server uses
- /// these completion queues to poll for new RPCs
- std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
- sync_server_cqs_;
-
- /// List of \a ThreadManager instances (one for each cq in
- /// the \a sync_server_cqs)
- std::vector<std::unique_ptr<SyncRequestThreadManager>> sync_req_mgrs_;
-
- // Sever status
- std::mutex mu_;
- bool started_;
- bool shutdown_;
- bool shutdown_notified_; // Was notify called on the shutdown_cv_
-
- std::condition_variable shutdown_cv_;
-
- std::shared_ptr<GlobalCallbacks> global_callbacks_;
-
- std::vector<grpc::string> services_;
- bool has_generic_service_;
-
- // Pointer to the wrapped grpc_server.
- grpc_server* server_;
-
- std::unique_ptr<ServerInitializer> server_initializer_;
-
- std::unique_ptr<HealthCheckServiceInterface> health_check_service_;
- bool health_check_service_disabled_;
-};
-
-} // namespace grpc
+#include <grpcpp/server.h>
#endif // GRPCXX_SERVER_H
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index ea9834c179..2c6dab4445 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015-2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,263 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SERVER_BUILDER_H
#define GRPCXX_SERVER_BUILDER_H
-#include <climits>
-#include <map>
-#include <memory>
-#include <vector>
-
-#include <grpc++/impl/channel_argument_option.h>
-#include <grpc++/impl/server_builder_option.h>
-#include <grpc++/impl/server_builder_plugin.h>
-#include <grpc++/support/config.h>
-#include <grpc/compression.h>
-#include <grpc/support/cpu.h>
-#include <grpc/support/workaround_list.h>
-
-struct grpc_resource_quota;
-
-namespace grpc {
-
-class AsyncGenericService;
-class ResourceQuota;
-class CompletionQueue;
-class Server;
-class ServerCompletionQueue;
-class ServerCredentials;
-class Service;
-
-namespace testing {
-class ServerBuilderPluginTest;
-} // namespace testing
-
-/// A builder class for the creation and startup of \a grpc::Server instances.
-class ServerBuilder {
- public:
- ServerBuilder();
- ~ServerBuilder();
-
- //////////////////////////////////////////////////////////////////////////////
- // Primary API's
-
- /// Return a running server which is ready for processing calls.
- /// Before calling, one typically needs to ensure that:
- /// 1. a service is registered - so that the server knows what to serve
- /// (via RegisterService, or RegisterAsyncGenericService)
- /// 2. a listening port has been added - so the server knows where to receive
- /// traffic (via AddListeningPort)
- /// 3. [for async api only] completion queues have been added via
- /// AddCompletionQueue
- std::unique_ptr<Server> BuildAndStart();
-
- /// Register a service. This call does not take ownership of the service.
- /// The service must exist for the lifetime of the \a Server instance returned
- /// by \a BuildAndStart().
- /// Matches requests with any :authority
- ServerBuilder& RegisterService(Service* service);
-
- /// Enlists an endpoint \a addr (port with an optional IP address) to
- /// bind the \a grpc::Server object to be created to.
- ///
- /// It can be invoked multiple times.
- ///
- /// \param addr_uri The address to try to bind to the server in URI form. If
- /// the scheme name is omitted, "dns:///" is assumed. To bind to any address,
- /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4
- /// connections. Valid values include dns:///localhost:1234, /
- /// 192.168.1.1:31416, dns:///[::1]:27182, etc.).
- /// \param creds The credentials associated with the server.
- /// \param selected_port[out] If not `nullptr`, gets populated with the port
- /// number bound to the \a grpc::Server for the corresponding endpoint after
- /// it is successfully bound, 0 otherwise.
- ///
- ServerBuilder& AddListeningPort(const grpc::string& addr_uri,
- std::shared_ptr<ServerCredentials> creds,
- int* selected_port = nullptr);
-
- /// Add a completion queue for handling asynchronous services.
- ///
- /// Best performance is typically obtained by using one thread per polling
- /// completion queue.
- ///
- /// Caller is required to shutdown the server prior to shutting down the
- /// returned completion queue. Caller is also required to drain the
- /// completion queue after shutting it down. A typical usage scenario:
- ///
- /// // While building the server:
- /// ServerBuilder builder;
- /// ...
- /// cq_ = builder.AddCompletionQueue();
- /// server_ = builder.BuildAndStart();
- ///
- /// // While shutting down the server;
- /// server_->Shutdown();
- /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()!
- /// // Drain the cq_ that was created
- /// void* ignored_tag;
- /// bool ignored_ok;
- /// while (cq_->Next(&ignored_tag, &ignored_ok)) { }
- ///
- /// \param is_frequently_polled This is an optional parameter to inform gRPC
- /// library about whether this completion queue would be frequently polled
- /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is
- /// 'true' and is the recommended setting. Setting this to 'false' (i.e.
- /// not polling the completion queue frequently) will have a significantly
- /// negative performance impact and hence should not be used in production
- /// use cases.
- std::unique_ptr<ServerCompletionQueue> AddCompletionQueue(
- bool is_frequently_polled = true);
-
- //////////////////////////////////////////////////////////////////////////////
- // Less commonly used RegisterService variants
-
- /// Register a service. This call does not take ownership of the service.
- /// The service must exist for the lifetime of the \a Server instance returned
- /// by \a BuildAndStart().
- /// Only matches requests with :authority \a host
- ServerBuilder& RegisterService(const grpc::string& host, Service* service);
-
- /// Register a generic service.
- /// Matches requests with any :authority
- /// This is mostly useful for writing generic gRPC Proxies where the exact
- /// serialization format is unknown
- ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service);
-
- //////////////////////////////////////////////////////////////////////////////
- // Fine control knobs
-
- /// Set max receive message size in bytes.
- ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) {
- max_receive_message_size_ = max_receive_message_size;
- return *this;
- }
-
- /// Set max send message size in bytes.
- ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) {
- max_send_message_size_ = max_send_message_size;
- return *this;
- }
-
- /// \deprecated For backward compatibility.
- ServerBuilder& SetMaxMessageSize(int max_message_size) {
- return SetMaxReceiveMessageSize(max_message_size);
- }
-
- /// Set the support status for compression algorithms. All algorithms are
- /// enabled by default.
- ///
- /// Incoming calls compressed with an unsupported algorithm will fail with
- /// \a GRPC_STATUS_UNIMPLEMENTED.
- ServerBuilder& SetCompressionAlgorithmSupportStatus(
- grpc_compression_algorithm algorithm, bool enabled);
-
- /// The default compression level to use for all channel calls in the
- /// absence of a call-specific level.
- ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level);
-
- /// The default compression algorithm to use for all channel calls in the
- /// absence of a call-specific level. Note that it overrides any compression
- /// level set by \a SetDefaultCompressionLevel.
- ServerBuilder& SetDefaultCompressionAlgorithm(
- grpc_compression_algorithm algorithm);
-
- /// Set the attached buffer pool for this server
- ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota);
-
- ServerBuilder& SetOption(std::unique_ptr<ServerBuilderOption> option);
-
- /// Options for synchronous servers.
- enum SyncServerOption {
- NUM_CQS, ///< Number of completion queues.
- MIN_POLLERS, ///< Minimum number of polling threads.
- MAX_POLLERS, ///< Maximum number of polling threads.
- CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds.
- };
-
- /// Only useful if this is a Synchronous server.
- ServerBuilder& SetSyncServerOption(SyncServerOption option, int value);
-
- /// Add a channel argument (an escape hatch to tuning core library parameters
- /// directly)
- template <class T>
- ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) {
- return SetOption(MakeChannelArgumentOption(arg, value));
- }
-
- /// For internal use only: Register a ServerBuilderPlugin factory function.
- static void InternalAddPluginFactory(
- std::unique_ptr<ServerBuilderPlugin> (*CreatePlugin)());
-
- /// Enable a server workaround. Do not use unless you know what the workaround
- /// does. For explanation and detailed descriptions of workarounds, see
- /// doc/workarounds.md.
- ServerBuilder& EnableWorkaround(grpc_workaround_list id);
-
- private:
- friend class ::grpc::testing::ServerBuilderPluginTest;
-
- struct Port {
- grpc::string addr;
- std::shared_ptr<ServerCredentials> creds;
- int* selected_port;
- };
-
- struct SyncServerSettings {
- SyncServerSettings()
- : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {}
-
- /// Number of server completion queues to create to listen to incoming RPCs.
- int num_cqs;
-
- /// Minimum number of threads per completion queue that should be listening
- /// to incoming RPCs.
- int min_pollers;
-
- /// Maximum number of threads per completion queue that can be listening to
- /// incoming RPCs.
- int max_pollers;
-
- /// The timeout for server completion queue's AsyncNext call.
- int cq_timeout_msec;
- };
-
- typedef std::unique_ptr<grpc::string> HostString;
- struct NamedService {
- explicit NamedService(Service* s) : service(s) {}
- NamedService(const grpc::string& h, Service* s)
- : host(new grpc::string(h)), service(s) {}
- HostString host;
- Service* service;
- };
-
- int max_receive_message_size_;
- int max_send_message_size_;
- std::vector<std::unique_ptr<ServerBuilderOption>> options_;
- std::vector<std::unique_ptr<NamedService>> services_;
- std::vector<Port> ports_;
-
- SyncServerSettings sync_server_settings_;
-
- /// List of completion queues added via \a AddCompletionQueue method.
- std::vector<ServerCompletionQueue*> cqs_;
-
- std::shared_ptr<ServerCredentials> creds_;
- std::vector<std::unique_ptr<ServerBuilderPlugin>> plugins_;
- grpc_resource_quota* resource_quota_;
- AsyncGenericService* generic_service_;
- struct {
- bool is_set;
- grpc_compression_level level;
- } maybe_default_compression_level_;
- struct {
- bool is_set;
- grpc_compression_algorithm algorithm;
- } maybe_default_compression_algorithm_;
- uint32_t enabled_compression_algorithms_bitset_;
-};
-
-} // namespace grpc
+#include <grpcpp/server_builder.h>
#endif // GRPCXX_SERVER_BUILDER_H
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index f9b98e1896..672ccdca6d 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SERVER_CONTEXT_H
#define GRPCXX_SERVER_CONTEXT_H
-#include <grpc++/impl/codegen/server_context.h>
+#include <grpcpp/server_context.h>
#endif // GRPCXX_SERVER_CONTEXT_H
diff --git a/include/grpc++/server_posix.h b/include/grpc++/server_posix.h
index 6cafcff540..d2866d9640 100644
--- a/include/grpc++/server_posix.h
+++ b/include/grpc++/server_posix.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,27 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SERVER_POSIX_H
#define GRPCXX_SERVER_POSIX_H
-#include <memory>
-
-#include <grpc++/server.h>
-#include <grpc/support/port_platform.h>
-
-namespace grpc {
-
-#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
-
-/// Add a new client to a \a Server communicating over the given
-/// file descriptor.
-///
-/// \param server The server to add the client to.
-/// \param fd The file descriptor representing a socket.
-void AddInsecureChannelFromFd(Server* server, int fd);
-
-#endif // GPR_SUPPORT_CHANNELS_FROM_FD
-
-} // namespace grpc
+#include <grpcpp/server_posix.h>
#endif // GRPCXX_SERVER_POSIX_H
diff --git a/include/grpc++/support/async_stream.h b/include/grpc++/support/async_stream.h
index f2cab848f0..9bb2b725c3 100644
--- a/include/grpc++/support/async_stream.h
+++ b/include/grpc++/support/async_stream.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_ASYNC_STREAM_H
#define GRPCXX_SUPPORT_ASYNC_STREAM_H
-#include <grpc++/impl/codegen/async_stream.h>
+#include <grpcpp/support/async_stream.h>
#endif // GRPCXX_SUPPORT_ASYNC_STREAM_H
diff --git a/include/grpc++/support/async_unary_call.h b/include/grpc++/support/async_unary_call.h
index 4947c442a9..56fbf31417 100644
--- a/include/grpc++/support/async_unary_call.h
+++ b/include/grpc++/support/async_unary_call.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H
#define GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H
-#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpcpp/support/async_unary_call.h>
#endif // GRPCXX_SUPPORT_ASYNC_UNARY_CALL_H
diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h
index 81fa3b0a18..ec607ee01a 100644
--- a/include/grpc++/support/byte_buffer.h
+++ b/include/grpc++/support/byte_buffer.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_BYTE_BUFFER_H
#define GRPCXX_SUPPORT_BYTE_BUFFER_H
-#include <grpc++/impl/codegen/byte_buffer.h>
-#include <grpc++/impl/serialization_traits.h>
-#include <grpc++/support/config.h>
-#include <grpc++/support/slice.h>
-#include <grpc++/support/status.h>
-#include <grpc/byte_buffer.h>
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
+#include <grpcpp/support/byte_buffer.h>
#endif // GRPCXX_SUPPORT_BYTE_BUFFER_H
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index c9879d8a28..6d5300ccb7 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,127 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_CHANNEL_ARGUMENTS_H
#define GRPCXX_SUPPORT_CHANNEL_ARGUMENTS_H
-#include <list>
-#include <vector>
-
-#include <grpc++/support/config.h>
-#include <grpc/compression.h>
-#include <grpc/grpc.h>
-
-namespace grpc {
-namespace testing {
-class ChannelArgumentsTest;
-} // namespace testing
-
-class ResourceQuota;
-
-/// Options for channel creation. The user can use generic setters to pass
-/// key value pairs down to C channel creation code. For gRPC related options,
-/// concrete setters are provided.
-class ChannelArguments {
- public:
- ChannelArguments();
- ~ChannelArguments();
-
- ChannelArguments(const ChannelArguments& other);
- ChannelArguments& operator=(ChannelArguments other) {
- Swap(other);
- return *this;
- }
-
- void Swap(ChannelArguments& other);
-
- /// Dump arguments in this instance to \a channel_args. Does not take
- /// ownership of \a channel_args.
- ///
- /// Note that the underlying arguments are shared. Changes made to either \a
- /// channel_args or this instance would be reflected on both.
- void SetChannelArgs(grpc_channel_args* channel_args) const;
-
- // gRPC specific channel argument setters
- /// Set target name override for SSL host name checking. This option is for
- /// testing only and should never be used in production.
- void SetSslTargetNameOverride(const grpc::string& name);
- // TODO(yangg) add flow control options
- /// Set the compression algorithm for the channel.
- void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
-
- /// Set the grpclb fallback timeout (in ms) for the channel. If this amount
- /// of time has passed but we have not gotten any non-empty \a serverlist from
- /// the balancer, we will fall back to use the backend address(es) returned by
- /// the resolver.
- void SetGrpclbFallbackTimeout(int fallback_timeout);
-
- /// Set the socket mutator for the channel.
- void SetSocketMutator(grpc_socket_mutator* mutator);
-
- /// Set the string to prepend to the user agent.
- void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
-
- /// Set the buffer pool to be attached to the constructed channel.
- void SetResourceQuota(const ResourceQuota& resource_quota);
-
- /// Set the max receive and send message sizes.
- void SetMaxReceiveMessageSize(int size);
- void SetMaxSendMessageSize(int size);
-
- /// Set LB policy name.
- /// Note that if the name resolver returns only balancer addresses, the
- /// grpclb LB policy will be used, regardless of what is specified here.
- void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name);
-
- /// Set service config in JSON form.
- /// Primarily meant for use in unit tests.
- void SetServiceConfigJSON(const grpc::string& service_config_json);
-
- // Generic channel argument setters. Only for advanced use cases.
- /// Set an integer argument \a value under \a key.
- void SetInt(const grpc::string& key, int value);
-
- // Generic channel argument setter. Only for advanced use cases.
- /// Set a pointer argument \a value under \a key. Owership is not transferred.
- void SetPointer(const grpc::string& key, void* value);
-
- void SetPointerWithVtable(const grpc::string& key, void* value,
- const grpc_arg_pointer_vtable* vtable);
-
- /// Set a textual argument \a value under \a key.
- void SetString(const grpc::string& key, const grpc::string& value);
-
- /// Return (by value) a C \a grpc_channel_args structure which points to
- /// arguments owned by this \a ChannelArguments instance
- grpc_channel_args c_channel_args() const {
- grpc_channel_args out;
- out.num_args = args_.size();
- out.args = args_.empty() ? NULL : const_cast<grpc_arg*>(&args_[0]);
- return out;
- }
-
- private:
- friend class SecureChannelCredentials;
- friend class testing::ChannelArgumentsTest;
-
- /// Default pointer argument operations.
- struct PointerVtableMembers {
- static void* Copy(void* in) { return in; }
- static void Destroy(void* in) {}
- static int Compare(void* a, void* b) {
- if (a < b) return -1;
- if (a > b) return 1;
- return 0;
- }
- };
-
- // Returns empty string when it is not set.
- grpc::string GetSslTargetNameOverride() const;
-
- std::vector<grpc_arg> args_;
- std::list<grpc::string> strings_;
-};
-
-} // namespace grpc
+#include <grpcpp/support/channel_arguments.h>
#endif // GRPCXX_SUPPORT_CHANNEL_ARGUMENTS_H
diff --git a/include/grpc++/support/config.h b/include/grpc++/support/config.h
index b65af3121b..f8eee5075a 100644
--- a/include/grpc++/support/config.h
+++ b/include/grpc++/support/config.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_CONFIG_H
#define GRPCXX_SUPPORT_CONFIG_H
-#include <grpc++/impl/codegen/config.h>
+#include <grpcpp/support/config.h>
#endif // GRPCXX_SUPPORT_CONFIG_H
diff --git a/include/grpc++/support/error_details.h b/include/grpc++/support/error_details.h
index 8925fa843a..7ace308e52 100644
--- a/include/grpc++/support/error_details.h
+++ b/include/grpc++/support/error_details.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2017 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,31 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_ERROR_DETAILS_H
#define GRPCXX_SUPPORT_ERROR_DETAILS_H
-#include <grpc++/support/status.h>
-
-namespace google {
-namespace rpc {
-class Status;
-} // namespace rpc
-} // namespace google
-
-namespace grpc {
-
-/// Map a \a grpc::Status to a \a google::rpc::Status.
-/// The given \a to object will be cleared.
-/// On success, returns status with OK.
-/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize.
-/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr.
-Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to);
-
-/// Map \a google::rpc::Status to a \a grpc::Status.
-/// Returns OK on success.
-/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr.
-Status SetErrorDetails(const ::google::rpc::Status& from, Status* to);
-
-} // namespace grpc
+#include <grpcpp/support/error_details.h>
#endif // GRPCXX_SUPPORT_ERROR_DETAILS_H
diff --git a/include/grpc++/support/slice.h b/include/grpc++/support/slice.h
index 10db10d79c..b02b1a977e 100644
--- a/include/grpc++/support/slice.h
+++ b/include/grpc++/support/slice.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_SLICE_H
#define GRPCXX_SUPPORT_SLICE_H
-#include <grpc++/impl/codegen/slice.h>
-#include <grpc++/support/config.h>
-#include <grpc/slice.h>
+#include <grpcpp/support/slice.h>
#endif // GRPCXX_SUPPORT_SLICE_H
diff --git a/include/grpc++/support/status.h b/include/grpc++/support/status.h
index 1fa910a68c..e58a18bdf9 100644
--- a/include/grpc++/support/status.h
+++ b/include/grpc++/support/status.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_STATUS_H
#define GRPCXX_SUPPORT_STATUS_H
-#include <grpc++/impl/codegen/status.h>
+#include <grpcpp/support/status.h>
#endif // GRPCXX_SUPPORT_STATUS_H
diff --git a/include/grpc++/support/status_code_enum.h b/include/grpc++/support/status_code_enum.h
index d320c0cf10..c278add0c6 100644
--- a/include/grpc++/support/status_code_enum.h
+++ b/include/grpc++/support/status_code_enum.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
#define GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
-#include <grpc++/impl/codegen/status_code_enum.h>
+#include <grpcpp/support/status_code_enum.h>
#endif // GRPCXX_SUPPORT_STATUS_CODE_ENUM_H
diff --git a/include/grpc++/support/string_ref.h b/include/grpc++/support/string_ref.h
index 873be63cee..49de6dafce 100644
--- a/include/grpc++/support/string_ref.h
+++ b/include/grpc++/support/string_ref.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_STRING_REF_H
#define GRPCXX_SUPPORT_STRING_REF_H
-#include <grpc++/impl/codegen/string_ref.h>
+#include <grpcpp/support/string_ref.h>
#endif // GRPCXX_SUPPORT_STRING_REF_H
diff --git a/include/grpc++/support/stub_options.h b/include/grpc++/support/stub_options.h
index 87843cf34f..a712ce8716 100644
--- a/include/grpc++/support/stub_options.h
+++ b/include/grpc++/support/stub_options.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_STUB_OPTIONS_H
#define GRPCXX_SUPPORT_STUB_OPTIONS_H
-#include <grpc++/impl/codegen/stub_options.h>
+#include <grpcpp/support/stub_options.h>
#endif // GRPCXX_SUPPORT_STUB_OPTIONS_H
diff --git a/include/grpc++/support/sync_stream.h b/include/grpc++/support/sync_stream.h
index 6a6e0c797f..c118df9f7b 100644
--- a/include/grpc++/support/sync_stream.h
+++ b/include/grpc++/support/sync_stream.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_SYNC_STREAM_H
#define GRPCXX_SUPPORT_SYNC_STREAM_H
-#include <grpc++/impl/codegen/sync_stream.h>
+#include <grpcpp/support/sync_stream.h>
#endif // GRPCXX_SUPPORT_SYNC_STREAM_H
diff --git a/include/grpc++/support/time.h b/include/grpc++/support/time.h
index e47a593ac9..d356b91001 100644
--- a/include/grpc++/support/time.h
+++ b/include/grpc++/support/time.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_SUPPORT_TIME_H
#define GRPCXX_SUPPORT_TIME_H
-#include <grpc++/impl/codegen/time.h>
+#include <grpcpp/support/time.h>
#endif // GRPCXX_SUPPORT_TIME_H
diff --git a/include/grpc++/test/mock_stream.h b/include/grpc++/test/mock_stream.h
index f8f78244f5..a29345b061 100644
--- a/include/grpc++/test/mock_stream.h
+++ b/include/grpc++/test/mock_stream.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2017 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,133 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_TEST_MOCK_STREAM_H
#define GRPCXX_TEST_MOCK_STREAM_H
-#include <stdint.h>
-
-#include <gmock/gmock.h>
-#include <grpc++/impl/codegen/call.h>
-#include <grpc++/support/async_stream.h>
-#include <grpc++/support/async_unary_call.h>
-#include <grpc++/support/sync_stream.h>
-
-namespace grpc {
-namespace testing {
-
-template <class R>
-class MockClientReader : public ClientReaderInterface<R> {
- public:
- MockClientReader() = default;
-
- /// ClientStreamingInterface
- MOCK_METHOD0_T(Finish, Status());
-
- /// ReaderInterface
- MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
- MOCK_METHOD1_T(Read, bool(R*));
-
- /// ClientReaderInterface
- MOCK_METHOD0_T(WaitForInitialMetadata, void());
-};
-
-template <class W>
-class MockClientWriter : public ClientWriterInterface<W> {
- public:
- MockClientWriter() = default;
-
- /// ClientStreamingInterface
- MOCK_METHOD0_T(Finish, Status());
-
- /// WriterInterface
- MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
-
- /// ClientWriterInterface
- MOCK_METHOD0_T(WritesDone, bool());
-};
-
-template <class W, class R>
-class MockClientReaderWriter : public ClientReaderWriterInterface<W, R> {
- public:
- MockClientReaderWriter() = default;
-
- /// ClientStreamingInterface
- MOCK_METHOD0_T(Finish, Status());
-
- /// ReaderInterface
- MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
- MOCK_METHOD1_T(Read, bool(R*));
-
- /// WriterInterface
- MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
-
- /// ClientReaderWriterInterface
- MOCK_METHOD0_T(WaitForInitialMetadata, void());
- MOCK_METHOD0_T(WritesDone, bool());
-};
-
-/// TODO: We do not support mocking an async RPC for now.
-
-template <class R>
-class MockClientAsyncResponseReader
- : public ClientAsyncResponseReaderInterface<R> {
- public:
- MockClientAsyncResponseReader() = default;
-
- MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
- MOCK_METHOD3_T(Finish, void(R*, Status*, void*));
-};
-
-template <class R>
-class MockClientAsyncReader : public ClientAsyncReaderInterface<R> {
- public:
- MockClientAsyncReader() = default;
-
- /// ClientAsyncStreamingInterface
- MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
- MOCK_METHOD2_T(Finish, void(Status*, void*));
-
- /// AsyncReaderInterface
- MOCK_METHOD2_T(Read, void(R*, void*));
-};
-
-template <class W>
-class MockClientAsyncWriter : public ClientAsyncWriterInterface<W> {
- public:
- MockClientAsyncWriter() = default;
-
- /// ClientAsyncStreamingInterface
- MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
- MOCK_METHOD2_T(Finish, void(Status*, void*));
-
- /// AsyncWriterInterface
- MOCK_METHOD2_T(Write, void(const W&, void*));
-
- /// ClientAsyncWriterInterface
- MOCK_METHOD1_T(WritesDone, void(void*));
-};
-
-template <class W, class R>
-class MockClientAsyncReaderWriter
- : public ClientAsyncReaderWriterInterface<W, R> {
- public:
- MockClientAsyncReaderWriter() = default;
-
- /// ClientAsyncStreamingInterface
- MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
- MOCK_METHOD2_T(Finish, void(Status*, void*));
-
- /// AsyncWriterInterface
- MOCK_METHOD2_T(Write, void(const W&, void*));
-
- /// AsyncReaderInterface
- MOCK_METHOD2_T(Read, void(R*, void*));
-
- /// ClientAsyncReaderWriterInterface
- MOCK_METHOD1_T(WritesDone, void(void*));
-};
-
-} // namespace testing
-} // namespace grpc
+#include <grpcpp/test/mock_stream.h>
#endif // GRPCXX_TEST_MOCK_STREAM_H
diff --git a/include/grpc++/test/server_context_test_spouse.h b/include/grpc++/test/server_context_test_spouse.h
index b1a7f87009..48a4838c2d 100644
--- a/include/grpc++/test/server_context_test_spouse.h
+++ b/include/grpc++/test/server_context_test_spouse.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2016 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,50 +16,13 @@
*
*/
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
#ifndef GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
#define GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
-#include <map>
-
-#include <grpc++/server_context.h>
-
-namespace grpc {
-namespace testing {
-
-/// A test-only class to access private members and methods of ServerContext.
-class ServerContextTestSpouse {
- public:
- explicit ServerContextTestSpouse(ServerContext* ctx) : ctx_(ctx) {}
-
- /// Inject client metadata to the ServerContext for the test. The test spouse
- /// must be alive when \a ServerContext::client_metadata is called.
- void AddClientMetadata(const grpc::string& key, const grpc::string& value) {
- client_metadata_storage_.insert(
- std::pair<grpc::string, grpc::string>(key, value));
- ctx_->client_metadata_.map()->clear();
- for (auto iter = client_metadata_storage_.begin();
- iter != client_metadata_storage_.end(); ++iter) {
- ctx_->client_metadata_.map()->insert(
- std::pair<grpc::string_ref, grpc::string_ref>(
- iter->first.c_str(),
- grpc::string_ref(iter->second.data(), iter->second.size())));
- }
- }
-
- std::multimap<grpc::string, grpc::string> GetInitialMetadata() const {
- return ctx_->initial_metadata_;
- }
-
- std::multimap<grpc::string, grpc::string> GetTrailingMetadata() const {
- return ctx_->trailing_metadata_;
- }
-
- private:
- ServerContext* ctx_; // not owned
- std::multimap<grpc::string, grpc::string> client_metadata_storage_;
-};
-
-} // namespace testing
-} // namespace grpc
+#include <grpcpp/test/server_context_test_spouse.h>
#endif // GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
diff --git a/include/grpc/byte_buffer.h b/include/grpc/byte_buffer.h
index 7669582af2..ee740f4794 100644
--- a/include/grpc/byte_buffer.h
+++ b/include/grpc/byte_buffer.h
@@ -19,6 +19,8 @@
#ifndef GRPC_BYTE_BUFFER_H
#define GRPC_BYTE_BUFFER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/byte_buffer.h>
#include <grpc/slice_buffer.h>
diff --git a/include/grpc/byte_buffer_reader.h b/include/grpc/byte_buffer_reader.h
index 6bd0784788..15e06cad7c 100644
--- a/include/grpc/byte_buffer_reader.h
+++ b/include/grpc/byte_buffer_reader.h
@@ -19,6 +19,8 @@
#ifndef GRPC_BYTE_BUFFER_READER_H
#define GRPC_BYTE_BUFFER_READER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/byte_buffer_reader.h>
#endif /* GRPC_BYTE_BUFFER_READER_H */
diff --git a/include/grpc/census.h b/include/grpc/census.h
index 2258af8898..4894f1c096 100644
--- a/include/grpc/census.h
+++ b/include/grpc/census.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CENSUS_H
#define GRPC_CENSUS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#ifdef __cplusplus
diff --git a/include/grpc/fork.h b/include/grpc/fork.h
index ca45e1139c..26f9df9871 100644
--- a/include/grpc/fork.h
+++ b/include/grpc/fork.h
@@ -19,6 +19,8 @@
#ifndef GRPC_FORK_H
#define GRPC_FORK_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/fork.h>
#endif /* GRPC_FORK_H */
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 47d749c728..c129a66949 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -19,6 +19,8 @@
#ifndef GRPC_GRPC_H
#define GRPC_GRPC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/status.h>
#include <grpc/byte_buffer.h>
@@ -269,9 +271,11 @@ GRPCAPI void grpc_channel_get_info(grpc_channel* channel,
/** Create a client channel to 'target'. Additional channel level configuration
MAY be provided by grpc_channel_args, though the expectation is that most
- clients will want to simply pass NULL. See grpc_channel_args definition for
- more on this. The data in 'args' need only live through the invocation of
- this function. */
+ clients will want to simply pass NULL. The user data in 'args' need only
+ live through the invocation of this function. However, if any args of the
+ 'pointer' type are passed, then the referenced vtable must be maintained
+ by the caller until grpc_channel_destroy terminates. See grpc_channel_args
+ definition for more on this. */
GRPCAPI grpc_channel* grpc_insecure_channel_create(
const char* target, const grpc_channel_args* args, void* reserved);
@@ -364,8 +368,11 @@ GRPCAPI grpc_call_error grpc_server_request_registered_call(
/** Create a server. Additional configuration for each incoming channel can
be specified with args. If no additional configuration is needed, args can
- be NULL. See grpc_channel_args for more. The data in 'args' need only live
- through the invocation of this function. */
+ be NULL. The user data in 'args' need only live through the invocation of
+ this function. However, if any args of the 'pointer' type are passed, then
+ the referenced vtable must be maintained by the caller until
+ grpc_server_destroy terminates. See grpc_channel_args definition for more
+ on this. */
GRPCAPI grpc_server* grpc_server_create(const grpc_channel_args* args,
void* reserved);
diff --git a/include/grpc/grpc_cronet.h b/include/grpc/grpc_cronet.h
index 127d5d038d..289cfcda67 100644
--- a/include/grpc/grpc_cronet.h
+++ b/include/grpc/grpc_cronet.h
@@ -19,6 +19,8 @@
#ifndef GRPC_GRPC_CRONET_H
#define GRPC_GRPC_CRONET_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#ifdef __cplusplus
diff --git a/include/grpc/grpc_posix.h b/include/grpc/grpc_posix.h
index fa7ebced3f..5f1ada5aaf 100644
--- a/include/grpc/grpc_posix.h
+++ b/include/grpc/grpc_posix.h
@@ -19,9 +19,10 @@
#ifndef GRPC_GRPC_POSIX_H
#define GRPC_GRPC_POSIX_H
-#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/port_platform.h>
+#include <grpc/impl/codegen/grpc_types.h>
+
#include <stddef.h>
#ifdef __cplusplus
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index bae07ac309..abc591fd75 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -19,6 +19,8 @@
#ifndef GRPC_GRPC_SECURITY_H
#define GRPC_GRPC_SECURITY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/grpc_security_constants.h>
#include <grpc/status.h>
@@ -300,7 +302,13 @@ GRPCAPI grpc_call_credentials* grpc_metadata_credentials_create_from_plugin(
/** --- Secure channel creation. --- */
-/** Creates a secure channel using the passed-in credentials. */
+/** Creates a secure channel using the passed-in credentials. Additional
+ channel level configuration MAY be provided by grpc_channel_args, though
+ the expectation is that most clients will want to simply pass NULL. The
+ user data in 'args' need only live through the invocation of this function.
+ However, if any args of the 'pointer' type are passed, then the referenced
+ vtable must be maintained by the caller until grpc_channel_destroy
+ terminates. See grpc_channel_args definition for more on this. */
GRPCAPI grpc_channel* grpc_secure_channel_create(
grpc_channel_credentials* creds, const char* target,
const grpc_channel_args* args, void* reserved);
diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h
index f8dfbd1d7d..774655ed66 100644
--- a/include/grpc/impl/codegen/byte_buffer.h
+++ b/include/grpc/impl/codegen/byte_buffer.h
@@ -19,6 +19,8 @@
#ifndef GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
+#include <grpc/impl/codegen/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#ifdef __cplusplus
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index efd0e28787..7d410c88b3 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -119,9 +119,14 @@ typedef struct {
These configuration options are modelled as key-value pairs as defined
by grpc_arg; keys are strings to allow easy backwards-compatible extension
by arbitrary parties. All evaluation is performed at channel creation
- time (i.e. the values in this structure need only live through the
+ time (i.e. the keys and values in this structure need only live through the
creation invocation).
+ However, if one of the args has grpc_arg_type==GRPC_ARG_POINTER, then the
+ grpc_arg_pointer_vtable must live until the channel args are done being
+ used by core (i.e. when the object for use with which they were passed
+ is destroyed).
+
See the description of the \ref grpc_arg_keys "available args" for more
details. */
typedef struct {
@@ -312,6 +317,17 @@ typedef struct {
Defaults to "blend". In the current implementation "blend" is equivalent to
"latency". */
#define GRPC_ARG_OPTIMIZATION_TARGET "grpc.optimization_target"
+/** If set to zero, disables retry behavior. Otherwise, transparent retries
+ are enabled for all RPCs, and configurable retries are enabled when they
+ are configured via the service config. For details, see:
+ https://github.com/grpc/proposal/blob/master/A6-client-retries.md
+ */
+#define GRPC_ARG_ENABLE_RETRIES "grpc.enable_retries"
+/** Per-RPC retry buffer size, in bytes. Default is 256 KiB. */
+#define GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE "grpc.per_rpc_retry_buffer_size"
+/** Channel arg that carries the bridged objective c object for custom metrics
+ * logging filter. */
+#define GRPC_ARG_MOBILE_LOG_CONFIG "grpc.mobile_log_config"
/** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a
@@ -549,6 +565,8 @@ typedef struct grpc_op {
} recv_initial_metadata;
/** ownership of the byte buffer is moved to the caller; the caller must
call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
+ The returned byte buffer will be NULL if trailing metadata was
+ received instead of a message.
*/
struct grpc_op_recv_message {
struct grpc_byte_buffer** recv_message;
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
index 6cdb0c5153..3df68c644f 100644
--- a/include/grpc/impl/codegen/sync.h
+++ b/include/grpc/impl/codegen/sync.h
@@ -43,6 +43,7 @@ extern "C" {
/* Platform-specific type declarations of gpr_mu and gpr_cv. */
#include <grpc/impl/codegen/port_platform.h>
+
#include <grpc/impl/codegen/sync_generic.h>
#if defined(GPR_POSIX_SYNC)
diff --git a/include/grpc/impl/codegen/sync_custom.h b/include/grpc/impl/codegen/sync_custom.h
index 0840ad26bf..69b1bf6cd1 100644
--- a/include/grpc/impl/codegen/sync_custom.h
+++ b/include/grpc/impl/codegen/sync_custom.h
@@ -19,6 +19,8 @@
#ifndef GRPC_IMPL_CODEGEN_SYNC_CUSTOM_H
#define GRPC_IMPL_CODEGEN_SYNC_CUSTOM_H
+#include <grpc/impl/codegen/port_platform.h>
+
#include <grpc/impl/codegen/sync_generic.h>
/* Users defining GPR_CUSTOM_SYNC need to define the following macros. */
diff --git a/include/grpc/impl/codegen/sync_generic.h b/include/grpc/impl/codegen/sync_generic.h
index 83f905e120..d64db58a84 100644
--- a/include/grpc/impl/codegen/sync_generic.h
+++ b/include/grpc/impl/codegen/sync_generic.h
@@ -20,6 +20,8 @@
#define GRPC_IMPL_CODEGEN_SYNC_GENERIC_H
/* Generic type defintions for gpr_sync. */
+#include <grpc/impl/codegen/port_platform.h>
+
#include <grpc/impl/codegen/atm.h>
/* gpr_event */
diff --git a/include/grpc/impl/codegen/sync_posix.h b/include/grpc/impl/codegen/sync_posix.h
index 6a3aed92c1..d927046c53 100644
--- a/include/grpc/impl/codegen/sync_posix.h
+++ b/include/grpc/impl/codegen/sync_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_IMPL_CODEGEN_SYNC_POSIX_H
#define GRPC_IMPL_CODEGEN_SYNC_POSIX_H
+#include <grpc/impl/codegen/port_platform.h>
+
#include <grpc/impl/codegen/sync_generic.h>
#include <pthread.h>
diff --git a/include/grpc/impl/codegen/sync_windows.h b/include/grpc/impl/codegen/sync_windows.h
index 39b127603d..ba5d5aede0 100644
--- a/include/grpc/impl/codegen/sync_windows.h
+++ b/include/grpc/impl/codegen/sync_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_IMPL_CODEGEN_SYNC_WINDOWS_H
#define GRPC_IMPL_CODEGEN_SYNC_WINDOWS_H
+#include <grpc/impl/codegen/port_platform.h>
+
#include <grpc/impl/codegen/sync_generic.h>
typedef struct {
diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap
index e5dac828b1..e0d5404e8a 100644
--- a/include/grpc/module.modulemap
+++ b/include/grpc/module.modulemap
@@ -11,7 +11,7 @@ framework module grpc {
header "support/string_util.h"
header "support/sync.h"
header "support/sync_generic.h"
- header "support/thd.h"
+ header "support/thd_id.h"
header "support/time.h"
header "impl/codegen/atm.h"
header "impl/codegen/fork.h"
diff --git a/include/grpc/slice.h b/include/grpc/slice.h
index 10b6a624b3..ce482922af 100644
--- a/include/grpc/slice.h
+++ b/include/grpc/slice.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SLICE_H
#define GRPC_SLICE_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/slice.h>
#include <grpc/support/sync.h>
diff --git a/include/grpc/slice_buffer.h b/include/grpc/slice_buffer.h
index 30833d02db..3260019ca7 100644
--- a/include/grpc/slice_buffer.h
+++ b/include/grpc/slice_buffer.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SLICE_BUFFER_H
#define GRPC_SLICE_BUFFER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#ifdef __cplusplus
diff --git a/include/grpc/status.h b/include/grpc/status.h
index 9d8f50bc02..ecb9668bbb 100644
--- a/include/grpc/status.h
+++ b/include/grpc/status.h
@@ -19,6 +19,8 @@
#ifndef GRPC_STATUS_H
#define GRPC_STATUS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/status.h>
#endif /* GRPC_STATUS_H */
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index 577d4f0069..8bd940bec4 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -19,9 +19,9 @@
#ifndef GRPC_SUPPORT_ALLOC_H
#define GRPC_SUPPORT_ALLOC_H
-#include <stddef.h>
+#include <grpc/support/port_platform.h>
-#include <grpc/impl/codegen/port_platform.h>
+#include <stddef.h>
#ifdef __cplusplus
extern "C" {
diff --git a/include/grpc/support/atm.h b/include/grpc/support/atm.h
index b3afa520a0..073b0a6fcf 100644
--- a/include/grpc/support/atm.h
+++ b/include/grpc/support/atm.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_ATM_H
#define GRPC_SUPPORT_ATM_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/atm.h>
#endif /* GRPC_SUPPORT_ATM_H */
diff --git a/include/grpc/support/atm_gcc_atomic.h b/include/grpc/support/atm_gcc_atomic.h
index e7b5ec402f..ae603db497 100644
--- a/include/grpc/support/atm_gcc_atomic.h
+++ b/include/grpc/support/atm_gcc_atomic.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_ATM_GCC_ATOMIC_H
#define GRPC_SUPPORT_ATM_GCC_ATOMIC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/atm_gcc_atomic.h>
#endif /* GRPC_SUPPORT_ATM_GCC_ATOMIC_H */
diff --git a/include/grpc/support/atm_gcc_sync.h b/include/grpc/support/atm_gcc_sync.h
index 7284897706..6f51fdb1aa 100644
--- a/include/grpc/support/atm_gcc_sync.h
+++ b/include/grpc/support/atm_gcc_sync.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_ATM_GCC_SYNC_H
#define GRPC_SUPPORT_ATM_GCC_SYNC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/atm_gcc_sync.h>
#endif /* GRPC_SUPPORT_ATM_GCC_SYNC_H */
diff --git a/include/grpc/support/atm_windows.h b/include/grpc/support/atm_windows.h
index 554c59a830..36955e4dae 100644
--- a/include/grpc/support/atm_windows.h
+++ b/include/grpc/support/atm_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_ATM_WINDOWS_H
#define GRPC_SUPPORT_ATM_WINDOWS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/atm_windows.h>
#endif /* GRPC_SUPPORT_ATM_WINDOWS_H */
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index a8371cbd48..ccb4b304cc 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -19,12 +19,12 @@
#ifndef GRPC_SUPPORT_LOG_H
#define GRPC_SUPPORT_LOG_H
+#include <grpc/impl/codegen/port_platform.h>
+
#include <inttypes.h>
#include <stdarg.h>
#include <stdlib.h> /* for abort() */
-#include <grpc/impl/codegen/port_platform.h>
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index 75192673a6..91d1fa79b5 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_SYNC_H
#define GRPC_SUPPORT_SYNC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/gpr_types.h> /* for gpr_timespec */
#include <grpc/impl/codegen/sync.h>
diff --git a/include/grpc/support/sync_custom.h b/include/grpc/support/sync_custom.h
index b575f5e002..27cf0e0578 100644
--- a/include/grpc/support/sync_custom.h
+++ b/include/grpc/support/sync_custom.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_SYNC_CUSTOM_H
#define GRPC_SUPPORT_SYNC_CUSTOM_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/sync_custom.h>
#endif /* GRPC_SUPPORT_SYNC_CUSTOM_H */
diff --git a/include/grpc/support/sync_generic.h b/include/grpc/support/sync_generic.h
index 970b7a5d9f..93028c4af0 100644
--- a/include/grpc/support/sync_generic.h
+++ b/include/grpc/support/sync_generic.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_SYNC_GENERIC_H
#define GRPC_SUPPORT_SYNC_GENERIC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/sync_generic.h>
#endif /* GRPC_SUPPORT_SYNC_GENERIC_H */
diff --git a/include/grpc/support/sync_posix.h b/include/grpc/support/sync_posix.h
index 482a6004ee..3dce7ee48c 100644
--- a/include/grpc/support/sync_posix.h
+++ b/include/grpc/support/sync_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_SYNC_POSIX_H
#define GRPC_SUPPORT_SYNC_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/sync_posix.h>
#endif /* GRPC_SUPPORT_SYNC_POSIX_H */
diff --git a/include/grpc/support/sync_windows.h b/include/grpc/support/sync_windows.h
index 90ce8b7765..a493c86422 100644
--- a/include/grpc/support/sync_windows.h
+++ b/include/grpc/support/sync_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_SYNC_WINDOWS_H
#define GRPC_SUPPORT_SYNC_WINDOWS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/sync_windows.h>
#endif /* GRPC_SUPPORT_SYNC_WINDOWS_H */
diff --git a/include/grpc/support/thd_id.h b/include/grpc/support/thd_id.h
new file mode 100644
index 0000000000..e9b2b7ec2a
--- /dev/null
+++ b/include/grpc/support/thd_id.h
@@ -0,0 +1,44 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_SUPPORT_THD_ID_H
+#define GRPC_SUPPORT_THD_ID_H
+/** Thread ID interface for GPR.
+
+ Used by some wrapped languages for logging purposes.
+
+ Types
+ gpr_thd_id a unique opaque identifier for a thread.
+ */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uintptr_t gpr_thd_id;
+
+/** Returns the identifier of the current thread. */
+GPRAPI gpr_thd_id gpr_thd_currentid(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_SUPPORT_THD_ID_H */
diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index 62d354aafe..550ffc2c20 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -19,6 +19,8 @@
#ifndef GRPC_SUPPORT_TIME_H
#define GRPC_SUPPORT_TIME_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/gpr_types.h>
#include <stddef.h>
diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h
new file mode 100644
index 0000000000..f484610a6e
--- /dev/null
+++ b/include/grpcpp/alarm.h
@@ -0,0 +1,87 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/// An Alarm posts the user provided tag to its associated completion queue upon
+/// expiry or cancellation.
+#ifndef GRPCPP_ALARM_H
+#define GRPCPP_ALARM_H
+
+#include <grpc/grpc.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+#include <grpcpp/impl/codegen/time.h>
+#include <grpcpp/impl/grpc_library.h>
+
+namespace grpc {
+
+/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
+class Alarm : private GrpcLibraryCodegen {
+ public:
+ /// Create an unset completion queue alarm
+ Alarm();
+
+ /// Destroy the given completion queue alarm, cancelling it in the process.
+ ~Alarm();
+
+ /// DEPRECATED: Create and set a completion queue alarm instance associated to
+ /// \a cq.
+ /// This form is deprecated because it is inherently racy.
+ /// \internal We rely on the presence of \a cq for grpc initialization. If \a
+ /// cq were ever to be removed, a reference to a static
+ /// internal::GrpcLibraryInitializer instance would need to be introduced
+ /// here. \endinternal.
+ template <typename T>
+ Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() {
+ SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
+ }
+
+ /// Trigger an alarm instance on completion queue \a cq at the specified time.
+ /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
+ /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
+ /// event's success bit will be true, false otherwise (ie, upon cancellation).
+ template <typename T>
+ void Set(CompletionQueue* cq, const T& deadline, void* tag) {
+ SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
+ }
+
+ /// Alarms aren't copyable.
+ Alarm(const Alarm&) = delete;
+ Alarm& operator=(const Alarm&) = delete;
+
+ /// Alarms are movable.
+ Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
+ Alarm& operator=(Alarm&& rhs) {
+ alarm_ = rhs.alarm_;
+ rhs.alarm_ = nullptr;
+ return *this;
+ }
+
+ /// Cancel a completion queue alarm. Calling this function over an alarm that
+ /// has already fired has no effect.
+ void Cancel();
+
+ private:
+ void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag);
+
+ internal::CompletionQueueTag* alarm_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_ALARM_H
diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h
new file mode 100644
index 0000000000..4b45d5382c
--- /dev/null
+++ b/include/grpcpp/channel.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_CHANNEL_H
+#define GRPCPP_CHANNEL_H
+
+#include <memory>
+
+#include <grpc/grpc.h>
+#include <grpcpp/impl/call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+
+struct grpc_channel;
+
+namespace grpc {
+/// Channels represent a connection to an endpoint. Created by \a CreateChannel.
+class Channel final : public ChannelInterface,
+ public internal::CallHook,
+ public std::enable_shared_from_this<Channel>,
+ private GrpcLibraryCodegen {
+ public:
+ ~Channel();
+
+ /// Get the current channel state. If the channel is in IDLE and
+ /// \a try_to_connect is set to true, try to connect.
+ grpc_connectivity_state GetState(bool try_to_connect) override;
+
+ /// Returns the LB policy name, or the empty string if not yet available.
+ grpc::string GetLoadBalancingPolicyName() const;
+
+ /// Returns the service config in JSON form, or the empty string if
+ /// not available.
+ grpc::string GetServiceConfigJSON() const;
+
+ private:
+ template <class InputMessage, class OutputMessage>
+ friend class internal::BlockingUnaryCallImpl;
+ friend std::shared_ptr<Channel> CreateChannelInternal(
+ const grpc::string& host, grpc_channel* c_channel);
+ Channel(const grpc::string& host, grpc_channel* c_channel);
+
+ internal::Call CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) override;
+ void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) override;
+ void* RegisterMethod(const char* method) override;
+
+ void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
+ gpr_timespec deadline, CompletionQueue* cq,
+ void* tag) override;
+ bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
+ gpr_timespec deadline) override;
+
+ const grpc::string host_;
+ grpc_channel* const c_channel_; // owned
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_CHANNEL_H
diff --git a/include/grpcpp/client_context.h b/include/grpcpp/client_context.h
new file mode 100644
index 0000000000..8c12577a17
--- /dev/null
+++ b/include/grpcpp/client_context.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/// A ClientContext allows the person implementing a service client to:
+///
+/// - Add custom metadata key-value pairs that will propagated to the server
+/// side.
+/// - Control call settings such as compression and authentication.
+/// - Initial and trailing metadata coming from the server.
+/// - Get performance metrics (ie, census).
+///
+/// Context settings are only relevant to the call they are invoked with, that
+/// is to say, they aren't sticky. Some of these settings, such as the
+/// compression options, can be made persistant at channel construction time
+/// (see \a grpc::CreateCustomChannel).
+///
+/// \warning ClientContext instances should \em not be reused across rpcs.
+
+#ifndef GRPCPP_CLIENT_CONTEXT_H
+#define GRPCPP_CLIENT_CONTEXT_H
+
+#include <grpcpp/impl/codegen/client_context.h>
+
+#endif // GRPCPP_CLIENT_CONTEXT_H
diff --git a/include/grpcpp/completion_queue.h b/include/grpcpp/completion_queue.h
new file mode 100644
index 0000000000..123b277f5f
--- /dev/null
+++ b/include/grpcpp/completion_queue.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_COMPLETION_QUEUE_H
+#define GRPCPP_COMPLETION_QUEUE_H
+
+#include <grpcpp/impl/codegen/completion_queue.h>
+
+#endif // GRPCPP_COMPLETION_QUEUE_H
diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h
new file mode 100644
index 0000000000..7a505a7127
--- /dev/null
+++ b/include/grpcpp/create_channel.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_CREATE_CHANNEL_H
+#define GRPCPP_CREATE_CHANNEL_H
+
+#include <memory>
+
+#include <grpcpp/channel.h>
+#include <grpcpp/security/credentials.h>
+#include <grpcpp/support/channel_arguments.h>
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+
+/// Create a new \a Channel pointing to \a target.
+///
+/// \param target The URI of the endpoint to connect to.
+/// \param creds Credentials to use for the created channel. If it does not
+/// hold an object or is invalid, a lame channel (one on which all operations
+/// fail) is returned.
+std::shared_ptr<Channel> CreateChannel(
+ const grpc::string& target,
+ const std::shared_ptr<ChannelCredentials>& creds);
+
+/// Create a new \em custom \a Channel pointing to \a target.
+///
+/// \warning For advanced use and testing ONLY. Override default channel
+/// arguments only if necessary.
+///
+/// \param target The URI of the endpoint to connect to.
+/// \param creds Credentials to use for the created channel. If it does not
+/// hold an object or is invalid, a lame channel (one on which all operations
+/// fail) is returned.
+/// \param args Options for channel creation.
+std::shared_ptr<Channel> CreateCustomChannel(
+ const grpc::string& target,
+ const std::shared_ptr<ChannelCredentials>& creds,
+ const ChannelArguments& args);
+
+} // namespace grpc
+
+#endif // GRPCPP_CREATE_CHANNEL_H
diff --git a/include/grpcpp/create_channel_posix.h b/include/grpcpp/create_channel_posix.h
new file mode 100644
index 0000000000..9bf5acc45c
--- /dev/null
+++ b/include/grpcpp/create_channel_posix.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_CREATE_CHANNEL_POSIX_H
+#define GRPCPP_CREATE_CHANNEL_POSIX_H
+
+#include <memory>
+
+#include <grpc/support/port_platform.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/support/channel_arguments.h>
+
+namespace grpc {
+
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
+
+/// Create a new \a Channel communicating over the given file descriptor.
+///
+/// \param target The name of the target.
+/// \param fd The file descriptor representing a socket.
+std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
+ int fd);
+
+/// Create a new \a Channel communicating over given file descriptor with custom
+/// channel arguments.
+///
+/// \param target The name of the target.
+/// \param fd The file descriptor representing a socket.
+/// \param args Options for channel creation.
+std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
+ const grpc::string& target, int fd, const ChannelArguments& args);
+
+#endif // GPR_SUPPORT_CHANNELS_FROM_FD
+
+} // namespace grpc
+
+#endif // GRPCPP_CREATE_CHANNEL_POSIX_H
diff --git a/include/grpcpp/ext/health_check_service_server_builder_option.h b/include/grpcpp/ext/health_check_service_server_builder_option.h
new file mode 100644
index 0000000000..dd43b05ef0
--- /dev/null
+++ b/include/grpcpp/ext/health_check_service_server_builder_option.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
+#define GRPCPP_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
+
+#include <memory>
+
+#include <grpcpp/health_check_service_interface.h>
+#include <grpcpp/impl/server_builder_option.h>
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+
+class HealthCheckServiceServerBuilderOption : public ServerBuilderOption {
+ public:
+ /// The ownership of \a hc will be taken and transferred to the grpc server.
+ /// To explicitly disable default service, pass in a nullptr.
+ explicit HealthCheckServiceServerBuilderOption(
+ std::unique_ptr<HealthCheckServiceInterface> hc);
+ ~HealthCheckServiceServerBuilderOption() override {}
+ void UpdateArguments(ChannelArguments* args) override;
+ void UpdatePlugins(
+ std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) override;
+
+ private:
+ std::unique_ptr<HealthCheckServiceInterface> hc_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
diff --git a/include/grpcpp/ext/proto_server_reflection_plugin.h b/include/grpcpp/ext/proto_server_reflection_plugin.h
new file mode 100644
index 0000000000..1cfdc1b6cc
--- /dev/null
+++ b/include/grpcpp/ext/proto_server_reflection_plugin.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
+#define GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
+
+#include <grpcpp/impl/server_builder_plugin.h>
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+class ServerInitializer;
+class ProtoServerReflection;
+} // namespace grpc
+
+namespace grpc {
+namespace reflection {
+
+class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
+ public:
+ ProtoServerReflectionPlugin();
+ ::grpc::string name() override;
+ void InitServer(::grpc::ServerInitializer* si) override;
+ void Finish(::grpc::ServerInitializer* si) override;
+ void ChangeArguments(const ::grpc::string& name, void* value) override;
+ bool has_async_methods() const override;
+ bool has_sync_methods() const override;
+
+ private:
+ std::shared_ptr<grpc::ProtoServerReflection> reflection_service_;
+};
+
+/// Add proto reflection plugin to \a ServerBuilder.
+/// This function should be called at the static initialization time.
+void InitProtoReflectionServerBuilderPlugin();
+
+} // namespace reflection
+} // namespace grpc
+
+#endif // GRPCPP_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
diff --git a/include/grpcpp/generic/async_generic_service.h b/include/grpcpp/generic/async_generic_service.h
new file mode 100644
index 0000000000..7eaa541151
--- /dev/null
+++ b/include/grpcpp/generic/async_generic_service.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
+#define GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
+
+#include <grpcpp/support/async_stream.h>
+#include <grpcpp/support/byte_buffer.h>
+
+struct grpc_server;
+
+namespace grpc {
+
+typedef ServerAsyncReaderWriter<ByteBuffer, ByteBuffer>
+ GenericServerAsyncReaderWriter;
+
+class GenericServerContext final : public ServerContext {
+ public:
+ const grpc::string& method() const { return method_; }
+ const grpc::string& host() const { return host_; }
+
+ private:
+ friend class Server;
+ friend class ServerInterface;
+
+ grpc::string method_;
+ grpc::string host_;
+};
+
+// A generic service at the server side accepts all RPC methods and hosts. It is
+// typically used in proxies. The generic service can be registered to a server
+// which also has other services.
+// Sample usage:
+// ServerBuilder builder;
+// auto cq = builder.AddCompletionQueue();
+// AsyncGenericService generic_service;
+// builder.RegisterAsyncGeneicService(&generic_service);
+// auto server = builder.BuildAndStart();
+//
+// // request a new call
+// GenericServerContext context;
+// GenericAsyncReaderWriter stream;
+// generic_service.RequestCall(&context, &stream, cq.get(), cq.get(), tag);
+//
+// When tag is retrieved from cq->Next(), context.method() can be used to look
+// at the method and the RPC can be handled accordingly.
+class AsyncGenericService final {
+ public:
+ AsyncGenericService() : server_(nullptr) {}
+
+ void RequestCall(GenericServerContext* ctx,
+ GenericServerAsyncReaderWriter* reader_writer,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag);
+
+ private:
+ friend class Server;
+ Server* server_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_GENERIC_ASYNC_GENERIC_SERVICE_H
diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h
new file mode 100644
index 0000000000..92405a43fa
--- /dev/null
+++ b/include/grpcpp/generic/generic_stub.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_GENERIC_GENERIC_STUB_H
+#define GRPCPP_GENERIC_GENERIC_STUB_H
+
+#include <grpcpp/support/async_stream.h>
+#include <grpcpp/support/async_unary_call.h>
+#include <grpcpp/support/byte_buffer.h>
+
+namespace grpc {
+
+class CompletionQueue;
+typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer>
+ GenericClientAsyncReaderWriter;
+typedef ClientAsyncResponseReader<ByteBuffer> GenericClientAsyncResponseReader;
+
+/// Generic stubs provide a type-unsafe interface to call gRPC methods
+/// by name.
+class GenericStub final {
+ public:
+ explicit GenericStub(std::shared_ptr<ChannelInterface> channel)
+ : channel_(channel) {}
+
+ /// Setup a call to a named method \a method using \a context, but don't
+ /// start it. Let it be started explicitly with StartCall and a tag.
+ /// The return value only indicates whether or not registration of the call
+ /// succeeded (i.e. the call won't proceed if the return value is nullptr).
+ std::unique_ptr<GenericClientAsyncReaderWriter> PrepareCall(
+ ClientContext* context, const grpc::string& method, CompletionQueue* cq);
+
+ /// Setup a unary call to a named method \a method using \a context, and don't
+ /// start it. Let it be started explicitly with StartCall.
+ /// The return value only indicates whether or not registration of the call
+ /// succeeded (i.e. the call won't proceed if the return value is nullptr).
+ std::unique_ptr<GenericClientAsyncResponseReader> PrepareUnaryCall(
+ ClientContext* context, const grpc::string& method,
+ const ByteBuffer& request, CompletionQueue* cq);
+
+ /// DEPRECATED for multi-threaded use
+ /// Begin a call to a named method \a method using \a context.
+ /// A tag \a tag will be delivered to \a cq when the call has been started
+ /// (i.e, initial metadata has been sent).
+ /// The return value only indicates whether or not registration of the call
+ /// succeeded (i.e. the call won't proceed if the return value is nullptr).
+ std::unique_ptr<GenericClientAsyncReaderWriter> Call(
+ ClientContext* context, const grpc::string& method, CompletionQueue* cq,
+ void* tag);
+
+ private:
+ std::shared_ptr<ChannelInterface> channel_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_GENERIC_GENERIC_STUB_H
diff --git a/include/grpcpp/grpcpp.h b/include/grpcpp/grpcpp.h
new file mode 100644
index 0000000000..aa8a24203b
--- /dev/null
+++ b/include/grpcpp/grpcpp.h
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/// \mainpage gRPC C++ API
+///
+/// The gRPC C++ API mainly consists of the following classes:
+/// <br>
+/// - grpc::Channel, which represents the connection to an endpoint. See [the
+/// gRPC Concepts page](https://grpc.io/docs/guides/concepts.html) for more
+/// details. Channels are created by the factory function grpc::CreateChannel.
+///
+/// - grpc::CompletionQueue, the producer-consumer queue used for all
+/// asynchronous communication with the gRPC runtime.
+///
+/// - grpc::ClientContext and grpc::ServerContext, where optional configuration
+/// for an RPC can be set, such as setting custom metadata to be conveyed to the
+/// peer, compression settings, authentication, etc.
+///
+/// - grpc::Server, representing a gRPC server, created by grpc::ServerBuilder.
+///
+/// Streaming calls are handled with the streaming classes in
+/// \ref sync_stream.h and
+/// \ref async_stream.h.
+///
+/// Refer to the
+/// [examples](https://github.com/grpc/grpc/blob/master/examples/cpp)
+/// for code putting these pieces into play.
+
+#ifndef GRPCPP_GRPCPP_H
+#define GRPCPP_GRPCPP_H
+
+// Pragma for http://include-what-you-use.org/ tool, tells that following
+// headers are not private for grpcpp.h and are part of its interface.
+// IWYU pragma: begin_exports
+#include <grpc/grpc.h>
+
+#include <grpcpp/channel.h>
+#include <grpcpp/client_context.h>
+#include <grpcpp/completion_queue.h>
+#include <grpcpp/create_channel.h>
+#include <grpcpp/create_channel_posix.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+#include <grpcpp/server_context.h>
+#include <grpcpp/server_posix.h>
+// IWYU pragma: end_exports
+
+namespace grpc {
+/// Return gRPC library version.
+grpc::string Version();
+} // namespace grpc
+
+#endif // GRPCPP_GRPCPP_H
diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h
new file mode 100644
index 0000000000..b45a699bda
--- /dev/null
+++ b/include/grpcpp/health_check_service_interface.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H
+#define GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H
+
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+
+const char kHealthCheckServiceInterfaceArg[] =
+ "grpc.health_check_service_interface";
+
+/// The gRPC server uses this interface to expose the health checking service
+/// without depending on protobuf.
+class HealthCheckServiceInterface {
+ public:
+ virtual ~HealthCheckServiceInterface() {}
+
+ /// Set or change the serving status of the given \a service_name.
+ virtual void SetServingStatus(const grpc::string& service_name,
+ bool serving) = 0;
+ /// Apply to all registered service names.
+ virtual void SetServingStatus(bool serving) = 0;
+};
+
+/// Enable/disable the default health checking service. This applies to all C++
+/// servers created afterwards. For each server, user can override the default
+/// with a HealthCheckServiceServerBuilderOption.
+/// NOT thread safe.
+void EnableDefaultHealthCheckService(bool enable);
+
+/// Returns whether the default health checking service is enabled.
+/// NOT thread safe.
+bool DefaultHealthCheckServiceEnabled();
+
+} // namespace grpc
+
+#endif // GRPCPP_HEALTH_CHECK_SERVICE_INTERFACE_H
diff --git a/include/grpc++/impl/README.md b/include/grpcpp/impl/README.md
index 612150caa0..612150caa0 100644
--- a/include/grpc++/impl/README.md
+++ b/include/grpcpp/impl/README.md
diff --git a/include/grpcpp/impl/call.h b/include/grpcpp/impl/call.h
new file mode 100644
index 0000000000..a6b1312693
--- /dev/null
+++ b/include/grpcpp/impl/call.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CALL_H
+#define GRPCPP_IMPL_CALL_H
+
+#include <grpcpp/impl/codegen/call.h>
+
+#endif // GRPCPP_IMPL_CALL_H
diff --git a/src/core/lib/security/transport/lb_targets_info.h b/include/grpcpp/impl/channel_argument_option.h
index 7543d3c012..0c4882478e 100644
--- a/src/core/lib/security/transport/lb_targets_info.h
+++ b/include/grpcpp/impl/channel_argument_option.h
@@ -16,17 +16,22 @@
*
*/
-#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
-#define GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H
+#ifndef GRPCPP_IMPL_CHANNEL_ARGUMENT_OPTION_H
+#define GRPCPP_IMPL_CHANNEL_ARGUMENT_OPTION_H
-#include "src/core/lib/slice/slice_hash_table.h"
+#include <map>
+#include <memory>
-/** Return a channel argument containing \a targets_info. */
-grpc_arg grpc_lb_targets_info_create_channel_arg(
- grpc_slice_hash_table* targets_info);
+#include <grpcpp/impl/server_builder_option.h>
+#include <grpcpp/support/channel_arguments.h>
-/** Return the instance of targets info in \a args or NULL */
-grpc_slice_hash_table* grpc_lb_targets_info_find_in_args(
- const grpc_channel_args* args);
+namespace grpc {
-#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_LB_TARGETS_INFO_H */
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+ const grpc::string& name, const grpc::string& value);
+std::unique_ptr<ServerBuilderOption> MakeChannelArgumentOption(
+ const grpc::string& name, int value);
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CHANNEL_ARGUMENT_OPTION_H
diff --git a/include/grpcpp/impl/client_unary_call.h b/include/grpcpp/impl/client_unary_call.h
new file mode 100644
index 0000000000..378482c540
--- /dev/null
+++ b/include/grpcpp/impl/client_unary_call.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CLIENT_UNARY_CALL_H
+#define GRPCPP_IMPL_CLIENT_UNARY_CALL_H
+
+#include <grpcpp/impl/codegen/client_unary_call.h>
+
+#endif // GRPCPP_IMPL_CLIENT_UNARY_CALL_H
diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h
new file mode 100644
index 0000000000..b2134590c3
--- /dev/null
+++ b/include/grpcpp/impl/codegen/async_stream.h
@@ -0,0 +1,1068 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
+#define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
+
+#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+class CompletionQueue;
+
+namespace internal {
+/// Common interface for all client side asynchronous streaming.
+class ClientAsyncStreamingInterface {
+ public:
+ virtual ~ClientAsyncStreamingInterface() {}
+
+ /// Start the call that was set up by the constructor, but only if the
+ /// constructor was invoked through the "Prepare" API which doesn't actually
+ /// start the call
+ virtual void StartCall(void* tag) = 0;
+
+ /// Request notification of the reading of the initial metadata. Completion
+ /// will be notified by \a tag on the associated completion queue.
+ /// This call is optional, but if it is used, it cannot be used concurrently
+ /// with or after the \a AsyncReaderInterface::Read method.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ virtual void ReadInitialMetadata(void* tag) = 0;
+
+ /// Indicate that the stream is to be finished and request notification for
+ /// when the call has been ended.
+ /// Should not be used concurrently with other operations.
+ ///
+ /// It is appropriate to call this method when both:
+ /// * the client side has no more message to send
+ /// (this can be declared implicitly by calling this method, or
+ /// explicitly through an earlier call to the <i>WritesDone</i> method
+ /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or
+ /// \a ClientAsyncReaderWriterInterface::WritesDone).
+ /// * there are no more messages to be received from the server (this can
+ /// be known implicitly by the calling code, or explicitly from an
+ /// earlier call to \a AsyncReaderInterface::Read that yielded a failed
+ /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
+ ///
+ /// This function will return when either:
+ /// - all incoming messages have been read and the server has returned
+ /// a status.
+ /// - the server has returned a non-OK status.
+ /// - the call failed for some reason and the library generated a
+ /// status.
+ ///
+ /// Note that implementations of this method attempt to receive initial
+ /// metadata from the server if initial metadata hasn't yet been received.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[out] status To be updated with the operation status.
+ virtual void Finish(Status* status, void* tag) = 0;
+};
+
+/// An interface that yields a sequence of messages of type \a R.
+template <class R>
+class AsyncReaderInterface {
+ public:
+ virtual ~AsyncReaderInterface() {}
+
+ /// Read a message of type \a R into \a msg. Completion will be notified by \a
+ /// tag on the associated completion queue.
+ /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
+ /// should not be called concurrently with other streaming APIs
+ /// on the same stream. It is not meaningful to call it concurrently
+ /// with another \a AsyncReaderInterface::Read on the same stream since reads
+ /// on the same stream are delivered in order.
+ ///
+ /// \param[out] msg Where to eventually store the read message.
+ /// \param[in] tag The tag identifying the operation.
+ ///
+ /// Side effect: note that this method attempt to receive initial metadata for
+ /// a stream if it hasn't yet been received.
+ virtual void Read(R* msg, void* tag) = 0;
+};
+
+/// An interface that can be fed a sequence of messages of type \a W.
+template <class W>
+class AsyncWriterInterface {
+ public:
+ virtual ~AsyncWriterInterface() {}
+
+ /// Request the writing of \a msg with identifying tag \a tag.
+ ///
+ /// Only one write may be outstanding at any given time. This means that
+ /// after calling Write, one must wait to receive \a tag from the completion
+ /// queue BEFORE calling Write again.
+ /// This is thread-safe with respect to \a AsyncReaderInterface::Read
+ ///
+ /// \param[in] msg The message to be written.
+ /// \param[in] tag The tag identifying the operation.
+ virtual void Write(const W& msg, void* tag) = 0;
+
+ /// Request the writing of \a msg using WriteOptions \a options with
+ /// identifying tag \a tag.
+ ///
+ /// Only one write may be outstanding at any given time. This means that
+ /// after calling Write, one must wait to receive \a tag from the completion
+ /// queue BEFORE calling Write again.
+ /// WriteOptions \a options is used to set the write options of this message.
+ /// This is thread-safe with respect to \a AsyncReaderInterface::Read
+ ///
+ /// \param[in] msg The message to be written.
+ /// \param[in] options The WriteOptions to be used to write this message.
+ /// \param[in] tag The tag identifying the operation.
+ virtual void Write(const W& msg, WriteOptions options, void* tag) = 0;
+
+ /// Request the writing of \a msg and coalesce it with the writing
+ /// of trailing metadata, using WriteOptions \a options with
+ /// identifying tag \a tag.
+ ///
+ /// For client, WriteLast is equivalent of performing Write and
+ /// WritesDone in a single step.
+ /// For server, WriteLast buffers the \a msg. The writing of \a msg is held
+ /// until Finish is called, where \a msg and trailing metadata are coalesced
+ /// and write is initiated. Note that WriteLast can only buffer \a msg up to
+ /// the flow control window size. If \a msg size is larger than the window
+ /// size, it will be sent on wire without buffering.
+ ///
+ /// \param[in] msg The message to be written.
+ /// \param[in] options The WriteOptions to be used to write this message.
+ /// \param[in] tag The tag identifying the operation.
+ void WriteLast(const W& msg, WriteOptions options, void* tag) {
+ Write(msg, options.set_last_message(), tag);
+ }
+};
+
+} // namespace internal
+
+template <class R>
+class ClientAsyncReaderInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncReaderInterface<R> {};
+
+namespace internal {
+template <class R>
+class ClientAsyncReaderFactory {
+ public:
+ /// Create a stream object.
+ /// Write the first request out if \a start is set.
+ /// \a tag will be notified on \a cq when the call has been started and
+ /// \a request has been written out. If \a start is not set, \a tag must be
+ /// nullptr and the actual call must be initiated by StartCall
+ /// Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ template <class W>
+ static ClientAsyncReader<R>* Create(ChannelInterface* channel,
+ CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
+ return new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientAsyncReader<R>)))
+ ClientAsyncReader<R>(call, context, request, start, tag);
+ }
+};
+} // namespace internal
+
+/// Async client-side API for doing server-streaming RPCs,
+/// where the incoming message stream coming from the server has
+/// messages of type \a R.
+template <class R>
+class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientAsyncReader));
+ }
+
+ void StartCall(void* tag) override {
+ assert(!started_);
+ started_ = true;
+ StartCallInternal(tag);
+ }
+
+ /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata
+ /// method for semantics.
+ ///
+ /// Side effect:
+ /// - upon receiving initial metadata from the server,
+ /// the \a ClientContext associated with this call is updated, and the
+ /// calling code can access the received metadata through the
+ /// \a ClientContext.
+ void ReadInitialMetadata(void* tag) override {
+ assert(started_);
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ meta_ops_.set_output_tag(tag);
+ meta_ops_.RecvInitialMetadata(context_);
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Read(R* msg, void* tag) override {
+ assert(started_);
+ read_ops_.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ read_ops_.RecvInitialMetadata(context_);
+ }
+ read_ops_.RecvMessage(msg);
+ call_.PerformOps(&read_ops_);
+ }
+
+ /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
+ ///
+ /// Side effect:
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible initial and trailing metadata received from the server.
+ void Finish(Status* status, void* tag) override {
+ assert(started_);
+ finish_ops_.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ finish_ops_.RecvInitialMetadata(context_);
+ }
+ finish_ops_.ClientRecvStatus(context_, status);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ private:
+ friend class internal::ClientAsyncReaderFactory<R>;
+ template <class W>
+ ClientAsyncReader(::grpc::internal::Call call, ClientContext* context,
+ const W& request, bool start, void* tag)
+ : context_(context), call_(call), started_(start) {
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
+ init_ops_.ClientSendClose();
+ if (start) {
+ StartCallInternal(tag);
+ } else {
+ assert(tag == nullptr);
+ }
+ }
+
+ void StartCallInternal(void* tag) {
+ init_ops_.SendInitialMetadata(context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ init_ops_.set_output_tag(tag);
+ call_.PerformOps(&init_ops_);
+ }
+
+ ClientContext* context_;
+ ::grpc::internal::Call call_;
+ bool started_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ init_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
+};
+
+/// Common interface for client side asynchronous writing.
+template <class W>
+class ClientAsyncWriterInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W> {
+ public:
+ /// Signal the client is done with the writes (half-close the client stream).
+ /// Thread-safe with respect to \a AsyncReaderInterface::Read
+ ///
+ /// \param[in] tag The tag identifying the operation.
+ virtual void WritesDone(void* tag) = 0;
+};
+
+namespace internal {
+template <class W>
+class ClientAsyncWriterFactory {
+ public:
+ /// Create a stream object.
+ /// Start the RPC if \a start is set
+ /// \a tag will be notified on \a cq when the call has been started (i.e.
+ /// intitial metadata sent) and \a request has been written out.
+ /// If \a start is not set, \a tag must be nullptr and the actual call
+ /// must be initiated by StartCall
+ /// Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ /// \a response will be filled in with the single expected response
+ /// message from the server upon a successful call to the \a Finish
+ /// method of this instance.
+ template <class R>
+ static ClientAsyncWriter<W>* Create(ChannelInterface* channel,
+ CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
+ return new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientAsyncWriter<W>)))
+ ClientAsyncWriter<W>(call, context, response, start, tag);
+ }
+};
+} // namespace internal
+
+/// Async API on the client side for doing client-streaming RPCs,
+/// where the outgoing message stream going to the server contains
+/// messages of type \a W.
+template <class W>
+class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientAsyncWriter));
+ }
+
+ void StartCall(void* tag) override {
+ assert(!started_);
+ started_ = true;
+ StartCallInternal(tag);
+ }
+
+ /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for
+ /// semantics.
+ ///
+ /// Side effect:
+ /// - upon receiving initial metadata from the server, the \a ClientContext
+ /// associated with this call is updated, and the calling code can access
+ /// the received metadata through the \a ClientContext.
+ void ReadInitialMetadata(void* tag) override {
+ assert(started_);
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ meta_ops_.set_output_tag(tag);
+ meta_ops_.RecvInitialMetadata(context_);
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Write(const W& msg, void* tag) override {
+ assert(started_);
+ write_ops_.set_output_tag(tag);
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void Write(const W& msg, WriteOptions options, void* tag) override {
+ assert(started_);
+ write_ops_.set_output_tag(tag);
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ write_ops_.ClientSendClose();
+ }
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void WritesDone(void* tag) override {
+ assert(started_);
+ write_ops_.set_output_tag(tag);
+ write_ops_.ClientSendClose();
+ call_.PerformOps(&write_ops_);
+ }
+
+ /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
+ ///
+ /// Side effect:
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible initial and trailing metadata received from the server.
+ /// - attempts to fill in the \a response parameter passed to this class's
+ /// constructor with the server's response message.
+ void Finish(Status* status, void* tag) override {
+ assert(started_);
+ finish_ops_.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ finish_ops_.RecvInitialMetadata(context_);
+ }
+ finish_ops_.ClientRecvStatus(context_, status);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ private:
+ friend class internal::ClientAsyncWriterFactory<W>;
+ template <class R>
+ ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context,
+ R* response, bool start, void* tag)
+ : context_(context), call_(call), started_(start) {
+ finish_ops_.RecvMessage(response);
+ finish_ops_.AllowNoMessage();
+ if (start) {
+ StartCallInternal(tag);
+ } else {
+ assert(tag == nullptr);
+ }
+ }
+
+ void StartCallInternal(void* tag) {
+ write_ops_.SendInitialMetadata(context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ // if corked bit is set in context, we just keep the initial metadata
+ // buffered up to coalesce with later message send. No op is performed.
+ if (!context_->initial_metadata_corked_) {
+ write_ops_.set_output_tag(tag);
+ call_.PerformOps(&write_ops_);
+ }
+ }
+
+ ClientContext* context_;
+ ::grpc::internal::Call call_;
+ bool started_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ write_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpGenericRecvMessage,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
+};
+
+/// Async client-side interface for bi-directional streaming,
+/// where the client-to-server message stream has messages of type \a W,
+/// and the server-to-client message stream has messages of type \a R.
+template <class W, class R>
+class ClientAsyncReaderWriterInterface
+ : public internal::ClientAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W>,
+ public internal::AsyncReaderInterface<R> {
+ public:
+ /// Signal the client is done with the writes (half-close the client stream).
+ /// Thread-safe with respect to \a AsyncReaderInterface::Read
+ ///
+ /// \param[in] tag The tag identifying the operation.
+ virtual void WritesDone(void* tag) = 0;
+};
+
+namespace internal {
+template <class W, class R>
+class ClientAsyncReaderWriterFactory {
+ public:
+ /// Create a stream object.
+ /// Start the RPC request if \a start is set.
+ /// \a tag will be notified on \a cq when the call has been started (i.e.
+ /// intitial metadata sent). If \a start is not set, \a tag must be
+ /// nullptr and the actual call must be initiated by StartCall
+ /// Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ static ClientAsyncReaderWriter<W, R>* Create(
+ ChannelInterface* channel, CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context,
+ bool start, void* tag) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
+
+ return new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientAsyncReaderWriter<W, R>)))
+ ClientAsyncReaderWriter<W, R>(call, context, start, tag);
+ }
+};
+} // namespace internal
+
+/// Async client-side interface for bi-directional streaming,
+/// where the outgoing message stream going to the server
+/// has messages of type \a W, and the incoming message stream coming
+/// from the server has messages of type \a R.
+template <class W, class R>
+class ClientAsyncReaderWriter final
+ : public ClientAsyncReaderWriterInterface<W, R> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientAsyncReaderWriter));
+ }
+
+ void StartCall(void* tag) override {
+ assert(!started_);
+ started_ = true;
+ StartCallInternal(tag);
+ }
+
+ /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method
+ /// for semantics of this method.
+ ///
+ /// Side effect:
+ /// - upon receiving initial metadata from the server, the \a ClientContext
+ /// is updated with it, and then the receiving initial metadata can
+ /// be accessed through this \a ClientContext.
+ void ReadInitialMetadata(void* tag) override {
+ assert(started_);
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ meta_ops_.set_output_tag(tag);
+ meta_ops_.RecvInitialMetadata(context_);
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Read(R* msg, void* tag) override {
+ assert(started_);
+ read_ops_.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ read_ops_.RecvInitialMetadata(context_);
+ }
+ read_ops_.RecvMessage(msg);
+ call_.PerformOps(&read_ops_);
+ }
+
+ void Write(const W& msg, void* tag) override {
+ assert(started_);
+ write_ops_.set_output_tag(tag);
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void Write(const W& msg, WriteOptions options, void* tag) override {
+ assert(started_);
+ write_ops_.set_output_tag(tag);
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ write_ops_.ClientSendClose();
+ }
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void WritesDone(void* tag) override {
+ assert(started_);
+ write_ops_.set_output_tag(tag);
+ write_ops_.ClientSendClose();
+ call_.PerformOps(&write_ops_);
+ }
+
+ /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
+ /// Side effect
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible initial and trailing metadata sent from the server.
+ void Finish(Status* status, void* tag) override {
+ assert(started_);
+ finish_ops_.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ finish_ops_.RecvInitialMetadata(context_);
+ }
+ finish_ops_.ClientRecvStatus(context_, status);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ private:
+ friend class internal::ClientAsyncReaderWriterFactory<W, R>;
+ ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context,
+ bool start, void* tag)
+ : context_(context), call_(call), started_(start) {
+ if (start) {
+ StartCallInternal(tag);
+ } else {
+ assert(tag == nullptr);
+ }
+ }
+
+ void StartCallInternal(void* tag) {
+ write_ops_.SendInitialMetadata(context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ // if corked bit is set in context, we just keep the initial metadata
+ // buffered up to coalesce with later message send. No op is performed.
+ if (!context_->initial_metadata_corked_) {
+ write_ops_.set_output_tag(tag);
+ call_.PerformOps(&write_ops_);
+ }
+ }
+
+ ClientContext* context_;
+ ::grpc::internal::Call call_;
+ bool started_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ write_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
+};
+
+template <class W, class R>
+class ServerAsyncReaderInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncReaderInterface<R> {
+ public:
+ /// Indicate that the stream is to be finished with a certain status code
+ /// and also send out \a msg response to the client.
+ /// Request notification for when the server has sent the response and the
+ /// appropriate signals to the client to end the call.
+ /// Should not be used concurrently with other operations.
+ ///
+ /// It is appropriate to call this method when:
+ /// * all messages from the client have been received (either known
+ /// implictly, or explicitly because a previous
+ /// \a AsyncReaderInterface::Read operation with a non-ok result,
+ /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
+ ///
+ /// This operation will end when the server has finished sending out initial
+ /// metadata (if not sent already), response message, and status, or if
+ /// some failure occurred when trying to do so.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[in] status To be sent to the client as the result of this call.
+ /// \param[in] msg To be sent to the client as the response for this call.
+ virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
+
+ /// Indicate that the stream is to be finished with a certain
+ /// non-OK status code.
+ /// Request notification for when the server has sent the appropriate
+ /// signals to the client to end the call.
+ /// Should not be used concurrently with other operations.
+ ///
+ /// This call is meant to end the call with some error, and can be called at
+ /// any point that the server would like to "fail" the call (though note
+ /// this shouldn't be called concurrently with any other "sending" call, like
+ /// \a AsyncWriterInterface::Write).
+ ///
+ /// This operation will end when the server has finished sending out initial
+ /// metadata (if not sent already), and status, or if some failure occurred
+ /// when trying to do so.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[in] status To be sent to the client as the result of this call.
+ /// - Note: \a status must have a non-OK code.
+ virtual void FinishWithError(const Status& status, void* tag) = 0;
+};
+
+/// Async server-side API for doing client-streaming RPCs,
+/// where the incoming message stream from the client has messages of type \a R,
+/// and the single response message sent from the server is type \a W.
+template <class W, class R>
+class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
+ public:
+ explicit ServerAsyncReader(ServerContext* ctx)
+ : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+ /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - The initial metadata that will be sent to the client from this op will
+ /// be taken from the \a ServerContext associated with the call.
+ void SendInitialMetadata(void* tag) override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ meta_ops_.set_output_tag(tag);
+ meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Read(R* msg, void* tag) override {
+ read_ops_.set_output_tag(tag);
+ read_ops_.RecvMessage(msg);
+ call_.PerformOps(&read_ops_);
+ }
+
+ /// See the \a ServerAsyncReaderInterface.Read method for semantics
+ ///
+ /// Side effect:
+ /// - also sends initial metadata if not alreay sent.
+ /// - uses the \a ServerContext associated with this call to send possible
+ /// initial and trailing metadata.
+ ///
+ /// Note: \a msg is not sent if \a status has a non-OK code.
+ void Finish(const W& msg, const Status& status, void* tag) override {
+ finish_ops_.set_output_tag(tag);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ // The response is dropped if the status is not OK.
+ if (status.ok()) {
+ finish_ops_.ServerSendStatus(ctx_->trailing_metadata_,
+ finish_ops_.SendMessage(msg));
+ } else {
+ finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ }
+ call_.PerformOps(&finish_ops_);
+ }
+
+ /// See the \a ServerAsyncReaderInterface.Read method for semantics
+ ///
+ /// Side effect:
+ /// - also sends initial metadata if not alreay sent.
+ /// - uses the \a ServerContext associated with this call to send possible
+ /// initial and trailing metadata.
+ void FinishWithError(const Status& status, void* tag) override {
+ GPR_CODEGEN_ASSERT(!status.ok());
+ finish_ops_.set_output_tag(tag);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ private:
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
+
+ ::grpc::internal::Call call_;
+ ServerContext* ctx_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
+};
+
+template <class W>
+class ServerAsyncWriterInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W> {
+ public:
+ /// Indicate that the stream is to be finished with a certain status code.
+ /// Request notification for when the server has sent the appropriate
+ /// signals to the client to end the call.
+ /// Should not be used concurrently with other operations.
+ ///
+ /// It is appropriate to call this method when either:
+ /// * all messages from the client have been received (either known
+ /// implictly, or explicitly because a previous \a
+ /// AsyncReaderInterface::Read operation with a non-ok
+ /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'.
+ /// * it is desired to end the call early with some non-OK status code.
+ ///
+ /// This operation will end when the server has finished sending out initial
+ /// metadata (if not sent already), response message, and status, or if
+ /// some failure occurred when trying to do so.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[in] status To be sent to the client as the result of this call.
+ virtual void Finish(const Status& status, void* tag) = 0;
+
+ /// Request the writing of \a msg and coalesce it with trailing metadata which
+ /// contains \a status, using WriteOptions options with
+ /// identifying tag \a tag.
+ ///
+ /// WriteAndFinish is equivalent of performing WriteLast and Finish
+ /// in a single step.
+ ///
+ /// \param[in] msg The message to be written.
+ /// \param[in] options The WriteOptions to be used to write this message.
+ /// \param[in] status The Status that server returns to client.
+ /// \param[in] tag The tag identifying the operation.
+ virtual void WriteAndFinish(const W& msg, WriteOptions options,
+ const Status& status, void* tag) = 0;
+};
+
+/// Async server-side API for doing server streaming RPCs,
+/// where the outgoing message stream from the server has messages of type \a W.
+template <class W>
+class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
+ public:
+ explicit ServerAsyncWriter(ServerContext* ctx)
+ : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+ /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - The initial metadata that will be sent to the client from this op will
+ /// be taken from the \a ServerContext associated with the call.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ void SendInitialMetadata(void* tag) override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ meta_ops_.set_output_tag(tag);
+ meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Write(const W& msg, void* tag) override {
+ write_ops_.set_output_tag(tag);
+ EnsureInitialMetadataSent(&write_ops_);
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void Write(const W& msg, WriteOptions options, void* tag) override {
+ write_ops_.set_output_tag(tag);
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ }
+
+ EnsureInitialMetadataSent(&write_ops_);
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - the \a ServerContext associated with this call is used
+ /// for sending trailing (and initial) metadata to the client.
+ ///
+ /// Note: \a status must have an OK code.
+ void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
+ void* tag) override {
+ write_ops_.set_output_tag(tag);
+ EnsureInitialMetadataSent(&write_ops_);
+ options.set_buffer_hint();
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+ write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&write_ops_);
+ }
+
+ /// See the \a ServerAsyncWriterInterface.Finish method for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - the \a ServerContext associated with this call is used for sending
+ /// trailing (and initial if not already sent) metadata to the client.
+ ///
+ /// Note: there are no restrictions are the code of
+ /// \a status,it may be non-OK
+ void Finish(const Status& status, void* tag) override {
+ finish_ops_.set_output_tag(tag);
+ EnsureInitialMetadataSent(&finish_ops_);
+ finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ private:
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
+
+ template <class T>
+ void EnsureInitialMetadataSent(T* ops) {
+ if (!ctx_->sent_initial_metadata_) {
+ ops->SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ops->set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ }
+
+ ::grpc::internal::Call call_;
+ ServerContext* ctx_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
+ write_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
+};
+
+/// Server-side interface for asynchronous bi-directional streaming.
+template <class W, class R>
+class ServerAsyncReaderWriterInterface
+ : public internal::ServerAsyncStreamingInterface,
+ public internal::AsyncWriterInterface<W>,
+ public internal::AsyncReaderInterface<R> {
+ public:
+ /// Indicate that the stream is to be finished with a certain status code.
+ /// Request notification for when the server has sent the appropriate
+ /// signals to the client to end the call.
+ /// Should not be used concurrently with other operations.
+ ///
+ /// It is appropriate to call this method when either:
+ /// * all messages from the client have been received (either known
+ /// implictly, or explicitly because a previous \a
+ /// AsyncReaderInterface::Read operation
+ /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok'
+ /// with 'false'.
+ /// * it is desired to end the call early with some non-OK status code.
+ ///
+ /// This operation will end when the server has finished sending out initial
+ /// metadata (if not sent already), response message, and status, or if some
+ /// failure occurred when trying to do so.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[in] status To be sent to the client as the result of this call.
+ virtual void Finish(const Status& status, void* tag) = 0;
+
+ /// Request the writing of \a msg and coalesce it with trailing metadata which
+ /// contains \a status, using WriteOptions options with
+ /// identifying tag \a tag.
+ ///
+ /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
+ /// single step.
+ ///
+ /// \param[in] msg The message to be written.
+ /// \param[in] options The WriteOptions to be used to write this message.
+ /// \param[in] status The Status that server returns to client.
+ /// \param[in] tag The tag identifying the operation.
+ virtual void WriteAndFinish(const W& msg, WriteOptions options,
+ const Status& status, void* tag) = 0;
+};
+
+/// Async server-side API for doing bidirectional streaming RPCs,
+/// where the incoming message stream coming from the client has messages of
+/// type \a R, and the outgoing message stream coming from the server has
+/// messages of type \a W.
+template <class W, class R>
+class ServerAsyncReaderWriter final
+ : public ServerAsyncReaderWriterInterface<W, R> {
+ public:
+ explicit ServerAsyncReaderWriter(ServerContext* ctx)
+ : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+ /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - The initial metadata that will be sent to the client from this op will
+ /// be taken from the \a ServerContext associated with the call.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ void SendInitialMetadata(void* tag) override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ meta_ops_.set_output_tag(tag);
+ meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Read(R* msg, void* tag) override {
+ read_ops_.set_output_tag(tag);
+ read_ops_.RecvMessage(msg);
+ call_.PerformOps(&read_ops_);
+ }
+
+ void Write(const W& msg, void* tag) override {
+ write_ops_.set_output_tag(tag);
+ EnsureInitialMetadataSent(&write_ops_);
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void Write(const W& msg, WriteOptions options, void* tag) override {
+ write_ops_.set_output_tag(tag);
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ }
+ EnsureInitialMetadataSent(&write_ops_);
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish
+ /// method for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - the \a ServerContext associated with this call is used
+ /// for sending trailing (and initial) metadata to the client.
+ ///
+ /// Note: \a status must have an OK code.
+ void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
+ void* tag) override {
+ write_ops_.set_output_tag(tag);
+ EnsureInitialMetadataSent(&write_ops_);
+ options.set_buffer_hint();
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
+ write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&write_ops_);
+ }
+
+ /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics.
+ ///
+ /// Implicit input parameter:
+ /// - the \a ServerContext associated with this call is used for sending
+ /// trailing (and initial if not already sent) metadata to the client.
+ ///
+ /// Note: there are no restrictions are the code of \a status,
+ /// it may be non-OK
+ void Finish(const Status& status, void* tag) override {
+ finish_ops_.set_output_tag(tag);
+ EnsureInitialMetadataSent(&finish_ops_);
+
+ finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ private:
+ friend class ::grpc::Server;
+
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
+
+ template <class T>
+ void EnsureInitialMetadataSent(T* ops) {
+ if (!ctx_->sent_initial_metadata_) {
+ ops->SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ops->set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ }
+
+ ::grpc::internal::Call call_;
+ ServerContext* ctx_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
+ write_ops_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_ops_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
diff --git a/include/grpcpp/impl/codegen/async_unary_call.h b/include/grpcpp/impl/codegen/async_unary_call.h
new file mode 100644
index 0000000000..255f874e26
--- /dev/null
+++ b/include/grpcpp/impl/codegen/async_unary_call.h
@@ -0,0 +1,309 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
+#define GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
+
+#include <assert.h>
+#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+class CompletionQueue;
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+/// An interface relevant for async client side unary RPCs (which send
+/// one request message to a server and receive one response message).
+template <class R>
+class ClientAsyncResponseReaderInterface {
+ public:
+ virtual ~ClientAsyncResponseReaderInterface() {}
+
+ /// Start the call that was set up by the constructor, but only if the
+ /// constructor was invoked through the "Prepare" API which doesn't actually
+ /// start the call
+ virtual void StartCall() = 0;
+
+ /// Request notification of the reading of initial metadata. Completion
+ /// will be notified by \a tag on the associated completion queue.
+ /// This call is optional, but if it is used, it cannot be used concurrently
+ /// with or after the \a Finish method.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ virtual void ReadInitialMetadata(void* tag) = 0;
+
+ /// Request to receive the server's response \a msg and final \a status for
+ /// the call, and to notify \a tag on this call's completion queue when
+ /// finished.
+ ///
+ /// This function will return when either:
+ /// - when the server's response message and status have been received.
+ /// - when the server has returned a non-OK status (no message expected in
+ /// this case).
+ /// - when the call failed for some reason and the library generated a
+ /// non-OK status.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[out] status To be updated with the operation status.
+ /// \param[out] msg To be filled in with the server's response message.
+ virtual void Finish(R* msg, Status* status, void* tag) = 0;
+};
+
+namespace internal {
+template <class R>
+class ClientAsyncResponseReaderFactory {
+ public:
+ /// Start a call and write the request out if \a start is set.
+ /// \a tag will be notified on \a cq when the call has been started (i.e.
+ /// intitial metadata sent) and \a request has been written out.
+ /// If \a start is not set, the actual call must be initiated by StartCall
+ /// Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ template <class W>
+ static ClientAsyncResponseReader<R>* Create(
+ ChannelInterface* channel, CompletionQueue* cq,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context,
+ const W& request, bool start) {
+ ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
+ return new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientAsyncResponseReader<R>)))
+ ClientAsyncResponseReader<R>(call, context, request, start);
+ }
+};
+} // namespace internal
+
+/// Async API for client-side unary RPCs, where the message response
+/// received from the server is of type \a R.
+template <class R>
+class ClientAsyncResponseReader final
+ : public ClientAsyncResponseReaderInterface<R> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientAsyncResponseReader));
+ }
+
+ // This operator should never be called as the memory should be freed as part
+ // of the arena destruction. It only exists to provide a matching operator
+ // delete to the operator new so that some compilers will not complain (see
+ // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this
+ // there are no tests catching the compiler warning.
+ static void operator delete(void*, void*) { assert(0); }
+
+ void StartCall() override {
+ assert(!started_);
+ started_ = true;
+ StartCallInternal();
+ }
+
+ /// See \a ClientAsyncResponseReaderInterface::ReadInitialMetadata for
+ /// semantics.
+ ///
+ /// Side effect:
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible initial and trailing metadata sent from the server.
+ void ReadInitialMetadata(void* tag) override {
+ assert(started_);
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ meta_buf.set_output_tag(tag);
+ meta_buf.RecvInitialMetadata(context_);
+ call_.PerformOps(&meta_buf);
+ }
+
+ /// See \a ClientAysncResponseReaderInterface::Finish for semantics.
+ ///
+ /// Side effect:
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible initial and trailing metadata sent from the server.
+ void Finish(R* msg, Status* status, void* tag) override {
+ assert(started_);
+ finish_buf.set_output_tag(tag);
+ if (!context_->initial_metadata_received_) {
+ finish_buf.RecvInitialMetadata(context_);
+ }
+ finish_buf.RecvMessage(msg);
+ finish_buf.AllowNoMessage();
+ finish_buf.ClientRecvStatus(context_, status);
+ call_.PerformOps(&finish_buf);
+ }
+
+ private:
+ friend class internal::ClientAsyncResponseReaderFactory<R>;
+ ClientContext* const context_;
+ ::grpc::internal::Call call_;
+ bool started_;
+
+ template <class W>
+ ClientAsyncResponseReader(::grpc::internal::Call call, ClientContext* context,
+ const W& request, bool start)
+ : context_(context), call_(call), started_(start) {
+ // Bind the metadata at time of StartCallInternal but set up the rest here
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(init_buf.SendMessage(request).ok());
+ init_buf.ClientSendClose();
+ if (start) StartCallInternal();
+ }
+
+ void StartCallInternal() {
+ init_buf.SendInitialMetadata(context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ call_.PerformOps(&init_buf);
+ }
+
+ // disable operator new
+ static void* operator new(std::size_t size);
+ static void* operator new(std::size_t size, void* p) { return p; }
+
+ ::grpc::internal::SneakyCallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ init_buf;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ meta_buf;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_buf;
+};
+
+/// Async server-side API for handling unary calls, where the single
+/// response message sent to the client is of type \a W.
+template <class W>
+class ServerAsyncResponseWriter final
+ : public internal::ServerAsyncStreamingInterface {
+ public:
+ explicit ServerAsyncResponseWriter(ServerContext* ctx)
+ : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
+
+ /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
+ ///
+ /// Side effect:
+ /// The initial metadata that will be sent to the client from this op will
+ /// be taken from the \a ServerContext associated with the call.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ void SendInitialMetadata(void* tag) override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ meta_buf_.set_output_tag(tag);
+ meta_buf_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_buf_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_.PerformOps(&meta_buf_);
+ }
+
+ /// Indicate that the stream is to be finished and request notification
+ /// when the server has sent the appropriate signals to the client to
+ /// end the call. Should not be used concurrently with other operations.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[in] status To be sent to the client as the result of the call.
+ /// \param[in] msg Message to be sent to the client.
+ ///
+ /// Side effect:
+ /// - also sends initial metadata if not already sent (using the
+ /// \a ServerContext associated with this call).
+ ///
+ /// Note: if \a status has a non-OK code, then \a msg will not be sent,
+ /// and the client will receive only the status with possible trailing
+ /// metadata.
+ void Finish(const W& msg, const Status& status, void* tag) {
+ finish_buf_.set_output_tag(tag);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_buf_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ // The response is dropped if the status is not OK.
+ if (status.ok()) {
+ finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
+ finish_buf_.SendMessage(msg));
+ } else {
+ finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ }
+ call_.PerformOps(&finish_buf_);
+ }
+
+ /// Indicate that the stream is to be finished with a non-OK status,
+ /// and request notification for when the server has finished sending the
+ /// appropriate signals to the client to end the call.
+ /// Should not be used concurrently with other operations.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ /// \param[in] status To be sent to the client as the result of the call.
+ /// - Note: \a status must have a non-OK code.
+ ///
+ /// Side effect:
+ /// - also sends initial metadata if not already sent (using the
+ /// \a ServerContext associated with this call).
+ void FinishWithError(const Status& status, void* tag) {
+ GPR_CODEGEN_ASSERT(!status.ok());
+ finish_buf_.set_output_tag(tag);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_buf_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
+ call_.PerformOps(&finish_buf_);
+ }
+
+ private:
+ void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
+
+ ::grpc::internal::Call call_;
+ ServerContext* ctx_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ meta_buf_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpServerSendStatus>
+ finish_buf_;
+};
+
+} // namespace grpc
+
+namespace std {
+template <class R>
+class default_delete<grpc::ClientAsyncResponseReader<R>> {
+ public:
+ void operator()(void* p) {}
+};
+template <class R>
+class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
+ public:
+ void operator()(void* p) {}
+};
+} // namespace std
+
+#endif // GRPCPP_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h
new file mode 100644
index 0000000000..8d6a169db9
--- /dev/null
+++ b/include/grpcpp/impl/codegen/byte_buffer.h
@@ -0,0 +1,157 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H
+#define GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H
+
+#include <grpc/impl/codegen/byte_buffer.h>
+
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/status.h>
+
+#include <vector>
+
+namespace grpc {
+
+namespace internal {
+class CallOpSendMessage;
+template <class R>
+class CallOpRecvMessage;
+class CallOpGenericRecvMessage;
+class MethodHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class RpcMethodHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class ServerStreamingHandler;
+template <class R>
+class DeserializeFuncType;
+} // namespace internal
+/// A sequence of bytes.
+class ByteBuffer final {
+ public:
+ /// Constuct an empty buffer.
+ ByteBuffer() : buffer_(nullptr) {}
+
+ /// Construct buffer from \a slices, of which there are \a nslices.
+ ByteBuffer(const Slice* slices, size_t nslices);
+
+ /// Constuct a byte buffer by referencing elements of existing buffer
+ /// \a buf. Wrapper of core function grpc_byte_buffer_copy
+ ByteBuffer(const ByteBuffer& buf);
+
+ ~ByteBuffer() {
+ if (buffer_) {
+ g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_);
+ }
+ }
+
+ ByteBuffer& operator=(const ByteBuffer&);
+
+ /// Dump (read) the buffer contents into \a slices.
+ Status Dump(std::vector<Slice>* slices) const;
+
+ /// Remove all data.
+ void Clear() {
+ if (buffer_) {
+ g_core_codegen_interface->grpc_byte_buffer_destroy(buffer_);
+ buffer_ = nullptr;
+ }
+ }
+
+ /// Make a duplicate copy of the internals of this byte
+ /// buffer so that we have our own owned version of it.
+ /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable
+ void Duplicate() {
+ buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_);
+ }
+
+ /// Forget underlying byte buffer without destroying
+ /// Use this only for un-owned byte buffers
+ void Release() { buffer_ = nullptr; }
+
+ /// Buffer size in bytes.
+ size_t Length() const;
+
+ /// Swap the state of *this and *other.
+ void Swap(ByteBuffer* other);
+
+ /// Is this ByteBuffer valid?
+ bool Valid() const { return (buffer_ != nullptr); }
+
+ private:
+ friend class SerializationTraits<ByteBuffer, void>;
+ friend class internal::CallOpSendMessage;
+ template <class R>
+ friend class internal::CallOpRecvMessage;
+ friend class internal::CallOpGenericRecvMessage;
+ friend class internal::MethodHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::RpcMethodHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ServerStreamingHandler;
+ template <class R>
+ friend class internal::DeserializeFuncType;
+
+ grpc_byte_buffer* buffer_;
+
+ // takes ownership
+ void set_buffer(grpc_byte_buffer* buf) {
+ if (buffer_) {
+ Clear();
+ }
+ buffer_ = buf;
+ }
+
+ grpc_byte_buffer* c_buffer() { return buffer_; }
+ grpc_byte_buffer** c_buffer_ptr() { return &buffer_; }
+
+ class ByteBufferPointer {
+ public:
+ ByteBufferPointer(const ByteBuffer* b)
+ : bbuf_(const_cast<ByteBuffer*>(b)) {}
+ operator ByteBuffer*() { return bbuf_; }
+ operator grpc_byte_buffer*() { return bbuf_->buffer_; }
+ operator grpc_byte_buffer**() { return &bbuf_->buffer_; }
+
+ private:
+ ByteBuffer* bbuf_;
+ };
+ ByteBufferPointer bbuf_ptr() const { return ByteBufferPointer(this); }
+};
+
+template <>
+class SerializationTraits<ByteBuffer, void> {
+ public:
+ static Status Deserialize(ByteBuffer* byte_buffer, ByteBuffer* dest) {
+ dest->set_buffer(byte_buffer->buffer_);
+ return Status::OK;
+ }
+ static Status Serialize(const ByteBuffer& source, ByteBuffer* buffer,
+ bool* own_buffer) {
+ *buffer = source;
+ *own_buffer = true;
+ return Status::OK;
+ }
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_BYTE_BUFFER_H
diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h
new file mode 100644
index 0000000000..3b0fd60aae
--- /dev/null
+++ b/include/grpcpp/impl/codegen/call.h
@@ -0,0 +1,709 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CALL_H
+#define GRPCPP_IMPL_CODEGEN_CALL_H
+
+#include <assert.h>
+#include <cstring>
+#include <functional>
+#include <map>
+#include <memory>
+
+#include <grpcpp/impl/codegen/byte_buffer.h>
+#include <grpcpp/impl/codegen/call_hook.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/string_ref.h>
+
+#include <grpc/impl/codegen/atm.h>
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/impl/codegen/grpc_types.h>
+
+namespace grpc {
+
+class ByteBuffer;
+class CompletionQueue;
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+namespace internal {
+class Call;
+class CallHook;
+
+const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
+
+// TODO(yangg) if the map is changed before we send, the pointers will be a
+// mess. Make sure it does not happen.
+inline grpc_metadata* FillMetadataArray(
+ const std::multimap<grpc::string, grpc::string>& metadata,
+ size_t* metadata_count, const grpc::string& optional_error_details) {
+ *metadata_count = metadata.size() + (optional_error_details.empty() ? 0 : 1);
+ if (*metadata_count == 0) {
+ return nullptr;
+ }
+ grpc_metadata* metadata_array =
+ (grpc_metadata*)(g_core_codegen_interface->gpr_malloc(
+ (*metadata_count) * sizeof(grpc_metadata)));
+ size_t i = 0;
+ for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
+ metadata_array[i].key = SliceReferencingString(iter->first);
+ metadata_array[i].value = SliceReferencingString(iter->second);
+ }
+ if (!optional_error_details.empty()) {
+ metadata_array[i].key =
+ g_core_codegen_interface->grpc_slice_from_static_buffer(
+ kBinaryErrorDetailsKey, sizeof(kBinaryErrorDetailsKey) - 1);
+ metadata_array[i].value = SliceReferencingString(optional_error_details);
+ }
+ return metadata_array;
+}
+} // namespace internal
+
+/// Per-message write options.
+class WriteOptions {
+ public:
+ WriteOptions() : flags_(0), last_message_(false) {}
+ WriteOptions(const WriteOptions& other)
+ : flags_(other.flags_), last_message_(other.last_message_) {}
+
+ /// Clear all flags.
+ inline void Clear() { flags_ = 0; }
+
+ /// Returns raw flags bitset.
+ inline uint32_t flags() const { return flags_; }
+
+ /// Sets flag for the disabling of compression for the next message write.
+ ///
+ /// \sa GRPC_WRITE_NO_COMPRESS
+ inline WriteOptions& set_no_compression() {
+ SetBit(GRPC_WRITE_NO_COMPRESS);
+ return *this;
+ }
+
+ /// Clears flag for the disabling of compression for the next message write.
+ ///
+ /// \sa GRPC_WRITE_NO_COMPRESS
+ inline WriteOptions& clear_no_compression() {
+ ClearBit(GRPC_WRITE_NO_COMPRESS);
+ return *this;
+ }
+
+ /// Get value for the flag indicating whether compression for the next
+ /// message write is forcefully disabled.
+ ///
+ /// \sa GRPC_WRITE_NO_COMPRESS
+ inline bool get_no_compression() const {
+ return GetBit(GRPC_WRITE_NO_COMPRESS);
+ }
+
+ /// Sets flag indicating that the write may be buffered and need not go out on
+ /// the wire immediately.
+ ///
+ /// \sa GRPC_WRITE_BUFFER_HINT
+ inline WriteOptions& set_buffer_hint() {
+ SetBit(GRPC_WRITE_BUFFER_HINT);
+ return *this;
+ }
+
+ /// Clears flag indicating that the write may be buffered and need not go out
+ /// on the wire immediately.
+ ///
+ /// \sa GRPC_WRITE_BUFFER_HINT
+ inline WriteOptions& clear_buffer_hint() {
+ ClearBit(GRPC_WRITE_BUFFER_HINT);
+ return *this;
+ }
+
+ /// Get value for the flag indicating that the write may be buffered and need
+ /// not go out on the wire immediately.
+ ///
+ /// \sa GRPC_WRITE_BUFFER_HINT
+ inline bool get_buffer_hint() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
+
+ /// corked bit: aliases set_buffer_hint currently, with the intent that
+ /// set_buffer_hint will be removed in the future
+ inline WriteOptions& set_corked() {
+ SetBit(GRPC_WRITE_BUFFER_HINT);
+ return *this;
+ }
+
+ inline WriteOptions& clear_corked() {
+ ClearBit(GRPC_WRITE_BUFFER_HINT);
+ return *this;
+ }
+
+ inline bool is_corked() const { return GetBit(GRPC_WRITE_BUFFER_HINT); }
+
+ /// last-message bit: indicates this is the last message in a stream
+ /// client-side: makes Write the equivalent of performing Write, WritesDone
+ /// in a single step
+ /// server-side: hold the Write until the service handler returns (sync api)
+ /// or until Finish is called (async api)
+ inline WriteOptions& set_last_message() {
+ last_message_ = true;
+ return *this;
+ }
+
+ /// Clears flag indicating that this is the last message in a stream,
+ /// disabling coalescing.
+ inline WriteOptions& clear_last_message() {
+ last_message_ = false;
+ return *this;
+ }
+
+ /// Guarantee that all bytes have been written to the wire before completing
+ /// this write (usually writes are completed when they pass flow control)
+ inline WriteOptions& set_write_through() {
+ SetBit(GRPC_WRITE_THROUGH);
+ return *this;
+ }
+
+ inline bool is_write_through() const { return GetBit(GRPC_WRITE_THROUGH); }
+
+ /// Get value for the flag indicating that this is the last message, and
+ /// should be coalesced with trailing metadata.
+ ///
+ /// \sa GRPC_WRITE_LAST_MESSAGE
+ bool is_last_message() const { return last_message_; }
+
+ WriteOptions& operator=(const WriteOptions& rhs) {
+ flags_ = rhs.flags_;
+ return *this;
+ }
+
+ private:
+ void SetBit(const uint32_t mask) { flags_ |= mask; }
+
+ void ClearBit(const uint32_t mask) { flags_ &= ~mask; }
+
+ bool GetBit(const uint32_t mask) const { return (flags_ & mask) != 0; }
+
+ uint32_t flags_;
+ bool last_message_;
+};
+
+namespace internal {
+/// Default argument for CallOpSet. I is unused by the class, but can be
+/// used for generating multiple names for the same thing.
+template <int I>
+class CallNoOp {
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {}
+ void FinishOp(bool* status) {}
+};
+
+class CallOpSendInitialMetadata {
+ public:
+ CallOpSendInitialMetadata() : send_(false) {
+ maybe_compression_level_.is_set = false;
+ }
+
+ void SendInitialMetadata(
+ const std::multimap<grpc::string, grpc::string>& metadata,
+ uint32_t flags) {
+ maybe_compression_level_.is_set = false;
+ send_ = true;
+ flags_ = flags;
+ initial_metadata_ =
+ FillMetadataArray(metadata, &initial_metadata_count_, "");
+ }
+
+ void set_compression_level(grpc_compression_level level) {
+ maybe_compression_level_.is_set = true;
+ maybe_compression_level_.level = level;
+ }
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!send_) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->flags = flags_;
+ op->reserved = NULL;
+ op->data.send_initial_metadata.count = initial_metadata_count_;
+ op->data.send_initial_metadata.metadata = initial_metadata_;
+ op->data.send_initial_metadata.maybe_compression_level.is_set =
+ maybe_compression_level_.is_set;
+ if (maybe_compression_level_.is_set) {
+ op->data.send_initial_metadata.maybe_compression_level.level =
+ maybe_compression_level_.level;
+ }
+ }
+ void FinishOp(bool* status) {
+ if (!send_) return;
+ g_core_codegen_interface->gpr_free(initial_metadata_);
+ send_ = false;
+ }
+
+ bool send_;
+ uint32_t flags_;
+ size_t initial_metadata_count_;
+ grpc_metadata* initial_metadata_;
+ struct {
+ bool is_set;
+ grpc_compression_level level;
+ } maybe_compression_level_;
+};
+
+class CallOpSendMessage {
+ public:
+ CallOpSendMessage() : send_buf_() {}
+
+ /// Send \a message using \a options for the write. The \a options are cleared
+ /// after use.
+ template <class M>
+ Status SendMessage(const M& message,
+ WriteOptions options) GRPC_MUST_USE_RESULT;
+
+ template <class M>
+ Status SendMessage(const M& message) GRPC_MUST_USE_RESULT;
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!send_buf_.Valid()) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->flags = write_options_.flags();
+ op->reserved = NULL;
+ op->data.send_message.send_message = send_buf_.c_buffer();
+ // Flags are per-message: clear them after use.
+ write_options_.Clear();
+ }
+ void FinishOp(bool* status) { send_buf_.Clear(); }
+
+ private:
+ ByteBuffer send_buf_;
+ WriteOptions write_options_;
+};
+
+template <class M>
+Status CallOpSendMessage::SendMessage(const M& message, WriteOptions options) {
+ write_options_ = options;
+ bool own_buf;
+ // TODO(vjpai): Remove the void below when possible
+ // The void in the template parameter below should not be needed
+ // (since it should be implicit) but is needed due to an observed
+ // difference in behavior between clang and gcc for certain internal users
+ Status result = SerializationTraits<M, void>::Serialize(
+ message, send_buf_.bbuf_ptr(), &own_buf);
+ if (!own_buf) {
+ send_buf_.Duplicate();
+ }
+ return result;
+}
+
+template <class M>
+Status CallOpSendMessage::SendMessage(const M& message) {
+ return SendMessage(message, WriteOptions());
+}
+
+template <class R>
+class CallOpRecvMessage {
+ public:
+ CallOpRecvMessage()
+ : got_message(false),
+ message_(nullptr),
+ allow_not_getting_message_(false) {}
+
+ void RecvMessage(R* message) { message_ = message; }
+
+ // Do not change status if no message is received.
+ void AllowNoMessage() { allow_not_getting_message_ = true; }
+
+ bool got_message;
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (message_ == nullptr) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->flags = 0;
+ op->reserved = NULL;
+ op->data.recv_message.recv_message = recv_buf_.c_buffer_ptr();
+ }
+
+ void FinishOp(bool* status) {
+ if (message_ == nullptr) return;
+ if (recv_buf_.Valid()) {
+ if (*status) {
+ got_message = *status =
+ SerializationTraits<R>::Deserialize(recv_buf_.bbuf_ptr(), message_)
+ .ok();
+ recv_buf_.Release();
+ } else {
+ got_message = false;
+ recv_buf_.Clear();
+ }
+ } else {
+ got_message = false;
+ if (!allow_not_getting_message_) {
+ *status = false;
+ }
+ }
+ message_ = nullptr;
+ }
+
+ private:
+ R* message_;
+ ByteBuffer recv_buf_;
+ bool allow_not_getting_message_;
+};
+
+class DeserializeFunc {
+ public:
+ virtual Status Deserialize(ByteBuffer* buf) = 0;
+ virtual ~DeserializeFunc() {}
+};
+
+template <class R>
+class DeserializeFuncType final : public DeserializeFunc {
+ public:
+ DeserializeFuncType(R* message) : message_(message) {}
+ Status Deserialize(ByteBuffer* buf) override {
+ return SerializationTraits<R>::Deserialize(buf->bbuf_ptr(), message_);
+ }
+
+ ~DeserializeFuncType() override {}
+
+ private:
+ R* message_; // Not a managed pointer because management is external to this
+};
+
+class CallOpGenericRecvMessage {
+ public:
+ CallOpGenericRecvMessage()
+ : got_message(false), allow_not_getting_message_(false) {}
+
+ template <class R>
+ void RecvMessage(R* message) {
+ // Use an explicit base class pointer to avoid resolution error in the
+ // following unique_ptr::reset for some old implementations.
+ DeserializeFunc* func = new DeserializeFuncType<R>(message);
+ deserialize_.reset(func);
+ }
+
+ // Do not change status if no message is received.
+ void AllowNoMessage() { allow_not_getting_message_ = true; }
+
+ bool got_message;
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!deserialize_) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->flags = 0;
+ op->reserved = NULL;
+ op->data.recv_message.recv_message = recv_buf_.c_buffer_ptr();
+ }
+
+ void FinishOp(bool* status) {
+ if (!deserialize_) return;
+ if (recv_buf_.Valid()) {
+ if (*status) {
+ got_message = true;
+ *status = deserialize_->Deserialize(&recv_buf_).ok();
+ recv_buf_.Release();
+ } else {
+ got_message = false;
+ recv_buf_.Clear();
+ }
+ } else {
+ got_message = false;
+ if (!allow_not_getting_message_) {
+ *status = false;
+ }
+ }
+ deserialize_.reset();
+ }
+
+ private:
+ std::unique_ptr<DeserializeFunc> deserialize_;
+ ByteBuffer recv_buf_;
+ bool allow_not_getting_message_;
+};
+
+class CallOpClientSendClose {
+ public:
+ CallOpClientSendClose() : send_(false) {}
+
+ void ClientSendClose() { send_ = true; }
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!send_) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+ }
+ void FinishOp(bool* status) { send_ = false; }
+
+ private:
+ bool send_;
+};
+
+class CallOpServerSendStatus {
+ public:
+ CallOpServerSendStatus() : send_status_available_(false) {}
+
+ void ServerSendStatus(
+ const std::multimap<grpc::string, grpc::string>& trailing_metadata,
+ const Status& status) {
+ send_error_details_ = status.error_details();
+ trailing_metadata_ = FillMetadataArray(
+ trailing_metadata, &trailing_metadata_count_, send_error_details_);
+ send_status_available_ = true;
+ send_status_code_ = static_cast<grpc_status_code>(status.error_code());
+ send_error_message_ = status.error_message();
+ }
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (!send_status_available_) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count =
+ trailing_metadata_count_;
+ op->data.send_status_from_server.trailing_metadata = trailing_metadata_;
+ op->data.send_status_from_server.status = send_status_code_;
+ error_message_slice_ = SliceReferencingString(send_error_message_);
+ op->data.send_status_from_server.status_details =
+ send_error_message_.empty() ? nullptr : &error_message_slice_;
+ op->flags = 0;
+ op->reserved = NULL;
+ }
+
+ void FinishOp(bool* status) {
+ if (!send_status_available_) return;
+ g_core_codegen_interface->gpr_free(trailing_metadata_);
+ send_status_available_ = false;
+ }
+
+ private:
+ bool send_status_available_;
+ grpc_status_code send_status_code_;
+ grpc::string send_error_details_;
+ grpc::string send_error_message_;
+ size_t trailing_metadata_count_;
+ grpc_metadata* trailing_metadata_;
+ grpc_slice error_message_slice_;
+};
+
+class CallOpRecvInitialMetadata {
+ public:
+ CallOpRecvInitialMetadata() : metadata_map_(nullptr) {}
+
+ void RecvInitialMetadata(ClientContext* context) {
+ context->initial_metadata_received_ = true;
+ metadata_map_ = &context->recv_initial_metadata_;
+ }
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (metadata_map_ == nullptr) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = metadata_map_->arr();
+ op->flags = 0;
+ op->reserved = NULL;
+ }
+
+ void FinishOp(bool* status) {
+ if (metadata_map_ == nullptr) return;
+ metadata_map_->FillMap();
+ metadata_map_ = nullptr;
+ }
+
+ private:
+ MetadataMap* metadata_map_;
+};
+
+class CallOpClientRecvStatus {
+ public:
+ CallOpClientRecvStatus()
+ : recv_status_(nullptr), debug_error_string_(nullptr) {}
+
+ void ClientRecvStatus(ClientContext* context, Status* status) {
+ client_context_ = context;
+ metadata_map_ = &client_context_->trailing_metadata_;
+ recv_status_ = status;
+ error_message_ = g_core_codegen_interface->grpc_empty_slice();
+ }
+
+ protected:
+ void AddOp(grpc_op* ops, size_t* nops) {
+ if (recv_status_ == nullptr) return;
+ grpc_op* op = &ops[(*nops)++];
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr();
+ op->data.recv_status_on_client.status = &status_code_;
+ op->data.recv_status_on_client.status_details = &error_message_;
+ op->data.recv_status_on_client.error_string = &debug_error_string_;
+ op->flags = 0;
+ op->reserved = NULL;
+ }
+
+ void FinishOp(bool* status) {
+ if (recv_status_ == nullptr) return;
+ metadata_map_->FillMap();
+ grpc::string binary_error_details;
+ auto iter = metadata_map_->map()->find(kBinaryErrorDetailsKey);
+ if (iter != metadata_map_->map()->end()) {
+ binary_error_details =
+ grpc::string(iter->second.begin(), iter->second.length());
+ }
+ *recv_status_ = Status(static_cast<StatusCode>(status_code_),
+ grpc::string(GRPC_SLICE_START_PTR(error_message_),
+ GRPC_SLICE_END_PTR(error_message_)),
+ binary_error_details);
+ client_context_->set_debug_error_string(
+ debug_error_string_ != nullptr ? debug_error_string_ : "");
+ g_core_codegen_interface->grpc_slice_unref(error_message_);
+ if (debug_error_string_ != nullptr) {
+ g_core_codegen_interface->gpr_free((void*)debug_error_string_);
+ }
+ recv_status_ = nullptr;
+ }
+
+ private:
+ ClientContext* client_context_;
+ MetadataMap* metadata_map_;
+ Status* recv_status_;
+ const char* debug_error_string_;
+ grpc_status_code status_code_;
+ grpc_slice error_message_;
+};
+
+/// An abstract collection of call ops, used to generate the
+/// grpc_call_op structure to pass down to the lower layers,
+/// and as it is-a CompletionQueueTag, also massages the final
+/// completion into the correct form for consumption in the C++
+/// API.
+class CallOpSetInterface : public CompletionQueueTag {
+ public:
+ /// Fills in grpc_op, starting from ops[*nops] and moving
+ /// upwards.
+ virtual void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) = 0;
+};
+
+/// Primary implementation of CallOpSetInterface.
+/// Since we cannot use variadic templates, we declare slots up to
+/// the maximum count of ops we'll need in a set. We leverage the
+/// empty base class optimization to slim this class (especially
+/// when there are many unused slots used). To avoid duplicate base classes,
+/// the template parmeter for CallNoOp is varied by argument position.
+template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
+ class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
+ class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
+class CallOpSet : public CallOpSetInterface,
+ public Op1,
+ public Op2,
+ public Op3,
+ public Op4,
+ public Op5,
+ public Op6 {
+ public:
+ CallOpSet() : return_tag_(this), call_(nullptr) {}
+ void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override {
+ this->Op1::AddOp(ops, nops);
+ this->Op2::AddOp(ops, nops);
+ this->Op3::AddOp(ops, nops);
+ this->Op4::AddOp(ops, nops);
+ this->Op5::AddOp(ops, nops);
+ this->Op6::AddOp(ops, nops);
+ g_core_codegen_interface->grpc_call_ref(call);
+ call_ = call;
+ }
+
+ bool FinalizeResult(void** tag, bool* status) override {
+ this->Op1::FinishOp(status);
+ this->Op2::FinishOp(status);
+ this->Op3::FinishOp(status);
+ this->Op4::FinishOp(status);
+ this->Op5::FinishOp(status);
+ this->Op6::FinishOp(status);
+ *tag = return_tag_;
+
+ g_core_codegen_interface->grpc_call_unref(call_);
+ return true;
+ }
+
+ void set_output_tag(void* return_tag) { return_tag_ = return_tag; }
+
+ private:
+ void* return_tag_;
+ grpc_call* call_;
+};
+
+/// A CallOpSet that does not post completions to the completion queue.
+///
+/// Allows hiding some completions that the C core must generate from
+/// C++ users.
+template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>,
+ class Op3 = CallNoOp<3>, class Op4 = CallNoOp<4>,
+ class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>>
+class SneakyCallOpSet : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> {
+ public:
+ bool FinalizeResult(void** tag, bool* status) override {
+ typedef CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> Base;
+ return Base::FinalizeResult(tag, status) && false;
+ }
+};
+
+/// Straightforward wrapping of the C call object
+class Call final {
+ public:
+ /** call is owned by the caller */
+ Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
+ : call_hook_(call_hook),
+ cq_(cq),
+ call_(call),
+ max_receive_message_size_(-1) {}
+
+ Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
+ int max_receive_message_size)
+ : call_hook_(call_hook),
+ cq_(cq),
+ call_(call),
+ max_receive_message_size_(max_receive_message_size) {}
+
+ void PerformOps(CallOpSetInterface* ops) {
+ call_hook_->PerformOpsOnCall(ops, this);
+ }
+
+ grpc_call* call() const { return call_; }
+ CompletionQueue* cq() const { return cq_; }
+
+ int max_receive_message_size() const { return max_receive_message_size_; }
+
+ private:
+ CallHook* call_hook_;
+ CompletionQueue* cq_;
+ grpc_call* call_;
+ int max_receive_message_size_;
+};
+} // namespace internal
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CALL_H
diff --git a/include/grpcpp/impl/codegen/call_hook.h b/include/grpcpp/impl/codegen/call_hook.h
new file mode 100644
index 0000000000..4f7d370c4f
--- /dev/null
+++ b/include/grpcpp/impl/codegen/call_hook.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CALL_HOOK_H
+#define GRPCPP_IMPL_CODEGEN_CALL_HOOK_H
+
+namespace grpc {
+
+namespace internal {
+class CallOpSetInterface;
+class Call;
+
+/// This is an interface that Channel and Server implement to allow them to hook
+/// performing ops.
+class CallHook {
+ public:
+ virtual ~CallHook() {}
+ virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
+};
+} // namespace internal
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CALL_HOOK_H
diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h
new file mode 100644
index 0000000000..ec1c6c25d8
--- /dev/null
+++ b/include/grpcpp/impl/codegen/channel_interface.h
@@ -0,0 +1,121 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H
+#define GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H
+
+#include <grpc/impl/codegen/connectivity_state.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/time.h>
+
+namespace grpc {
+class ChannelInterface;
+class ClientContext;
+class CompletionQueue;
+
+template <class R>
+class ClientReader;
+template <class W>
+class ClientWriter;
+template <class W, class R>
+class ClientReaderWriter;
+
+namespace internal {
+class Call;
+class CallOpSetInterface;
+class RpcMethod;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+template <class R>
+class ClientAsyncReaderFactory;
+template <class W>
+class ClientAsyncWriterFactory;
+template <class W, class R>
+class ClientAsyncReaderWriterFactory;
+template <class R>
+class ClientAsyncResponseReaderFactory;
+} // namespace internal
+
+/// Codegen interface for \a grpc::Channel.
+class ChannelInterface {
+ public:
+ virtual ~ChannelInterface() {}
+ /// Get the current channel state. If the channel is in IDLE and
+ /// \a try_to_connect is set to true, try to connect.
+ virtual grpc_connectivity_state GetState(bool try_to_connect) = 0;
+
+ /// Return the \a tag on \a cq when the channel state is changed or \a
+ /// deadline expires. \a GetState needs to called to get the current state.
+ template <typename T>
+ void NotifyOnStateChange(grpc_connectivity_state last_observed, T deadline,
+ CompletionQueue* cq, void* tag) {
+ TimePoint<T> deadline_tp(deadline);
+ NotifyOnStateChangeImpl(last_observed, deadline_tp.raw_time(), cq, tag);
+ }
+
+ /// Blocking wait for channel state change or \a deadline expiration.
+ /// \a GetState needs to called to get the current state.
+ template <typename T>
+ bool WaitForStateChange(grpc_connectivity_state last_observed, T deadline) {
+ TimePoint<T> deadline_tp(deadline);
+ return WaitForStateChangeImpl(last_observed, deadline_tp.raw_time());
+ }
+
+ /// Wait for this channel to be connected
+ template <typename T>
+ bool WaitForConnected(T deadline) {
+ grpc_connectivity_state state;
+ while ((state = GetState(true)) != GRPC_CHANNEL_READY) {
+ if (!WaitForStateChange(state, deadline)) return false;
+ }
+ return true;
+ }
+
+ private:
+ template <class R>
+ friend class ::grpc::ClientReader;
+ template <class W>
+ friend class ::grpc::ClientWriter;
+ template <class W, class R>
+ friend class ::grpc::ClientReaderWriter;
+ template <class R>
+ friend class ::grpc::internal::ClientAsyncReaderFactory;
+ template <class W>
+ friend class ::grpc::internal::ClientAsyncWriterFactory;
+ template <class W, class R>
+ friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
+ template <class R>
+ friend class ::grpc::internal::ClientAsyncResponseReaderFactory;
+ template <class InputMessage, class OutputMessage>
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+ friend class ::grpc::internal::RpcMethod;
+ virtual internal::Call CreateCall(const internal::RpcMethod& method,
+ ClientContext* context,
+ CompletionQueue* cq) = 0;
+ virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) = 0;
+ virtual void* RegisterMethod(const char* method) = 0;
+ virtual void NotifyOnStateChangeImpl(grpc_connectivity_state last_observed,
+ gpr_timespec deadline,
+ CompletionQueue* cq, void* tag) = 0;
+ virtual bool WaitForStateChangeImpl(grpc_connectivity_state last_observed,
+ gpr_timespec deadline) = 0;
+};
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CHANNEL_INTERFACE_H
diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h
new file mode 100644
index 0000000000..9dda4c7fac
--- /dev/null
+++ b/include/grpcpp/impl/codegen/client_context.h
@@ -0,0 +1,442 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/// A ClientContext allows the person implementing a service client to:
+///
+/// - Add custom metadata key-value pairs that will propagated to the server
+/// side.
+/// - Control call settings such as compression and authentication.
+/// - Initial and trailing metadata coming from the server.
+/// - Get performance metrics (ie, census).
+///
+/// Context settings are only relevant to the call they are invoked with, that
+/// is to say, they aren't sticky. Some of these settings, such as the
+/// compression options, can be made persistent at channel construction time
+/// (see \a grpc::CreateCustomChannel).
+///
+/// \warning ClientContext instances should \em not be reused across rpcs.
+
+#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H
+#define GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H
+
+#include <map>
+#include <memory>
+#include <mutex>
+#include <string>
+
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/impl/codegen/propagation_bits.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/create_auth_context.h>
+#include <grpcpp/impl/codegen/metadata_map.h>
+#include <grpcpp/impl/codegen/security/auth_context.h>
+#include <grpcpp/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/string_ref.h>
+#include <grpcpp/impl/codegen/time.h>
+
+struct census_context;
+struct grpc_call;
+
+namespace grpc {
+
+class Channel;
+class ChannelInterface;
+class CompletionQueue;
+class CallCredentials;
+class ClientContext;
+
+namespace internal {
+class RpcMethod;
+class CallOpClientRecvStatus;
+class CallOpRecvInitialMetadata;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+} // namespace internal
+
+template <class R>
+class ClientReader;
+template <class W>
+class ClientWriter;
+template <class W, class R>
+class ClientReaderWriter;
+template <class R>
+class ClientAsyncReader;
+template <class W>
+class ClientAsyncWriter;
+template <class W, class R>
+class ClientAsyncReaderWriter;
+template <class R>
+class ClientAsyncResponseReader;
+class ServerContext;
+
+/// Options for \a ClientContext::FromServerContext specifying which traits from
+/// the \a ServerContext to propagate (copy) from it into a new \a
+/// ClientContext.
+///
+/// \see ClientContext::FromServerContext
+class PropagationOptions {
+ public:
+ PropagationOptions() : propagate_(GRPC_PROPAGATE_DEFAULTS) {}
+
+ PropagationOptions& enable_deadline_propagation() {
+ propagate_ |= GRPC_PROPAGATE_DEADLINE;
+ return *this;
+ }
+
+ PropagationOptions& disable_deadline_propagation() {
+ propagate_ &= ~GRPC_PROPAGATE_DEADLINE;
+ return *this;
+ }
+
+ PropagationOptions& enable_census_stats_propagation() {
+ propagate_ |= GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
+ return *this;
+ }
+
+ PropagationOptions& disable_census_stats_propagation() {
+ propagate_ &= ~GRPC_PROPAGATE_CENSUS_STATS_CONTEXT;
+ return *this;
+ }
+
+ PropagationOptions& enable_census_tracing_propagation() {
+ propagate_ |= GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
+ return *this;
+ }
+
+ PropagationOptions& disable_census_tracing_propagation() {
+ propagate_ &= ~GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT;
+ return *this;
+ }
+
+ PropagationOptions& enable_cancellation_propagation() {
+ propagate_ |= GRPC_PROPAGATE_CANCELLATION;
+ return *this;
+ }
+
+ PropagationOptions& disable_cancellation_propagation() {
+ propagate_ &= ~GRPC_PROPAGATE_CANCELLATION;
+ return *this;
+ }
+
+ uint32_t c_bitmask() const { return propagate_; }
+
+ private:
+ uint32_t propagate_;
+};
+
+namespace testing {
+class InteropClientContextInspector;
+} // namespace testing
+
+/// A ClientContext allows the person implementing a service client to:
+///
+/// - Add custom metadata key-value pairs that will propagated to the server
+/// side.
+/// - Control call settings such as compression and authentication.
+/// - Initial and trailing metadata coming from the server.
+/// - Get performance metrics (ie, census).
+///
+/// Context settings are only relevant to the call they are invoked with, that
+/// is to say, they aren't sticky. Some of these settings, such as the
+/// compression options, can be made persistent at channel construction time
+/// (see \a grpc::CreateCustomChannel).
+///
+/// \warning ClientContext instances should \em not be reused across rpcs.
+class ClientContext {
+ public:
+ ClientContext();
+ ~ClientContext();
+
+ /// Create a new \a ClientContext as a child of an incoming server call,
+ /// according to \a options (\see PropagationOptions).
+ ///
+ /// \param server_context The source server context to use as the basis for
+ /// constructing the client context.
+ /// \param options The options controlling what to copy from the \a
+ /// server_context.
+ ///
+ /// \return A newly constructed \a ClientContext instance based on \a
+ /// server_context, with traits propagated (copied) according to \a options.
+ static std::unique_ptr<ClientContext> FromServerContext(
+ const ServerContext& server_context,
+ PropagationOptions options = PropagationOptions());
+
+ /// Add the (\a meta_key, \a meta_value) pair to the metadata associated with
+ /// a client call. These are made available at the server side by the \a
+ /// grpc::ServerContext::client_metadata() method.
+ ///
+ /// \warning This method should only be called before invoking the rpc.
+ ///
+ /// \param meta_key The metadata key. If \a meta_value is binary data, it must
+ /// end in "-bin".
+ /// \param meta_value The metadata value. If its value is binary, the key name
+ /// must end in "-bin".
+ void AddMetadata(const grpc::string& meta_key,
+ const grpc::string& meta_value);
+
+ /// Return a collection of initial metadata key-value pairs. Note that keys
+ /// may happen more than once (ie, a \a std::multimap is returned).
+ ///
+ /// \warning This method should only be called after initial metadata has been
+ /// received. For streaming calls, see \a
+ /// ClientReaderInterface::WaitForInitialMetadata().
+ ///
+ /// \return A multimap of initial metadata key-value pairs from the server.
+ const std::multimap<grpc::string_ref, grpc::string_ref>&
+ GetServerInitialMetadata() const {
+ GPR_CODEGEN_ASSERT(initial_metadata_received_);
+ return *recv_initial_metadata_.map();
+ }
+
+ /// Return a collection of trailing metadata key-value pairs. Note that keys
+ /// may happen more than once (ie, a \a std::multimap is returned).
+ ///
+ /// \warning This method is only callable once the stream has finished.
+ ///
+ /// \return A multimap of metadata trailing key-value pairs from the server.
+ const std::multimap<grpc::string_ref, grpc::string_ref>&
+ GetServerTrailingMetadata() const {
+ // TODO(yangg) check finished
+ return *trailing_metadata_.map();
+ }
+
+ /// Set the deadline for the client call.
+ ///
+ /// \warning This method should only be called before invoking the rpc.
+ ///
+ /// \param deadline the deadline for the client call. Units are determined by
+ /// the type used.
+ template <typename T>
+ void set_deadline(const T& deadline) {
+ TimePoint<T> deadline_tp(deadline);
+ deadline_ = deadline_tp.raw_time();
+ }
+
+ /// EXPERIMENTAL: Indicate that this request is idempotent.
+ /// By default, RPCs are assumed to <i>not</i> be idempotent.
+ ///
+ /// If true, the gRPC library assumes that it's safe to initiate
+ /// this RPC multiple times.
+ void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
+
+ /// EXPERIMENTAL: Set this request to be cacheable.
+ /// If set, grpc is free to use the HTTP GET verb for sending the request,
+ /// with the possibility of receiving a cached response.
+ void set_cacheable(bool cacheable) { cacheable_ = cacheable; }
+
+ /// EXPERIMENTAL: Trigger wait-for-ready or not on this request.
+ /// See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md.
+ /// If set, if an RPC is made when a channel's connectivity state is
+ /// TRANSIENT_FAILURE or CONNECTING, the call will not "fail fast",
+ /// and the channel will wait until the channel is READY before making the
+ /// call.
+ void set_wait_for_ready(bool wait_for_ready) {
+ wait_for_ready_ = wait_for_ready;
+ wait_for_ready_explicitly_set_ = true;
+ }
+
+ /// DEPRECATED: Use set_wait_for_ready() instead.
+ void set_fail_fast(bool fail_fast) { set_wait_for_ready(!fail_fast); }
+
+ /// Return the deadline for the client call.
+ std::chrono::system_clock::time_point deadline() const {
+ return Timespec2Timepoint(deadline_);
+ }
+
+ /// Return a \a gpr_timespec representation of the client call's deadline.
+ gpr_timespec raw_deadline() const { return deadline_; }
+
+ /// Set the per call authority header (see
+ /// https://tools.ietf.org/html/rfc7540#section-8.1.2.3).
+ void set_authority(const grpc::string& authority) { authority_ = authority; }
+
+ /// Return the authentication context for this client call.
+ ///
+ /// \see grpc::AuthContext.
+ std::shared_ptr<const AuthContext> auth_context() const {
+ if (auth_context_.get() == nullptr) {
+ auth_context_ = CreateAuthContext(call_);
+ }
+ return auth_context_;
+ }
+
+ /// Set credentials for the client call.
+ ///
+ /// A credentials object encapsulates all the state needed by a client to
+ /// authenticate with a server and make various assertions, e.g., about the
+ /// client’s identity, role, or whether it is authorized to make a particular
+ /// call.
+ ///
+ /// \see https://grpc.io/docs/guides/auth.html
+ void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
+ creds_ = creds;
+ }
+
+ /// Return the compression algorithm the client call will request be used.
+ /// Note that the gRPC runtime may decide to ignore this request, for example,
+ /// due to resource constraints.
+ grpc_compression_algorithm compression_algorithm() const {
+ return compression_algorithm_;
+ }
+
+ /// Set \a algorithm to be the compression algorithm used for the client call.
+ ///
+ /// \param algorithm The compression algorithm used for the client call.
+ void set_compression_algorithm(grpc_compression_algorithm algorithm);
+
+ /// Flag whether the initial metadata should be \a corked
+ ///
+ /// If \a corked is true, then the initial metadata will be coalesced with the
+ /// write of first message in the stream. As a result, any tag set for the
+ /// initial metadata operation (starting a client-streaming or bidi-streaming
+ /// RPC) will not actually be sent to the completion queue or delivered
+ /// via Next.
+ ///
+ /// \param corked The flag indicating whether the initial metadata is to be
+ /// corked or not.
+ void set_initial_metadata_corked(bool corked) {
+ initial_metadata_corked_ = corked;
+ }
+
+ /// Return the peer uri in a string.
+ ///
+ /// \warning This value is never authenticated or subject to any security
+ /// related code. It must not be used for any authentication related
+ /// functionality. Instead, use auth_context.
+ ///
+ /// \return The call's peer URI.
+ grpc::string peer() const;
+
+ /// Get and set census context.
+ void set_census_context(struct census_context* ccp) { census_context_ = ccp; }
+ struct census_context* census_context() const {
+ return census_context_;
+ }
+
+ /// Send a best-effort out-of-band cancel on the call associated with
+ /// this client context. The call could be in any stage; e.g., if it is
+ /// already finished, it may still return success.
+ ///
+ /// There is no guarantee the call will be cancelled.
+ ///
+ /// Note that TryCancel() does not change any of the tags that are pending
+ /// on the completion queue. All pending tags will still be delivered
+ /// (though their ok result may reflect the effect of cancellation).
+ void TryCancel();
+
+ /// Global Callbacks
+ ///
+ /// Can be set exactly once per application to install hooks whenever
+ /// a client context is constructed and destructed.
+ class GlobalCallbacks {
+ public:
+ virtual ~GlobalCallbacks() {}
+ virtual void DefaultConstructor(ClientContext* context) = 0;
+ virtual void Destructor(ClientContext* context) = 0;
+ };
+ static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
+
+ /// Should be used for framework-level extensions only.
+ /// Applications never need to call this method.
+ grpc_call* c_call() { return call_; }
+
+ /// EXPERIMENTAL debugging API
+ ///
+ /// if status is not ok() for an RPC, this will return a detailed string
+ /// of the gRPC Core error that led to the failure. It should not be relied
+ /// upon for anything other than gaining more debug data in failure cases.
+ grpc::string debug_error_string() const { return debug_error_string_; }
+
+ private:
+ // Disallow copy and assign.
+ ClientContext(const ClientContext&);
+ ClientContext& operator=(const ClientContext&);
+
+ friend class ::grpc::testing::InteropClientContextInspector;
+ friend class ::grpc::internal::CallOpClientRecvStatus;
+ friend class ::grpc::internal::CallOpRecvInitialMetadata;
+ friend class Channel;
+ template <class R>
+ friend class ::grpc::ClientReader;
+ template <class W>
+ friend class ::grpc::ClientWriter;
+ template <class W, class R>
+ friend class ::grpc::ClientReaderWriter;
+ template <class R>
+ friend class ::grpc::ClientAsyncReader;
+ template <class W>
+ friend class ::grpc::ClientAsyncWriter;
+ template <class W, class R>
+ friend class ::grpc::ClientAsyncReaderWriter;
+ template <class R>
+ friend class ::grpc::ClientAsyncResponseReader;
+ template <class InputMessage, class OutputMessage>
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+
+ // Used by friend class CallOpClientRecvStatus
+ void set_debug_error_string(const grpc::string& debug_error_string) {
+ debug_error_string_ = debug_error_string;
+ }
+
+ grpc_call* call() const { return call_; }
+ void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
+
+ uint32_t initial_metadata_flags() const {
+ return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
+ (wait_for_ready_ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY : 0) |
+ (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0) |
+ (wait_for_ready_explicitly_set_
+ ? GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET
+ : 0) |
+ (initial_metadata_corked_ ? GRPC_INITIAL_METADATA_CORKED : 0);
+ }
+
+ grpc::string authority() { return authority_; }
+
+ bool initial_metadata_received_;
+ bool wait_for_ready_;
+ bool wait_for_ready_explicitly_set_;
+ bool idempotent_;
+ bool cacheable_;
+ std::shared_ptr<Channel> channel_;
+ std::mutex mu_;
+ grpc_call* call_;
+ bool call_canceled_;
+ gpr_timespec deadline_;
+ grpc::string authority_;
+ std::shared_ptr<CallCredentials> creds_;
+ mutable std::shared_ptr<const AuthContext> auth_context_;
+ struct census_context* census_context_;
+ std::multimap<grpc::string, grpc::string> send_initial_metadata_;
+ internal::MetadataMap recv_initial_metadata_;
+ internal::MetadataMap trailing_metadata_;
+
+ grpc_call* propagate_from_call_;
+ PropagationOptions propagation_options_;
+
+ grpc_compression_algorithm compression_algorithm_;
+ bool initial_metadata_corked_;
+
+ grpc::string debug_error_string_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CLIENT_CONTEXT_H
diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h
new file mode 100644
index 0000000000..a37a81b75b
--- /dev/null
+++ b/include/grpcpp/impl/codegen/client_unary_call.h
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
+#define GRPCPP_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
+
+#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+class Channel;
+class ClientContext;
+class CompletionQueue;
+
+namespace internal {
+class RpcMethod;
+/// Wrapper that performs a blocking unary call
+template <class InputMessage, class OutputMessage>
+Status BlockingUnaryCall(ChannelInterface* channel, const RpcMethod& method,
+ ClientContext* context, const InputMessage& request,
+ OutputMessage* result) {
+ return BlockingUnaryCallImpl<InputMessage, OutputMessage>(
+ channel, method, context, request, result)
+ .status();
+}
+
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl {
+ public:
+ BlockingUnaryCallImpl(ChannelInterface* channel, const RpcMethod& method,
+ ClientContext* context, const InputMessage& request,
+ OutputMessage* result) {
+ CompletionQueue cq(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}); // Pluckable completion queue
+ Call call(channel->CreateCall(method, context, &cq));
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpRecvInitialMetadata, CallOpRecvMessage<OutputMessage>,
+ CallOpClientSendClose, CallOpClientRecvStatus>
+ ops;
+ status_ = ops.SendMessage(request);
+ if (!status_.ok()) {
+ return;
+ }
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ ops.RecvInitialMetadata(context);
+ ops.RecvMessage(result);
+ ops.AllowNoMessage();
+ ops.ClientSendClose();
+ ops.ClientRecvStatus(context, &status_);
+ call.PerformOps(&ops);
+ if (cq.Pluck(&ops)) {
+ if (!ops.got_message && status_.ok()) {
+ status_ = Status(StatusCode::UNIMPLEMENTED,
+ "No message returned for unary request");
+ }
+ } else {
+ GPR_CODEGEN_ASSERT(!status_.ok());
+ }
+ }
+ Status status() { return status_; }
+
+ private:
+ Status status_;
+};
+
+} // namespace internal
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CLIENT_UNARY_CALL_H
diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h
new file mode 100644
index 0000000000..80c7c41982
--- /dev/null
+++ b/include/grpcpp/impl/codegen/completion_queue.h
@@ -0,0 +1,383 @@
+/*
+ *
+ * Copyright 2015-2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/// A completion queue implements a concurrent producer-consumer queue, with
+/// two main API-exposed methods: \a Next and \a AsyncNext. These
+/// methods are the essential component of the gRPC C++ asynchronous API.
+/// There is also a \a Shutdown method to indicate that a given completion queue
+/// will no longer have regular events. This must be called before the
+/// completion queue is destroyed.
+/// All completion queue APIs are thread-safe and may be used concurrently with
+/// any other completion queue API invocation; it is acceptable to have
+/// multiple threads calling \a Next or \a AsyncNext on the same or different
+/// completion queues, or to call these methods concurrently with a \a Shutdown
+/// elsewhere.
+/// \remark{All other API calls on completion queue should be completed before
+/// a completion queue destructor is called.}
+#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
+#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
+
+#include <grpc/impl/codegen/atm.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/time.h>
+
+struct grpc_completion_queue;
+
+namespace grpc {
+
+template <class R>
+class ClientReader;
+template <class W>
+class ClientWriter;
+template <class W, class R>
+class ClientReaderWriter;
+template <class R>
+class ServerReader;
+template <class W>
+class ServerWriter;
+namespace internal {
+template <class W, class R>
+class ServerReaderWriterBody;
+} // namespace internal
+
+class Channel;
+class ChannelInterface;
+class ClientContext;
+class CompletionQueue;
+class Server;
+class ServerBuilder;
+class ServerContext;
+class ServerInterface;
+
+namespace internal {
+class CompletionQueueTag;
+class RpcMethod;
+template <class ServiceType, class RequestType, class ResponseType>
+class RpcMethodHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class ClientStreamingHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class ServerStreamingHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class BidiStreamingHandler;
+class UnknownMethodHandler;
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler;
+template <class InputMessage, class OutputMessage>
+class BlockingUnaryCallImpl;
+} // namespace internal
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+/// A thin wrapper around \ref grpc_completion_queue (see \ref
+/// src/core/lib/surface/completion_queue.h).
+/// See \ref doc/cpp/perf_notes.md for notes on best practices for high
+/// performance servers.
+class CompletionQueue : private GrpcLibraryCodegen {
+ public:
+ /// Default constructor. Implicitly creates a \a grpc_completion_queue
+ /// instance.
+ CompletionQueue()
+ : CompletionQueue(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, GRPC_CQ_DEFAULT_POLLING}) {}
+
+ /// Wrap \a take, taking ownership of the instance.
+ ///
+ /// \param take The completion queue instance to wrap. Ownership is taken.
+ explicit CompletionQueue(grpc_completion_queue* take);
+
+ /// Destructor. Destroys the owned wrapped completion queue / instance.
+ ~CompletionQueue() {
+ g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
+ }
+
+ /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
+ enum NextStatus {
+ SHUTDOWN, ///< The completion queue has been shutdown and fully-drained
+ GOT_EVENT, ///< Got a new event; \a tag will be filled in with its
+ ///< associated value; \a ok indicating its success.
+ TIMEOUT ///< deadline was reached.
+ };
+
+ /// Read from the queue, blocking until an event is available or the queue is
+ /// shutting down.
+ ///
+ /// \param tag[out] Updated to point to the read event's tag.
+ /// \param ok[out] true if read a successful event, false otherwise.
+ ///
+ /// Note that each tag sent to the completion queue (through RPC operations
+ /// or alarms) will be delivered out of the completion queue by a call to
+ /// Next (or a related method), regardless of whether the operation succeeded
+ /// or not. Success here means that this operation completed in the normal
+ /// valid manner.
+ ///
+ /// Server-side RPC request: \a ok indicates that the RPC has indeed
+ /// been started. If it is false, the server has been Shutdown
+ /// before this particular call got matched to an incoming RPC.
+ ///
+ /// Client-side StartCall/RPC invocation: \a ok indicates that the RPC is
+ /// going to go to the wire. If it is false, it not going to the wire. This
+ /// would happen if the channel is either permanently broken or
+ /// transiently broken but with the fail-fast option. (Note that async unary
+ /// RPCs don't post a CQ tag at this point, nor do client-streaming
+ /// or bidi-streaming RPCs that have the initial metadata corked option set.)
+ ///
+ /// Client-side Write, Client-side WritesDone, Server-side Write,
+ /// Server-side Finish, Server-side SendInitialMetadata (which is
+ /// typically included in Write or Finish when not done explicitly):
+ /// \a ok means that the data/metadata/status/etc is going to go to the
+ /// wire. If it is false, it not going to the wire because the call
+ /// is already dead (i.e., canceled, deadline expired, other side
+ /// dropped the channel, etc).
+ ///
+ /// Client-side Read, Server-side Read, Client-side
+ /// RecvInitialMetadata (which is typically included in Read if not
+ /// done explicitly): \a ok indicates whether there is a valid message
+ /// that got read. If not, you know that there are certainly no more
+ /// messages that can ever be read from this stream. For the client-side
+ /// operations, this only happens because the call is dead. For the
+ /// server-sider operation, though, this could happen because the client
+ /// has done a WritesDone already.
+ ///
+ /// Client-side Finish: \a ok should always be true
+ ///
+ /// Server-side AsyncNotifyWhenDone: \a ok should always be true
+ ///
+ /// Alarm: \a ok is true if it expired, false if it was canceled
+ ///
+ /// \return true if got an event, false if the queue is fully drained and
+ /// shut down.
+ bool Next(void** tag, bool* ok) {
+ return (AsyncNextInternal(tag, ok,
+ g_core_codegen_interface->gpr_inf_future(
+ GPR_CLOCK_REALTIME)) != SHUTDOWN);
+ }
+
+ /// Read from the queue, blocking up to \a deadline (or the queue's shutdown).
+ /// Both \a tag and \a ok are updated upon success (if an event is available
+ /// within the \a deadline). A \a tag points to an arbitrary location usually
+ /// employed to uniquely identify an event.
+ ///
+ /// \param tag[out] Upon sucess, updated to point to the event's tag.
+ /// \param ok[out] Upon sucess, true if a successful event, false otherwise
+ /// See documentation for CompletionQueue::Next for explanation of ok
+ /// \param deadline[in] How long to block in wait for an event.
+ ///
+ /// \return The type of event read.
+ template <typename T>
+ NextStatus AsyncNext(void** tag, bool* ok, const T& deadline) {
+ TimePoint<T> deadline_tp(deadline);
+ return AsyncNextInternal(tag, ok, deadline_tp.raw_time());
+ }
+
+ /// EXPERIMENTAL
+ /// First executes \a F, then reads from the queue, blocking up to
+ /// \a deadline (or the queue's shutdown).
+ /// Both \a tag and \a ok are updated upon success (if an event is available
+ /// within the \a deadline). A \a tag points to an arbitrary location usually
+ /// employed to uniquely identify an event.
+ ///
+ /// \param F[in] Function to execute before calling AsyncNext on this queue.
+ /// \param tag[out] Upon sucess, updated to point to the event's tag.
+ /// \param ok[out] Upon sucess, true if read a regular event, false otherwise.
+ /// \param deadline[in] How long to block in wait for an event.
+ ///
+ /// \return The type of event read.
+ template <typename T, typename F>
+ NextStatus DoThenAsyncNext(F&& f, void** tag, bool* ok, const T& deadline) {
+ CompletionQueueTLSCache cache = CompletionQueueTLSCache(this);
+ f();
+ if (cache.Flush(tag, ok)) {
+ return GOT_EVENT;
+ } else {
+ return AsyncNext(tag, ok, deadline);
+ }
+ }
+
+ /// Request the shutdown of the queue.
+ ///
+ /// \warning This method must be called at some point if this completion queue
+ /// is accessed with Next or AsyncNext. \a Next will not return false
+ /// until this method has been called and all pending tags have been drained.
+ /// (Likewise for \a AsyncNext returning \a NextStatus::SHUTDOWN .)
+ /// Only once either one of these methods does that (that is, once the queue
+ /// has been \em drained) can an instance of this class be destroyed.
+ /// Also note that applications must ensure that no work is enqueued on this
+ /// completion queue after this method is called.
+ void Shutdown();
+
+ /// Returns a \em raw pointer to the underlying \a grpc_completion_queue
+ /// instance.
+ ///
+ /// \warning Remember that the returned instance is owned. No transfer of
+ /// owership is performed.
+ grpc_completion_queue* cq() { return cq_; }
+
+ protected:
+ /// Private constructor of CompletionQueue only visible to friend classes
+ CompletionQueue(const grpc_completion_queue_attributes& attributes) {
+ cq_ = g_core_codegen_interface->grpc_completion_queue_create(
+ g_core_codegen_interface->grpc_completion_queue_factory_lookup(
+ &attributes),
+ &attributes, NULL);
+ InitialAvalanching(); // reserve this for the future shutdown
+ }
+
+ private:
+ // Friend synchronous wrappers so that they can access Pluck(), which is
+ // a semi-private API geared towards the synchronous implementation.
+ template <class R>
+ friend class ::grpc::ClientReader;
+ template <class W>
+ friend class ::grpc::ClientWriter;
+ template <class W, class R>
+ friend class ::grpc::ClientReaderWriter;
+ template <class R>
+ friend class ::grpc::ServerReader;
+ template <class W>
+ friend class ::grpc::ServerWriter;
+ template <class W, class R>
+ friend class ::grpc::internal::ServerReaderWriterBody;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class ::grpc::internal::RpcMethodHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class ::grpc::internal::ClientStreamingHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class ::grpc::internal::ServerStreamingHandler;
+ template <class Streamer, bool WriteNeeded>
+ friend class ::grpc::internal::TemplatedBidiStreamingHandler;
+ friend class ::grpc::internal::UnknownMethodHandler;
+ friend class ::grpc::Server;
+ friend class ::grpc::ServerContext;
+ friend class ::grpc::ServerInterface;
+ template <class InputMessage, class OutputMessage>
+ friend class ::grpc::internal::BlockingUnaryCallImpl;
+
+ /// EXPERIMENTAL
+ /// Creates a Thread Local cache to store the first event
+ /// On this completion queue queued from this thread. Once
+ /// initialized, it must be flushed on the same thread.
+ class CompletionQueueTLSCache {
+ public:
+ CompletionQueueTLSCache(CompletionQueue* cq);
+ ~CompletionQueueTLSCache();
+ bool Flush(void** tag, bool* ok);
+
+ private:
+ CompletionQueue* cq_;
+ bool flushed_;
+ };
+
+ NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline);
+
+ /// Wraps \a grpc_completion_queue_pluck.
+ /// \warning Must not be mixed with calls to \a Next.
+ bool Pluck(internal::CompletionQueueTag* tag) {
+ auto deadline =
+ g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
+ auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
+ cq_, tag, deadline, nullptr);
+ bool ok = ev.success != 0;
+ void* ignored = tag;
+ GPR_CODEGEN_ASSERT(tag->FinalizeResult(&ignored, &ok));
+ GPR_CODEGEN_ASSERT(ignored == tag);
+ // Ignore mutations by FinalizeResult: Pluck returns the C API status
+ return ev.success != 0;
+ }
+
+ /// Performs a single polling pluck on \a tag.
+ /// \warning Must not be mixed with calls to \a Next.
+ ///
+ /// TODO: sreek - This calls tag->FinalizeResult() even if the cq_ is already
+ /// shutdown. This is most likely a bug and if it is a bug, then change this
+ /// implementation to simple call the other TryPluck function with a zero
+ /// timeout. i.e:
+ /// TryPluck(tag, gpr_time_0(GPR_CLOCK_REALTIME))
+ void TryPluck(internal::CompletionQueueTag* tag) {
+ auto deadline = g_core_codegen_interface->gpr_time_0(GPR_CLOCK_REALTIME);
+ auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
+ cq_, tag, deadline, nullptr);
+ if (ev.type == GRPC_QUEUE_TIMEOUT) return;
+ bool ok = ev.success != 0;
+ void* ignored = tag;
+ // the tag must be swallowed if using TryPluck
+ GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
+ }
+
+ /// Performs a single polling pluck on \a tag. Calls tag->FinalizeResult if
+ /// the pluck() was successful and returned the tag.
+ ///
+ /// This exects tag->FinalizeResult (if called) to return 'false' i.e expects
+ /// that the tag is internal not something that is returned to the user.
+ void TryPluck(internal::CompletionQueueTag* tag, gpr_timespec deadline) {
+ auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
+ cq_, tag, deadline, nullptr);
+ if (ev.type == GRPC_QUEUE_TIMEOUT || ev.type == GRPC_QUEUE_SHUTDOWN) {
+ return;
+ }
+
+ bool ok = ev.success != 0;
+ void* ignored = tag;
+ GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
+ }
+
+ /// Manage state of avalanching operations : completion queue tags that
+ /// trigger other completion queue operations. The underlying core completion
+ /// queue should not really shutdown until all avalanching operations have
+ /// been finalized. Note that we maintain the requirement that an avalanche
+ /// registration must take place before CQ shutdown (which must be maintained
+ /// elsehwere)
+ void InitialAvalanching() {
+ gpr_atm_rel_store(&avalanches_in_flight_, static_cast<gpr_atm>(1));
+ }
+ void RegisterAvalanching() {
+ gpr_atm_no_barrier_fetch_add(&avalanches_in_flight_,
+ static_cast<gpr_atm>(1));
+ }
+ void CompleteAvalanching();
+
+ grpc_completion_queue* cq_; // owned
+
+ gpr_atm avalanches_in_flight_;
+};
+
+/// A specific type of completion queue used by the processing of notifications
+/// by servers. Instantiated by \a ServerBuilder.
+class ServerCompletionQueue : public CompletionQueue {
+ public:
+ bool IsFrequentlyPolled() { return polling_type_ != GRPC_CQ_NON_LISTENING; }
+
+ private:
+ grpc_cq_polling_type polling_type_;
+ friend class ServerBuilder;
+ /// \param is_frequently_polled Informs the GRPC library about whether the
+ /// server completion queue would be actively polled (by calling Next() or
+ /// AsyncNext()). By default all server completion queues are assumed to be
+ /// frequently polled.
+ ServerCompletionQueue(grpc_cq_polling_type polling_type)
+ : CompletionQueue(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_NEXT, polling_type}),
+ polling_type_(polling_type) {}
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_H
diff --git a/include/grpcpp/impl/codegen/completion_queue_tag.h b/include/grpcpp/impl/codegen/completion_queue_tag.h
new file mode 100644
index 0000000000..ffb642c56b
--- /dev/null
+++ b/include/grpcpp/impl/codegen/completion_queue_tag.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
+#define GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
+
+namespace grpc {
+
+namespace internal {
+/// An interface allowing implementors to process and filter event tags.
+class CompletionQueueTag {
+ public:
+ virtual ~CompletionQueueTag() {}
+ /// Called prior to returning from Next(), return value is the status of the
+ /// operation (return status is the default thing to do). If this function
+ /// returns false, the tag is dropped and not returned from the completion
+ /// queue
+ virtual bool FinalizeResult(void** tag, bool* status) = 0;
+};
+} // namespace internal
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
diff --git a/include/grpcpp/impl/codegen/config.h b/include/grpcpp/impl/codegen/config.h
new file mode 100644
index 0000000000..37f0fd1faf
--- /dev/null
+++ b/include/grpcpp/impl/codegen/config.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CONFIG_H
+#define GRPCPP_IMPL_CODEGEN_CONFIG_H
+
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
+/// The following macros are deprecated and appear only for users
+/// with PB files generated using gRPC 1.0.x plugins. They should
+/// not be used in new code
+#define GRPC_OVERRIDE override // deprecated
+#define GRPC_FINAL final // deprecated
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+using std::to_string;
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CONFIG_H
diff --git a/include/grpcpp/impl/codegen/config_protobuf.h b/include/grpcpp/impl/codegen/config_protobuf.h
new file mode 100644
index 0000000000..94e593d1ef
--- /dev/null
+++ b/include/grpcpp/impl/codegen/config_protobuf.h
@@ -0,0 +1,95 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CONFIG_PROTOBUF_H
+#define GRPCPP_IMPL_CODEGEN_CONFIG_PROTOBUF_H
+
+#define GRPC_OPEN_SOURCE_PROTO
+
+#ifndef GRPC_CUSTOM_PROTOBUF_INT64
+#include <google/protobuf/stubs/common.h>
+#define GRPC_CUSTOM_PROTOBUF_INT64 ::google::protobuf::int64
+#endif
+
+#ifndef GRPC_CUSTOM_MESSAGE
+#ifdef GRPC_USE_PROTO_LITE
+#include <google/protobuf/message_lite.h>
+#define GRPC_CUSTOM_MESSAGE ::google::protobuf::MessageLite
+#else
+#include <google/protobuf/message.h>
+#define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message
+#endif
+#endif
+
+#ifndef GRPC_CUSTOM_DESCRIPTOR
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor
+#define GRPC_CUSTOM_DESCRIPTORPOOL ::google::protobuf::DescriptorPool
+#define GRPC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor
+#define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor
+#define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto
+#define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor
+#define GRPC_CUSTOM_SERVICEDESCRIPTOR ::google::protobuf::ServiceDescriptor
+#define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation
+#endif
+
+#ifndef GRPC_CUSTOM_DESCRIPTORDATABASE
+#include <google/protobuf/descriptor_database.h>
+#define GRPC_CUSTOM_DESCRIPTORDATABASE ::google::protobuf::DescriptorDatabase
+#define GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE \
+ ::google::protobuf::SimpleDescriptorDatabase
+#endif
+
+#ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#define GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM \
+ ::google::protobuf::io::ZeroCopyOutputStream
+#define GRPC_CUSTOM_ZEROCOPYINPUTSTREAM \
+ ::google::protobuf::io::ZeroCopyInputStream
+#define GRPC_CUSTOM_CODEDINPUTSTREAM ::google::protobuf::io::CodedInputStream
+#endif
+
+namespace grpc {
+namespace protobuf {
+
+typedef GRPC_CUSTOM_MESSAGE Message;
+typedef GRPC_CUSTOM_PROTOBUF_INT64 int64;
+
+typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;
+typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool;
+typedef GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase;
+typedef GRPC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor;
+typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;
+typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto;
+typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor;
+typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor;
+typedef GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase;
+typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation;
+
+namespace io {
+typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream;
+typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream;
+typedef GRPC_CUSTOM_CODEDINPUTSTREAM CodedInputStream;
+} // namespace io
+
+} // namespace protobuf
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CONFIG_PROTOBUF_H
diff --git a/include/grpcpp/impl/codegen/core_codegen.h b/include/grpcpp/impl/codegen/core_codegen.h
new file mode 100644
index 0000000000..0ca4ad524c
--- /dev/null
+++ b/include/grpcpp/impl/codegen/core_codegen.h
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_H
+#define GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_H
+
+// This file should be compiled as part of grpcpp.
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+
+namespace grpc {
+
+/// Implementation of the core codegen interface.
+class CoreCodegen final : public CoreCodegenInterface {
+ private:
+ virtual const grpc_completion_queue_factory*
+ grpc_completion_queue_factory_lookup(
+ const grpc_completion_queue_attributes* attributes) override;
+ virtual grpc_completion_queue* grpc_completion_queue_create(
+ const grpc_completion_queue_factory* factory,
+ const grpc_completion_queue_attributes* attributes,
+ void* reserved) override;
+ grpc_completion_queue* grpc_completion_queue_create_for_next(
+ void* reserved) override;
+ grpc_completion_queue* grpc_completion_queue_create_for_pluck(
+ void* reserved) override;
+ void grpc_completion_queue_destroy(grpc_completion_queue* cq) override;
+ grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag,
+ gpr_timespec deadline,
+ void* reserved) override;
+
+ void* gpr_malloc(size_t size) override;
+ void gpr_free(void* p) override;
+
+ void grpc_init() override;
+ void grpc_shutdown() override;
+
+ void gpr_mu_init(gpr_mu* mu) override;
+ void gpr_mu_destroy(gpr_mu* mu) override;
+ void gpr_mu_lock(gpr_mu* mu) override;
+ void gpr_mu_unlock(gpr_mu* mu) override;
+ void gpr_cv_init(gpr_cv* cv) override;
+ void gpr_cv_destroy(gpr_cv* cv) override;
+ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) override;
+ void gpr_cv_signal(gpr_cv* cv) override;
+ void gpr_cv_broadcast(gpr_cv* cv) override;
+
+ grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
+ grpc_status_code status,
+ const char* description,
+ void* reserved) override;
+ void grpc_call_ref(grpc_call* call) override;
+ void grpc_call_unref(grpc_call* call) override;
+ virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) override;
+
+ grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb) override;
+ void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
+
+ int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
+ grpc_byte_buffer* buffer) override;
+ void grpc_byte_buffer_reader_destroy(
+ grpc_byte_buffer_reader* reader) override;
+ int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
+ grpc_slice* slice) override;
+
+ grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
+ size_t nslices) override;
+ grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
+ void (*destroy)(void*),
+ void* user_data) override;
+ grpc_slice grpc_empty_slice() override;
+ grpc_slice grpc_slice_malloc(size_t length) override;
+ void grpc_slice_unref(grpc_slice slice) override;
+ grpc_slice grpc_slice_ref(grpc_slice slice) override;
+ grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) override;
+ grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split) override;
+ grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end) override;
+ void grpc_slice_buffer_add(grpc_slice_buffer* sb, grpc_slice slice) override;
+ void grpc_slice_buffer_pop(grpc_slice_buffer* sb) override;
+ grpc_slice grpc_slice_from_static_buffer(const void* buffer,
+ size_t length) override;
+ grpc_slice grpc_slice_from_copied_buffer(const void* buffer,
+ size_t length) override;
+ void grpc_metadata_array_init(grpc_metadata_array* array) override;
+ void grpc_metadata_array_destroy(grpc_metadata_array* array) override;
+
+ gpr_timespec gpr_inf_future(gpr_clock_type type) override;
+ gpr_timespec gpr_time_0(gpr_clock_type type) override;
+
+ virtual const Status& ok() override;
+ virtual const Status& cancelled() override;
+
+ void assert_fail(const char* failed_assertion, const char* file,
+ int line) override;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_H
diff --git a/include/grpcpp/impl/codegen/core_codegen_interface.h b/include/grpcpp/impl/codegen/core_codegen_interface.h
new file mode 100644
index 0000000000..d72f579c8e
--- /dev/null
+++ b/include/grpcpp/impl/codegen/core_codegen_interface.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
+#define GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
+
+#include <grpc/impl/codegen/byte_buffer_reader.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/impl/codegen/sync.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+/// Interface between the codegen library and the minimal subset of core
+/// features required by the generated code.
+///
+/// All undocumented methods are simply forwarding the call to their namesakes.
+/// Please refer to their corresponding documentation for details.
+///
+/// \warning This interface should be considered internal and private.
+class CoreCodegenInterface {
+ public:
+ virtual ~CoreCodegenInterface() = default;
+
+ /// Upon a failed assertion, log the error.
+ virtual void assert_fail(const char* failed_assertion, const char* file,
+ int line) = 0;
+
+ virtual const grpc_completion_queue_factory*
+ grpc_completion_queue_factory_lookup(
+ const grpc_completion_queue_attributes* attributes) = 0;
+ virtual grpc_completion_queue* grpc_completion_queue_create(
+ const grpc_completion_queue_factory* factory,
+ const grpc_completion_queue_attributes* attributes, void* reserved) = 0;
+ virtual grpc_completion_queue* grpc_completion_queue_create_for_next(
+ void* reserved) = 0;
+ virtual grpc_completion_queue* grpc_completion_queue_create_for_pluck(
+ void* reserved) = 0;
+ virtual void grpc_completion_queue_destroy(grpc_completion_queue* cq) = 0;
+ virtual grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq,
+ void* tag,
+ gpr_timespec deadline,
+ void* reserved) = 0;
+
+ virtual void* gpr_malloc(size_t size) = 0;
+ virtual void gpr_free(void* p) = 0;
+
+ // These are only to be used to fix edge cases involving grpc_init and
+ // grpc_shutdown. Calling grpc_init from the codegen interface before
+ // the real grpc_init is called will cause a crash, so if you use this
+ // function, ensure that it is not the first call to grpc_init.
+ virtual void grpc_init() = 0;
+ virtual void grpc_shutdown() = 0;
+
+ virtual void gpr_mu_init(gpr_mu* mu) = 0;
+ virtual void gpr_mu_destroy(gpr_mu* mu) = 0;
+ virtual void gpr_mu_lock(gpr_mu* mu) = 0;
+ virtual void gpr_mu_unlock(gpr_mu* mu) = 0;
+ virtual void gpr_cv_init(gpr_cv* cv) = 0;
+ virtual void gpr_cv_destroy(gpr_cv* cv) = 0;
+ virtual int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu,
+ gpr_timespec abs_deadline) = 0;
+ virtual void gpr_cv_signal(gpr_cv* cv) = 0;
+ virtual void gpr_cv_broadcast(gpr_cv* cv) = 0;
+
+ virtual grpc_byte_buffer* grpc_byte_buffer_copy(grpc_byte_buffer* bb) = 0;
+ virtual void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) = 0;
+
+ virtual int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
+ grpc_byte_buffer* buffer)
+ GRPC_MUST_USE_RESULT = 0;
+ virtual void grpc_byte_buffer_reader_destroy(
+ grpc_byte_buffer_reader* reader) = 0;
+ virtual int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader* reader,
+ grpc_slice* slice) = 0;
+
+ virtual grpc_byte_buffer* grpc_raw_byte_buffer_create(grpc_slice* slice,
+ size_t nslices) = 0;
+ virtual grpc_slice grpc_slice_new_with_user_data(void* p, size_t len,
+ void (*destroy)(void*),
+ void* user_data) = 0;
+ virtual grpc_call_error grpc_call_cancel_with_status(grpc_call* call,
+ grpc_status_code status,
+ const char* description,
+ void* reserved) = 0;
+ virtual void grpc_call_ref(grpc_call* call) = 0;
+ virtual void grpc_call_unref(grpc_call* call) = 0;
+ virtual void* grpc_call_arena_alloc(grpc_call* call, size_t length) = 0;
+ virtual grpc_slice grpc_empty_slice() = 0;
+ virtual grpc_slice grpc_slice_malloc(size_t length) = 0;
+ virtual void grpc_slice_unref(grpc_slice slice) = 0;
+ virtual grpc_slice grpc_slice_ref(grpc_slice slice) = 0;
+ virtual grpc_slice grpc_slice_split_tail(grpc_slice* s, size_t split) = 0;
+ virtual grpc_slice grpc_slice_split_head(grpc_slice* s, size_t split) = 0;
+ virtual grpc_slice grpc_slice_sub(grpc_slice s, size_t begin, size_t end) = 0;
+ virtual void grpc_slice_buffer_add(grpc_slice_buffer* sb,
+ grpc_slice slice) = 0;
+ virtual void grpc_slice_buffer_pop(grpc_slice_buffer* sb) = 0;
+ virtual grpc_slice grpc_slice_from_static_buffer(const void* buffer,
+ size_t length) = 0;
+ virtual grpc_slice grpc_slice_from_copied_buffer(const void* buffer,
+ size_t length) = 0;
+
+ virtual void grpc_metadata_array_init(grpc_metadata_array* array) = 0;
+ virtual void grpc_metadata_array_destroy(grpc_metadata_array* array) = 0;
+
+ virtual const Status& ok() = 0;
+ virtual const Status& cancelled() = 0;
+
+ virtual gpr_timespec gpr_inf_future(gpr_clock_type type) = 0;
+ virtual gpr_timespec gpr_time_0(gpr_clock_type type) = 0;
+};
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+/// Codegen specific version of \a GPR_ASSERT.
+#define GPR_CODEGEN_ASSERT(x) \
+ do { \
+ if (!(x)) { \
+ grpc::g_core_codegen_interface->assert_fail(#x, __FILE__, __LINE__); \
+ } \
+ } while (0)
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
diff --git a/include/grpcpp/impl/codegen/create_auth_context.h b/include/grpcpp/impl/codegen/create_auth_context.h
new file mode 100644
index 0000000000..cb6095c3a5
--- /dev/null
+++ b/include/grpcpp/impl/codegen/create_auth_context.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_CREATE_AUTH_CONTEXT_H
+#define GRPCPP_IMPL_CODEGEN_CREATE_AUTH_CONTEXT_H
+
+#include <memory>
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpcpp/impl/codegen/security/auth_context.h>
+
+namespace grpc {
+
+std::shared_ptr<const AuthContext> CreateAuthContext(grpc_call* call);
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_CREATE_AUTH_CONTEXT_H
diff --git a/include/grpcpp/impl/codegen/grpc_library.h b/include/grpcpp/impl/codegen/grpc_library.h
new file mode 100644
index 0000000000..17c904d71a
--- /dev/null
+++ b/include/grpcpp/impl/codegen/grpc_library.h
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_GRPC_LIBRARY_H
+#define GRPCPP_IMPL_CODEGEN_GRPC_LIBRARY_H
+
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+
+namespace grpc {
+
+class GrpcLibraryInterface {
+ public:
+ virtual ~GrpcLibraryInterface() = default;
+ virtual void init() = 0;
+ virtual void shutdown() = 0;
+};
+
+/// Initialized by \a grpc::GrpcLibraryInitializer from
+/// <grpcpp/impl/grpc_library.h>
+extern GrpcLibraryInterface* g_glip;
+
+/// Classes that require gRPC to be initialized should inherit from this class.
+class GrpcLibraryCodegen {
+ public:
+ GrpcLibraryCodegen(bool call_grpc_init = true) : grpc_init_called_(false) {
+ if (call_grpc_init) {
+ GPR_CODEGEN_ASSERT(g_glip &&
+ "gRPC library not initialized. See "
+ "grpc::internal::GrpcLibraryInitializer.");
+ g_glip->init();
+ grpc_init_called_ = true;
+ }
+ }
+ virtual ~GrpcLibraryCodegen() {
+ if (grpc_init_called_) {
+ GPR_CODEGEN_ASSERT(g_glip &&
+ "gRPC library not initialized. See "
+ "grpc::internal::GrpcLibraryInitializer.");
+ g_glip->shutdown();
+ }
+ }
+
+ private:
+ bool grpc_init_called_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_GRPC_LIBRARY_H
diff --git a/include/grpcpp/impl/codegen/metadata_map.h b/include/grpcpp/impl/codegen/metadata_map.h
new file mode 100644
index 0000000000..0866539d88
--- /dev/null
+++ b/include/grpcpp/impl/codegen/metadata_map.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
+#define GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
+
+#include <grpcpp/impl/codegen/slice.h>
+
+namespace grpc {
+
+namespace internal {
+class MetadataMap {
+ public:
+ MetadataMap() { memset(&arr_, 0, sizeof(arr_)); }
+
+ ~MetadataMap() {
+ g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
+ }
+
+ void FillMap() {
+ for (size_t i = 0; i < arr_.count; i++) {
+ // TODO(yangg) handle duplicates?
+ map_.insert(std::pair<grpc::string_ref, grpc::string_ref>(
+ StringRefFromSlice(&arr_.metadata[i].key),
+ StringRefFromSlice(&arr_.metadata[i].value)));
+ }
+ }
+
+ std::multimap<grpc::string_ref, grpc::string_ref>* map() { return &map_; }
+ const std::multimap<grpc::string_ref, grpc::string_ref>* map() const {
+ return &map_;
+ }
+ grpc_metadata_array* arr() { return &arr_; }
+
+ private:
+ grpc_metadata_array arr_;
+ std::multimap<grpc::string_ref, grpc::string_ref> map_;
+};
+} // namespace internal
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_METADATA_MAP_H
diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h
new file mode 100644
index 0000000000..27552d79df
--- /dev/null
+++ b/include/grpcpp/impl/codegen/method_handler_impl.h
@@ -0,0 +1,302 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
+#define GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
+
+#include <grpcpp/impl/codegen/byte_buffer.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+namespace grpc {
+
+namespace internal {
+
+// Invoke the method handler, fill in the status, and
+// return whether or not we finished safely (without an exception).
+// Note that exception handling is 0-cost in most compiler/library
+// implementations (except when an exception is actually thrown),
+// so this process doesn't require additional overhead in the common case.
+// Additionally, we don't need to return if we caught an exception or not;
+// the handling is the same in either case.
+template <class Callable>
+Status CatchingFunctionHandler(Callable&& handler) {
+#if GRPC_ALLOW_EXCEPTIONS
+ try {
+ return handler();
+ } catch (...) {
+ return Status(StatusCode::UNKNOWN, "Unexpected error in RPC handling");
+ }
+#else // GRPC_ALLOW_EXCEPTIONS
+ return handler();
+#endif // GRPC_ALLOW_EXCEPTIONS
+}
+
+/// A wrapper class of an application provided rpc method handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class RpcMethodHandler : public MethodHandler {
+ public:
+ RpcMethodHandler(std::function<Status(ServiceType*, ServerContext*,
+ const RequestType*, ResponseType*)>
+ func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) final {
+ RequestType req;
+ Status status = SerializationTraits<RequestType>::Deserialize(
+ param.request.bbuf_ptr(), &req);
+ ResponseType rsp;
+ if (status.ok()) {
+ status = CatchingFunctionHandler([this, &param, &req, &rsp] {
+ return func_(service_, param.server_context, &req, &rsp);
+ });
+ }
+
+ GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus>
+ ops;
+ ops.SendInitialMetadata(param.server_context->initial_metadata_,
+ param.server_context->initial_metadata_flags());
+ if (param.server_context->compression_level_set()) {
+ ops.set_compression_level(param.server_context->compression_level());
+ }
+ if (status.ok()) {
+ status = ops.SendMessage(rsp);
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ /// Application provided rpc handler function.
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ResponseType*)>
+ func_;
+ // The class the above handler function lives in.
+ ServiceType* service_;
+};
+
+/// A wrapper class of an application provided client streaming handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class ClientStreamingHandler : public MethodHandler {
+ public:
+ ClientStreamingHandler(
+ std::function<Status(ServiceType*, ServerContext*,
+ ServerReader<RequestType>*, ResponseType*)>
+ func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) final {
+ ServerReader<RequestType> reader(param.call, param.server_context);
+ ResponseType rsp;
+ Status status = CatchingFunctionHandler([this, &param, &reader, &rsp] {
+ return func_(service_, param.server_context, &reader, &rsp);
+ });
+
+ GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus>
+ ops;
+ ops.SendInitialMetadata(param.server_context->initial_metadata_,
+ param.server_context->initial_metadata_flags());
+ if (param.server_context->compression_level_set()) {
+ ops.set_compression_level(param.server_context->compression_level());
+ }
+ if (status.ok()) {
+ status = ops.SendMessage(rsp);
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
+ ResponseType*)>
+ func_;
+ ServiceType* service_;
+};
+
+/// A wrapper class of an application provided server streaming handler.
+template <class ServiceType, class RequestType, class ResponseType>
+class ServerStreamingHandler : public MethodHandler {
+ public:
+ ServerStreamingHandler(
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ServerWriter<ResponseType>*)>
+ func,
+ ServiceType* service)
+ : func_(func), service_(service) {}
+
+ void RunHandler(const HandlerParameter& param) final {
+ RequestType req;
+ Status status = SerializationTraits<RequestType>::Deserialize(
+ param.request.bbuf_ptr(), &req);
+
+ if (status.ok()) {
+ ServerWriter<ResponseType> writer(param.call, param.server_context);
+ status = CatchingFunctionHandler([this, &param, &req, &writer] {
+ return func_(service_, param.server_context, &req, &writer);
+ });
+ }
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
+ if (!param.server_context->sent_initial_metadata_) {
+ ops.SendInitialMetadata(param.server_context->initial_metadata_,
+ param.server_context->initial_metadata_flags());
+ if (param.server_context->compression_level_set()) {
+ ops.set_compression_level(param.server_context->compression_level());
+ }
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ if (param.server_context->has_pending_ops_) {
+ param.call->cq()->Pluck(&param.server_context->pending_ops_);
+ }
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ std::function<Status(ServiceType*, ServerContext*, const RequestType*,
+ ServerWriter<ResponseType>*)>
+ func_;
+ ServiceType* service_;
+};
+
+/// A wrapper class of an application provided bidi-streaming handler.
+/// This also applies to server-streamed implementation of a unary method
+/// with the additional requirement that such methods must have done a
+/// write for status to be ok
+/// Since this is used by more than 1 class, the service is not passed in.
+/// Instead, it is expected to be an implicitly-captured argument of func
+/// (through bind or something along those lines)
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler : public MethodHandler {
+ public:
+ TemplatedBidiStreamingHandler(
+ std::function<Status(ServerContext*, Streamer*)> func)
+ : func_(func), write_needed_(WriteNeeded) {}
+
+ void RunHandler(const HandlerParameter& param) final {
+ Streamer stream(param.call, param.server_context);
+ Status status = CatchingFunctionHandler([this, &param, &stream] {
+ return func_(param.server_context, &stream);
+ });
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
+ if (!param.server_context->sent_initial_metadata_) {
+ ops.SendInitialMetadata(param.server_context->initial_metadata_,
+ param.server_context->initial_metadata_flags());
+ if (param.server_context->compression_level_set()) {
+ ops.set_compression_level(param.server_context->compression_level());
+ }
+ if (write_needed_ && status.ok()) {
+ // If we needed a write but never did one, we need to mark the
+ // status as a fail
+ status = Status(StatusCode::INTERNAL,
+ "Service did not provide response message");
+ }
+ }
+ ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
+ param.call->PerformOps(&ops);
+ if (param.server_context->has_pending_ops_) {
+ param.call->cq()->Pluck(&param.server_context->pending_ops_);
+ }
+ param.call->cq()->Pluck(&ops);
+ }
+
+ private:
+ std::function<Status(ServerContext*, Streamer*)> func_;
+ const bool write_needed_;
+};
+
+template <class ServiceType, class RequestType, class ResponseType>
+class BidiStreamingHandler
+ : public TemplatedBidiStreamingHandler<
+ ServerReaderWriter<ResponseType, RequestType>, false> {
+ public:
+ BidiStreamingHandler(
+ std::function<Status(ServiceType*, ServerContext*,
+ ServerReaderWriter<ResponseType, RequestType>*)>
+ func,
+ ServiceType* service)
+ : TemplatedBidiStreamingHandler<
+ ServerReaderWriter<ResponseType, RequestType>, false>(std::bind(
+ func, service, std::placeholders::_1, std::placeholders::_2)) {}
+};
+
+template <class RequestType, class ResponseType>
+class StreamedUnaryHandler
+ : public TemplatedBidiStreamingHandler<
+ ServerUnaryStreamer<RequestType, ResponseType>, true> {
+ public:
+ explicit StreamedUnaryHandler(
+ std::function<Status(ServerContext*,
+ ServerUnaryStreamer<RequestType, ResponseType>*)>
+ func)
+ : TemplatedBidiStreamingHandler<
+ ServerUnaryStreamer<RequestType, ResponseType>, true>(func) {}
+};
+
+template <class RequestType, class ResponseType>
+class SplitServerStreamingHandler
+ : public TemplatedBidiStreamingHandler<
+ ServerSplitStreamer<RequestType, ResponseType>, false> {
+ public:
+ explicit SplitServerStreamingHandler(
+ std::function<Status(ServerContext*,
+ ServerSplitStreamer<RequestType, ResponseType>*)>
+ func)
+ : TemplatedBidiStreamingHandler<
+ ServerSplitStreamer<RequestType, ResponseType>, false>(func) {}
+};
+
+/// Handle unknown method by returning UNIMPLEMENTED error.
+class UnknownMethodHandler : public MethodHandler {
+ public:
+ template <class T>
+ static void FillOps(ServerContext* context, T* ops) {
+ Status status(StatusCode::UNIMPLEMENTED, "");
+ if (!context->sent_initial_metadata_) {
+ ops->SendInitialMetadata(context->initial_metadata_,
+ context->initial_metadata_flags());
+ if (context->compression_level_set()) {
+ ops->set_compression_level(context->compression_level());
+ }
+ context->sent_initial_metadata_ = true;
+ }
+ ops->ServerSendStatus(context->trailing_metadata_, status);
+ }
+
+ void RunHandler(const HandlerParameter& param) final {
+ CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
+ FillOps(param.server_context, &ops);
+ param.call->PerformOps(&ops);
+ param.call->cq()->Pluck(&ops);
+ }
+};
+
+} // namespace internal
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
diff --git a/include/grpcpp/impl/codegen/proto_utils.h b/include/grpcpp/impl/codegen/proto_utils.h
new file mode 100644
index 0000000000..81438ee1d5
--- /dev/null
+++ b/include/grpcpp/impl/codegen/proto_utils.h
@@ -0,0 +1,268 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_PROTO_UTILS_H
+#define GRPCPP_IMPL_CODEGEN_PROTO_UTILS_H
+
+#include <type_traits>
+
+#include <grpc/impl/codegen/byte_buffer_reader.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/config_protobuf.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+namespace internal {
+
+class GrpcBufferWriterPeer;
+
+const int kGrpcBufferWriterMaxBufferLength = 1024 * 1024;
+
+class GrpcBufferWriter : public ::grpc::protobuf::io::ZeroCopyOutputStream {
+ public:
+ GrpcBufferWriter(grpc_byte_buffer** bp, int block_size, int total_size)
+ : block_size_(block_size),
+ total_size_(total_size),
+ byte_count_(0),
+ have_backup_(false) {
+ *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(NULL, 0);
+ slice_buffer_ = &(*bp)->data.raw.slice_buffer;
+ }
+
+ ~GrpcBufferWriter() override {
+ if (have_backup_) {
+ g_core_codegen_interface->grpc_slice_unref(backup_slice_);
+ }
+ }
+
+ bool Next(void** data, int* size) override {
+ // Protobuf should not ask for more memory than total_size_.
+ GPR_CODEGEN_ASSERT(byte_count_ < total_size_);
+ size_t remain = total_size_ - byte_count_;
+ if (have_backup_) {
+ slice_ = backup_slice_;
+ have_backup_ = false;
+ if (GRPC_SLICE_LENGTH(slice_) > remain) {
+ GRPC_SLICE_SET_LENGTH(slice_, remain);
+ }
+ } else {
+ // When less than a whole block is needed, only allocate that much.
+ // But make sure the allocated slice is not inlined.
+ size_t allocate_length =
+ remain > static_cast<size_t>(block_size_) ? block_size_ : remain;
+ slice_ = g_core_codegen_interface->grpc_slice_malloc(
+ allocate_length > GRPC_SLICE_INLINED_SIZE
+ ? allocate_length
+ : GRPC_SLICE_INLINED_SIZE + 1);
+ }
+ *data = GRPC_SLICE_START_PTR(slice_);
+ // On win x64, int is only 32bit
+ GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
+ byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
+ g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
+ return true;
+ }
+
+ void BackUp(int count) override {
+ g_core_codegen_interface->grpc_slice_buffer_pop(slice_buffer_);
+ if ((size_t)count == GRPC_SLICE_LENGTH(slice_)) {
+ backup_slice_ = slice_;
+ } else {
+ backup_slice_ = g_core_codegen_interface->grpc_slice_split_tail(
+ &slice_, GRPC_SLICE_LENGTH(slice_) - count);
+ g_core_codegen_interface->grpc_slice_buffer_add(slice_buffer_, slice_);
+ }
+ // It's dangerous to keep an inlined grpc_slice as the backup slice, since
+ // on a following Next() call, a reference will be returned to this slice
+ // via GRPC_SLICE_START_PTR, which will not be an adddress held by
+ // slice_buffer_.
+ have_backup_ = backup_slice_.refcount != NULL;
+ byte_count_ -= count;
+ }
+
+ grpc::protobuf::int64 ByteCount() const override { return byte_count_; }
+
+ protected:
+ friend class GrpcBufferWriterPeer;
+ const int block_size_;
+ const int total_size_;
+ int64_t byte_count_;
+ grpc_slice_buffer* slice_buffer_;
+ bool have_backup_;
+ grpc_slice backup_slice_;
+ grpc_slice slice_;
+};
+
+class GrpcBufferReader : public ::grpc::protobuf::io::ZeroCopyInputStream {
+ public:
+ explicit GrpcBufferReader(grpc_byte_buffer* buffer)
+ : byte_count_(0), backup_count_(0), status_() {
+ if (!g_core_codegen_interface->grpc_byte_buffer_reader_init(&reader_,
+ buffer)) {
+ status_ = Status(StatusCode::INTERNAL,
+ "Couldn't initialize byte buffer reader");
+ }
+ }
+ ~GrpcBufferReader() override {
+ g_core_codegen_interface->grpc_byte_buffer_reader_destroy(&reader_);
+ }
+
+ bool Next(const void** data, int* size) override {
+ if (!status_.ok()) {
+ return false;
+ }
+ if (backup_count_ > 0) {
+ *data = GRPC_SLICE_START_PTR(slice_) + GRPC_SLICE_LENGTH(slice_) -
+ backup_count_;
+ GPR_CODEGEN_ASSERT(backup_count_ <= INT_MAX);
+ *size = (int)backup_count_;
+ backup_count_ = 0;
+ return true;
+ }
+ if (!g_core_codegen_interface->grpc_byte_buffer_reader_next(&reader_,
+ &slice_)) {
+ return false;
+ }
+ g_core_codegen_interface->grpc_slice_unref(slice_);
+ *data = GRPC_SLICE_START_PTR(slice_);
+ // On win x64, int is only 32bit
+ GPR_CODEGEN_ASSERT(GRPC_SLICE_LENGTH(slice_) <= INT_MAX);
+ byte_count_ += * size = (int)GRPC_SLICE_LENGTH(slice_);
+ return true;
+ }
+
+ Status status() const { return status_; }
+
+ void BackUp(int count) override { backup_count_ = count; }
+
+ bool Skip(int count) override {
+ const void* data;
+ int size;
+ while (Next(&data, &size)) {
+ if (size >= count) {
+ BackUp(size - count);
+ return true;
+ }
+ // size < count;
+ count -= size;
+ }
+ // error or we have too large count;
+ return false;
+ }
+
+ grpc::protobuf::int64 ByteCount() const override {
+ return byte_count_ - backup_count_;
+ }
+
+ protected:
+ int64_t byte_count_;
+ int64_t backup_count_;
+ grpc_byte_buffer_reader reader_;
+ grpc_slice slice_;
+ Status status_;
+};
+
+// BufferWriter must be a subclass of io::ZeroCopyOutputStream.
+template <class BufferWriter, class T>
+Status GenericSerialize(const grpc::protobuf::Message& msg,
+ grpc_byte_buffer** bp, bool* own_buffer) {
+ static_assert(
+ std::is_base_of<protobuf::io::ZeroCopyOutputStream, BufferWriter>::value,
+ "BufferWriter must be a subclass of io::ZeroCopyOutputStream");
+ *own_buffer = true;
+ int byte_size = msg.ByteSize();
+ if ((size_t)byte_size <= GRPC_SLICE_INLINED_SIZE) {
+ grpc_slice slice = g_core_codegen_interface->grpc_slice_malloc(byte_size);
+ GPR_CODEGEN_ASSERT(
+ GRPC_SLICE_END_PTR(slice) ==
+ msg.SerializeWithCachedSizesToArray(GRPC_SLICE_START_PTR(slice)));
+ *bp = g_core_codegen_interface->grpc_raw_byte_buffer_create(&slice, 1);
+ g_core_codegen_interface->grpc_slice_unref(slice);
+
+ return g_core_codegen_interface->ok();
+ }
+ BufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength, byte_size);
+ return msg.SerializeToZeroCopyStream(&writer)
+ ? g_core_codegen_interface->ok()
+ : Status(StatusCode::INTERNAL, "Failed to serialize message");
+}
+
+// BufferReader must be a subclass of io::ZeroCopyInputStream.
+template <class BufferReader, class T>
+Status GenericDeserialize(grpc_byte_buffer* buffer,
+ grpc::protobuf::Message* msg) {
+ static_assert(
+ std::is_base_of<protobuf::io::ZeroCopyInputStream, BufferReader>::value,
+ "BufferReader must be a subclass of io::ZeroCopyInputStream");
+ if (buffer == nullptr) {
+ return Status(StatusCode::INTERNAL, "No payload");
+ }
+ Status result = g_core_codegen_interface->ok();
+ {
+ BufferReader reader(buffer);
+ if (!reader.status().ok()) {
+ return reader.status();
+ }
+ ::grpc::protobuf::io::CodedInputStream decoder(&reader);
+ decoder.SetTotalBytesLimit(INT_MAX, INT_MAX);
+ if (!msg->ParseFromCodedStream(&decoder)) {
+ result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
+ }
+ if (!decoder.ConsumedEntireMessage()) {
+ result = Status(StatusCode::INTERNAL, "Did not read entire message");
+ }
+ }
+ g_core_codegen_interface->grpc_byte_buffer_destroy(buffer);
+ return result;
+}
+
+} // namespace internal
+
+// this is needed so the following class does not conflict with protobuf
+// serializers that utilize internal-only tools.
+#ifdef GRPC_OPEN_SOURCE_PROTO
+// This class provides a protobuf serializer. It translates between protobuf
+// objects and grpc_byte_buffers. More information about SerializationTraits can
+// be found in include/grpcpp/impl/codegen/serialization_traits.h.
+template <class T>
+class SerializationTraits<T, typename std::enable_if<std::is_base_of<
+ grpc::protobuf::Message, T>::value>::type> {
+ public:
+ static Status Serialize(const grpc::protobuf::Message& msg,
+ grpc_byte_buffer** bp, bool* own_buffer) {
+ return internal::GenericSerialize<internal::GrpcBufferWriter, T>(
+ msg, bp, own_buffer);
+ }
+
+ static Status Deserialize(grpc_byte_buffer* buffer,
+ grpc::protobuf::Message* msg) {
+ return internal::GenericDeserialize<internal::GrpcBufferReader, T>(buffer,
+ msg);
+ }
+};
+#endif
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_PROTO_UTILS_H
diff --git a/include/grpcpp/impl/codegen/rpc_method.h b/include/grpcpp/impl/codegen/rpc_method.h
new file mode 100644
index 0000000000..9dcde954f1
--- /dev/null
+++ b/include/grpcpp/impl/codegen/rpc_method.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_RPC_METHOD_H
+#define GRPCPP_IMPL_CODEGEN_RPC_METHOD_H
+
+#include <memory>
+
+#include <grpcpp/impl/codegen/channel_interface.h>
+
+namespace grpc {
+namespace internal {
+/// Descriptor of an RPC method
+class RpcMethod {
+ public:
+ enum RpcType {
+ NORMAL_RPC = 0,
+ CLIENT_STREAMING, // request streaming
+ SERVER_STREAMING, // response streaming
+ BIDI_STREAMING
+ };
+
+ RpcMethod(const char* name, RpcType type)
+ : name_(name), method_type_(type), channel_tag_(NULL) {}
+
+ RpcMethod(const char* name, RpcType type,
+ const std::shared_ptr<ChannelInterface>& channel)
+ : name_(name),
+ method_type_(type),
+ channel_tag_(channel->RegisterMethod(name)) {}
+
+ const char* name() const { return name_; }
+ RpcType method_type() const { return method_type_; }
+ void SetMethodType(RpcType type) { method_type_ = type; }
+ void* channel_tag() const { return channel_tag_; }
+
+ private:
+ const char* const name_;
+ RpcType method_type_;
+ void* const channel_tag_;
+};
+
+} // namespace internal
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_RPC_METHOD_H
diff --git a/include/grpcpp/impl/codegen/rpc_service_method.h b/include/grpcpp/impl/codegen/rpc_service_method.h
new file mode 100644
index 0000000000..dd85405e7a
--- /dev/null
+++ b/include/grpcpp/impl/codegen/rpc_service_method.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
+#define GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
+
+#include <climits>
+#include <functional>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <grpcpp/impl/codegen/byte_buffer.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+class ServerContext;
+
+namespace internal {
+/// Base class for running an RPC handler.
+class MethodHandler {
+ public:
+ virtual ~MethodHandler() {}
+ struct HandlerParameter {
+ HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req)
+ : call(c), server_context(context) {
+ request.set_buffer(req);
+ }
+ ~HandlerParameter() { request.Release(); }
+ Call* call;
+ ServerContext* server_context;
+ // Handler required to destroy these contents
+ ByteBuffer request;
+ };
+ virtual void RunHandler(const HandlerParameter& param) = 0;
+};
+
+/// Server side rpc method class
+class RpcServiceMethod : public RpcMethod {
+ public:
+ /// Takes ownership of the handler
+ RpcServiceMethod(const char* name, RpcMethod::RpcType type,
+ MethodHandler* handler)
+ : RpcMethod(name, type), server_tag_(nullptr), handler_(handler) {}
+
+ void set_server_tag(void* tag) { server_tag_ = tag; }
+ void* server_tag() const { return server_tag_; }
+ /// if MethodHandler is nullptr, then this is an async method
+ MethodHandler* handler() const { return handler_.get(); }
+ void ResetHandler() { handler_.reset(); }
+ void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
+
+ private:
+ void* server_tag_;
+ std::unique_ptr<MethodHandler> handler_;
+};
+} // namespace internal
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
diff --git a/include/grpcpp/impl/codegen/security/auth_context.h b/include/grpcpp/impl/codegen/security/auth_context.h
new file mode 100644
index 0000000000..0e30f7cc3f
--- /dev/null
+++ b/include/grpcpp/impl/codegen/security/auth_context.h
@@ -0,0 +1,95 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
+#define GRPCPP_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
+
+#include <iterator>
+#include <vector>
+
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/string_ref.h>
+
+struct grpc_auth_context;
+struct grpc_auth_property;
+struct grpc_auth_property_iterator;
+
+namespace grpc {
+class SecureAuthContext;
+
+typedef std::pair<grpc::string_ref, grpc::string_ref> AuthProperty;
+
+class AuthPropertyIterator
+ : public std::iterator<std::input_iterator_tag, const AuthProperty> {
+ public:
+ ~AuthPropertyIterator();
+ AuthPropertyIterator& operator++();
+ AuthPropertyIterator operator++(int);
+ bool operator==(const AuthPropertyIterator& rhs) const;
+ bool operator!=(const AuthPropertyIterator& rhs) const;
+ const AuthProperty operator*();
+
+ protected:
+ AuthPropertyIterator();
+ AuthPropertyIterator(const grpc_auth_property* property,
+ const grpc_auth_property_iterator* iter);
+
+ private:
+ friend class SecureAuthContext;
+ const grpc_auth_property* property_;
+ // The following items form a grpc_auth_property_iterator.
+ const grpc_auth_context* ctx_;
+ size_t index_;
+ const char* name_;
+};
+
+/// Class encapsulating the Authentication Information.
+///
+/// It includes the secure identity of the peer, the type of secure transport
+/// used as well as any other properties required by the authorization layer.
+class AuthContext {
+ public:
+ virtual ~AuthContext() {}
+
+ /// Returns true if the peer is authenticated.
+ virtual bool IsPeerAuthenticated() const = 0;
+
+ /// A peer identity.
+ ///
+ /// It is, in general, comprised of one or more properties (in which case they
+ /// have the same name).
+ virtual std::vector<grpc::string_ref> GetPeerIdentity() const = 0;
+ virtual grpc::string GetPeerIdentityPropertyName() const = 0;
+
+ /// Returns all the property values with the given name.
+ virtual std::vector<grpc::string_ref> FindPropertyValues(
+ const grpc::string& name) const = 0;
+
+ /// Iteration over all the properties.
+ virtual AuthPropertyIterator begin() const = 0;
+ virtual AuthPropertyIterator end() const = 0;
+
+ /// Mutation functions: should only be used by an AuthMetadataProcessor.
+ virtual void AddProperty(const grpc::string& key,
+ const grpc::string_ref& value) = 0;
+ virtual bool SetPeerIdentityPropertyName(const grpc::string& name) = 0;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SECURITY_AUTH_CONTEXT_H
diff --git a/include/grpcpp/impl/codegen/serialization_traits.h b/include/grpcpp/impl/codegen/serialization_traits.h
new file mode 100644
index 0000000000..8f79223290
--- /dev/null
+++ b/include/grpcpp/impl/codegen/serialization_traits.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
+#define GRPCPP_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
+
+namespace grpc {
+
+/// Defines how to serialize and deserialize some type.
+///
+/// Used for hooking different message serialization API's into GRPC.
+/// Each SerializationTraits<Message> implementation must provide the
+/// following functions:
+/// 1. static Status Serialize(const Message& msg,
+/// ByteBuffer* buffer,
+/// bool* own_buffer);
+/// OR
+/// static Status Serialize(const Message& msg,
+/// grpc_byte_buffer** buffer,
+/// bool* own_buffer);
+/// The former is preferred; the latter is deprecated
+///
+/// 2. static Status Deserialize(ByteBuffer* buffer,
+/// Message* msg);
+/// OR
+/// static Status Deserialize(grpc_byte_buffer* buffer,
+/// Message* msg);
+/// The former is preferred; the latter is deprecated
+///
+/// Serialize is required to convert message to a ByteBuffer, and
+/// return that byte buffer through *buffer. *own_buffer should
+/// be set to true if the caller owns said byte buffer, or false if
+/// ownership is retained elsewhere.
+///
+/// Deserialize is required to convert buffer into the message stored at
+/// msg. max_receive_message_size is passed in as a bound on the maximum
+/// number of message bytes Deserialize should accept.
+///
+/// Both functions return a Status, allowing them to explain what went
+/// wrong if required.
+template <class Message,
+ class UnusedButHereForPartialTemplateSpecialization = void>
+class SerializationTraits;
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SERIALIZATION_TRAITS_H
diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h
new file mode 100644
index 0000000000..bb357d6734
--- /dev/null
+++ b/include/grpcpp/impl/codegen/server_context.h
@@ -0,0 +1,309 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
+#define GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
+
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <grpc/impl/codegen/compression_types.h>
+
+#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/create_auth_context.h>
+#include <grpcpp/impl/codegen/metadata_map.h>
+#include <grpcpp/impl/codegen/security/auth_context.h>
+#include <grpcpp/impl/codegen/string_ref.h>
+#include <grpcpp/impl/codegen/time.h>
+
+struct grpc_metadata;
+struct grpc_call;
+struct census_context;
+
+namespace grpc {
+class ClientContext;
+template <class W, class R>
+class ServerAsyncReader;
+template <class W>
+class ServerAsyncWriter;
+template <class W>
+class ServerAsyncResponseWriter;
+template <class W, class R>
+class ServerAsyncReaderWriter;
+template <class R>
+class ServerReader;
+template <class W>
+class ServerWriter;
+namespace internal {
+template <class W, class R>
+class ServerReaderWriterBody;
+template <class ServiceType, class RequestType, class ResponseType>
+class RpcMethodHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class ClientStreamingHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class ServerStreamingHandler;
+template <class ServiceType, class RequestType, class ResponseType>
+class BidiStreamingHandler;
+class UnknownMethodHandler;
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler;
+class Call;
+} // namespace internal
+
+class CompletionQueue;
+class Server;
+class ServerInterface;
+
+namespace testing {
+class InteropServerContextInspector;
+class ServerContextTestSpouse;
+} // namespace testing
+
+/// A ServerContext allows the person implementing a service handler to:
+///
+/// - Add custom initial and trailing metadata key-value pairs that will
+/// propagated to the client side.
+/// - Control call settings such as compression and authentication.
+/// - Access metadata coming from the client.
+/// - Get performance metrics (ie, census).
+///
+/// Context settings are only relevant to the call handler they are supplied to,
+/// that is to say, they aren't sticky across multiple calls. Some of these
+/// settings, such as the compression options, can be made persistant at server
+/// construction time by specifying the approriate \a ChannelArguments
+/// to a \a grpc::ServerBuilder, via \a ServerBuilder::AddChannelArgument.
+///
+/// \warning ServerContext instances should \em not be reused across rpcs.
+class ServerContext {
+ public:
+ ServerContext(); // for async calls
+ ~ServerContext();
+
+ /// Return the deadline for the server call.
+ std::chrono::system_clock::time_point deadline() const {
+ return Timespec2Timepoint(deadline_);
+ }
+
+ /// Return a \a gpr_timespec representation of the server call's deadline.
+ gpr_timespec raw_deadline() const { return deadline_; }
+
+ /// Add the (\a meta_key, \a meta_value) pair to the initial metadata
+ /// associated with a server call. These are made available at the client side
+ /// by the \a grpc::ClientContext::GetServerInitialMetadata() method.
+ ///
+ /// \warning This method should only be called before sending initial metadata
+ /// to the client (which can happen explicitly, or implicitly when sending a
+ /// a response message or status to the client).
+ ///
+ /// \param meta_key The metadata key. If \a meta_value is binary data, it must
+ /// end in "-bin".
+ /// \param meta_value The metadata value. If its value is binary, the key name
+ /// must end in "-bin".
+ void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
+
+ /// Add the (\a meta_key, \a meta_value) pair to the initial metadata
+ /// associated with a server call. These are made available at the client
+ /// side by the \a grpc::ClientContext::GetServerTrailingMetadata() method.
+ ///
+ /// \warning This method should only be called before sending trailing
+ /// metadata to the client (which happens when the call is finished and a
+ /// status is sent to the client).
+ ///
+ /// \param meta_key The metadata key. If \a meta_value is binary data,
+ /// it must end in "-bin".
+ /// \param meta_value The metadata value. If its value is binary, the key name
+ /// must end in "-bin".
+ void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
+
+ /// IsCancelled is always safe to call when using sync API.
+ /// When using async API, it is only safe to call IsCancelled after
+ /// the AsyncNotifyWhenDone tag has been delivered.
+ bool IsCancelled() const;
+
+ /// Cancel the Call from the server. This is a best-effort API and
+ /// depending on when it is called, the RPC may still appear successful to
+ /// the client.
+ /// For example, if TryCancel() is called on a separate thread, it might race
+ /// with the server handler which might return success to the client before
+ /// TryCancel() was even started by the thread.
+ ///
+ /// It is the caller's responsibility to prevent such races and ensure that if
+ /// TryCancel() is called, the serverhandler must return Status::CANCELLED.
+ /// The only exception is that if the serverhandler is already returning an
+ /// error status code, it is ok to not return Status::CANCELLED even if
+ /// TryCancel() was called.
+ ///
+ /// Note that TryCancel() does not change any of the tags that are pending
+ /// on the completion queue. All pending tags will still be delivered
+ /// (though their ok result may reflect the effect of cancellation).
+ void TryCancel() const;
+
+ /// Return a collection of initial metadata key-value pairs sent from the
+ /// client. Note that keys may happen more than
+ /// once (ie, a \a std::multimap is returned).
+ ///
+ /// It is safe to use this method after initial metadata has been received,
+ /// Calls always begin with the client sending initial metadata, so this is
+ /// safe to access as soon as the call has begun on the server side.
+ ///
+ /// \return A multimap of initial metadata key-value pairs from the server.
+ const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata()
+ const {
+ return *client_metadata_.map();
+ }
+
+ /// Return the compression algorithm to be used by the server call.
+ grpc_compression_level compression_level() const {
+ return compression_level_;
+ }
+
+ /// Set \a algorithm to be the compression algorithm used for the server call.
+ ///
+ /// \param algorithm The compression algorithm used for the server call.
+ void set_compression_level(grpc_compression_level level) {
+ compression_level_set_ = true;
+ compression_level_ = level;
+ }
+
+ /// Return a bool indicating whether the compression level for this call
+ /// has been set (either implicitly or through a previous call to
+ /// \a set_compression_level.
+ bool compression_level_set() const { return compression_level_set_; }
+
+ /// Return the compression algorithm the server call will request be used.
+ /// Note that the gRPC runtime may decide to ignore this request, for example,
+ /// due to resource constraints, or if the server is aware the client doesn't
+ /// support the requested algorithm.
+ grpc_compression_algorithm compression_algorithm() const {
+ return compression_algorithm_;
+ }
+ /// Set \a algorithm to be the compression algorithm used for the server call.
+ ///
+ /// \param algorithm The compression algorithm used for the server call.
+ void set_compression_algorithm(grpc_compression_algorithm algorithm);
+
+ /// Set the load reporting costs in \a cost_data for the call.
+ void SetLoadReportingCosts(const std::vector<grpc::string>& cost_data);
+
+ /// Return the authentication context for this server call.
+ ///
+ /// \see grpc::AuthContext.
+ std::shared_ptr<const AuthContext> auth_context() const {
+ if (auth_context_.get() == nullptr) {
+ auth_context_ = CreateAuthContext(call_);
+ }
+ return auth_context_;
+ }
+
+ /// Return the peer uri in a string.
+ /// WARNING: this value is never authenticated or subject to any security
+ /// related code. It must not be used for any authentication related
+ /// functionality. Instead, use auth_context.
+ grpc::string peer() const;
+
+ /// Get the census context associated with this server call.
+ const struct census_context* census_context() const;
+
+ /// Async only. Has to be called before the rpc starts.
+ /// Returns the tag in completion queue when the rpc finishes.
+ /// IsCancelled() can then be called to check whether the rpc was cancelled.
+ void AsyncNotifyWhenDone(void* tag) {
+ has_notify_when_done_tag_ = true;
+ async_notify_when_done_tag_ = tag;
+ }
+
+ /// Should be used for framework-level extensions only.
+ /// Applications never need to call this method.
+ grpc_call* c_call() { return call_; }
+
+ private:
+ friend class ::grpc::testing::InteropServerContextInspector;
+ friend class ::grpc::testing::ServerContextTestSpouse;
+ friend class ::grpc::ServerInterface;
+ friend class ::grpc::Server;
+ template <class W, class R>
+ friend class ::grpc::ServerAsyncReader;
+ template <class W>
+ friend class ::grpc::ServerAsyncWriter;
+ template <class W>
+ friend class ::grpc::ServerAsyncResponseWriter;
+ template <class W, class R>
+ friend class ::grpc::ServerAsyncReaderWriter;
+ template <class R>
+ friend class ::grpc::ServerReader;
+ template <class W>
+ friend class ::grpc::ServerWriter;
+ template <class W, class R>
+ friend class ::grpc::internal::ServerReaderWriterBody;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class ::grpc::internal::RpcMethodHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class ::grpc::internal::ClientStreamingHandler;
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class ::grpc::internal::ServerStreamingHandler;
+ template <class Streamer, bool WriteNeeded>
+ friend class ::grpc::internal::TemplatedBidiStreamingHandler;
+ friend class ::grpc::internal::UnknownMethodHandler;
+ friend class ::grpc::ClientContext;
+
+ /// Prevent copying.
+ ServerContext(const ServerContext&);
+ ServerContext& operator=(const ServerContext&);
+
+ class CompletionOp;
+
+ void BeginCompletionOp(internal::Call* call);
+ /// Return the tag queued by BeginCompletionOp()
+ internal::CompletionQueueTag* GetCompletionOpTag();
+
+ ServerContext(gpr_timespec deadline, grpc_metadata_array* arr);
+
+ void set_call(grpc_call* call) { call_ = call; }
+
+ uint32_t initial_metadata_flags() const { return 0; }
+
+ CompletionOp* completion_op_;
+ bool has_notify_when_done_tag_;
+ void* async_notify_when_done_tag_;
+
+ gpr_timespec deadline_;
+ grpc_call* call_;
+ CompletionQueue* cq_;
+ bool sent_initial_metadata_;
+ mutable std::shared_ptr<const AuthContext> auth_context_;
+ internal::MetadataMap client_metadata_;
+ std::multimap<grpc::string, grpc::string> initial_metadata_;
+ std::multimap<grpc::string, grpc::string> trailing_metadata_;
+
+ bool compression_level_set_;
+ grpc_compression_level compression_level_;
+ grpc_compression_algorithm compression_algorithm_;
+
+ internal::CallOpSet<internal::CallOpSendInitialMetadata,
+ internal::CallOpSendMessage>
+ pending_ops_;
+ bool has_pending_ops_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SERVER_CONTEXT_H
diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h
new file mode 100644
index 0000000000..4700763ed2
--- /dev/null
+++ b/include/grpcpp/impl/codegen/server_interface.h
@@ -0,0 +1,274 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H
+#define GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpcpp/impl/codegen/call_hook.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+
+namespace grpc {
+
+class AsyncGenericService;
+class Channel;
+class GenericServerContext;
+class ServerCompletionQueue;
+class ServerContext;
+class ServerCredentials;
+class Service;
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+/// Models a gRPC server.
+///
+/// Servers are configured and started via \a grpc::ServerBuilder.
+namespace internal {
+class ServerAsyncStreamingInterface;
+} // namespace internal
+
+class ServerInterface : public internal::CallHook {
+ public:
+ virtual ~ServerInterface() {}
+
+ /// Shutdown the server, blocking until all rpc processing finishes.
+ /// Forcefully terminate pending calls after \a deadline expires.
+ ///
+ /// All completion queue associated with the server (for example, for async
+ /// serving) must be shutdown *after* this method has returned:
+ /// See \a ServerBuilder::AddCompletionQueue for details.
+ ///
+ /// \param deadline How long to wait until pending rpcs are forcefully
+ /// terminated.
+ template <class T>
+ void Shutdown(const T& deadline) {
+ ShutdownInternal(TimePoint<T>(deadline).raw_time());
+ }
+
+ /// Shutdown the server, waiting for all rpc processing to finish.
+ ///
+ /// All completion queue associated with the server (for example, for async
+ /// serving) must be shutdown *after* this method has returned:
+ /// See \a ServerBuilder::AddCompletionQueue for details.
+ void Shutdown() {
+ ShutdownInternal(
+ g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_MONOTONIC));
+ }
+
+ /// Block waiting for all work to complete.
+ ///
+ /// \warning The server must be either shutting down or some other thread must
+ /// call \a Shutdown for this function to ever return.
+ virtual void Wait() = 0;
+
+ protected:
+ friend class ::grpc::Service;
+
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the Server instance.
+ virtual bool RegisterService(const grpc::string* host, Service* service) = 0;
+
+ /// Register a generic service. This call does not take ownership of the
+ /// service. The service must exist for the lifetime of the Server instance.
+ virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
+
+ /// Tries to bind \a server to the given \a addr.
+ ///
+ /// It can be invoked multiple times.
+ ///
+ /// \param addr The address to try to bind to the server (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.).
+ /// \params creds The credentials associated with the server.
+ ///
+ /// \return bound port number on sucess, 0 on failure.
+ ///
+ /// \warning It's an error to call this method on an already started server.
+ virtual int AddListeningPort(const grpc::string& addr,
+ ServerCredentials* creds) = 0;
+
+ /// Start the server.
+ ///
+ /// \param cqs Completion queues for handling asynchronous services. The
+ /// caller is required to keep all completion queues live until the server is
+ /// destroyed.
+ /// \param num_cqs How many completion queues does \a cqs hold.
+ virtual void Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
+
+ virtual void ShutdownInternal(gpr_timespec deadline) = 0;
+
+ virtual int max_receive_message_size() const = 0;
+
+ virtual grpc_server* server() = 0;
+
+ virtual void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) = 0;
+
+ class BaseAsyncRequest : public internal::CompletionQueueTag {
+ public:
+ BaseAsyncRequest(ServerInterface* server, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq, void* tag,
+ bool delete_on_finalize);
+ virtual ~BaseAsyncRequest();
+
+ bool FinalizeResult(void** tag, bool* status) override;
+
+ protected:
+ ServerInterface* const server_;
+ ServerContext* const context_;
+ internal::ServerAsyncStreamingInterface* const stream_;
+ CompletionQueue* const call_cq_;
+ void* const tag_;
+ const bool delete_on_finalize_;
+ grpc_call* call_;
+ };
+
+ class RegisteredAsyncRequest : public BaseAsyncRequest {
+ public:
+ RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq, void* tag);
+
+ // uses BaseAsyncRequest::FinalizeResult
+
+ protected:
+ void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
+ ServerCompletionQueue* notification_cq);
+ };
+
+ class NoPayloadAsyncRequest final : public RegisteredAsyncRequest {
+ public:
+ NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag)
+ : RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
+ IssueRequest(registered_method, nullptr, notification_cq);
+ }
+
+ // uses RegisteredAsyncRequest::FinalizeResult
+ };
+
+ template <class Message>
+ class PayloadAsyncRequest final : public RegisteredAsyncRequest {
+ public:
+ PayloadAsyncRequest(void* registered_method, ServerInterface* server,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag,
+ Message* request)
+ : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
+ registered_method_(registered_method),
+ server_(server),
+ context_(context),
+ stream_(stream),
+ call_cq_(call_cq),
+ notification_cq_(notification_cq),
+ tag_(tag),
+ request_(request) {
+ IssueRequest(registered_method, &payload_, notification_cq);
+ }
+
+ bool FinalizeResult(void** tag, bool* status) override {
+ if (*status) {
+ if (payload_ == nullptr ||
+ !SerializationTraits<Message>::Deserialize(payload_, request_)
+ .ok()) {
+ // If deserialization fails, we cancel the call and instantiate
+ // a new instance of ourselves to request another call. We then
+ // return false, which prevents the call from being returned to
+ // the application.
+ g_core_codegen_interface->grpc_call_cancel_with_status(
+ call_, GRPC_STATUS_INTERNAL, "Unable to parse request", nullptr);
+ g_core_codegen_interface->grpc_call_unref(call_);
+ new PayloadAsyncRequest(registered_method_, server_, context_,
+ stream_, call_cq_, notification_cq_, tag_,
+ request_);
+ delete this;
+ return false;
+ }
+ }
+ return RegisteredAsyncRequest::FinalizeResult(tag, status);
+ }
+
+ private:
+ void* const registered_method_;
+ ServerInterface* const server_;
+ ServerContext* const context_;
+ internal::ServerAsyncStreamingInterface* const stream_;
+ CompletionQueue* const call_cq_;
+ ServerCompletionQueue* const notification_cq_;
+ void* const tag_;
+ Message* const request_;
+ grpc_byte_buffer* payload_;
+ };
+
+ class GenericAsyncRequest : public BaseAsyncRequest {
+ public:
+ GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag,
+ bool delete_on_finalize);
+
+ bool FinalizeResult(void** tag, bool* status) override;
+
+ private:
+ grpc_call_details call_details_;
+ };
+
+ template <class Message>
+ void RequestAsyncCall(internal::RpcServiceMethod* method,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag,
+ Message* message) {
+ GPR_CODEGEN_ASSERT(method);
+ new PayloadAsyncRequest<Message>(method->server_tag(), this, context,
+ stream, call_cq, notification_cq, tag,
+ message);
+ }
+
+ void RequestAsyncCall(internal::RpcServiceMethod* method,
+ ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
+ GPR_CODEGEN_ASSERT(method);
+ new NoPayloadAsyncRequest(method->server_tag(), this, context, stream,
+ call_cq, notification_cq, tag);
+ }
+
+ void RequestAsyncGenericCall(GenericServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq,
+ void* tag) {
+ new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
+ tag, true);
+ }
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H
diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h
new file mode 100644
index 0000000000..a576f66911
--- /dev/null
+++ b/include/grpcpp/impl/codegen/service_type.h
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SERVICE_TYPE_H
+#define GRPCPP_IMPL_CODEGEN_SERVICE_TYPE_H
+
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/rpc_service_method.h>
+#include <grpcpp/impl/codegen/serialization_traits.h>
+#include <grpcpp/impl/codegen/server_interface.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+class CompletionQueue;
+class Server;
+class ServerInterface;
+class ServerCompletionQueue;
+class ServerContext;
+
+namespace internal {
+class Call;
+class ServerAsyncStreamingInterface {
+ public:
+ virtual ~ServerAsyncStreamingInterface() {}
+
+ /// Request notification of the sending of initial metadata to the client.
+ /// Completion will be notified by \a tag on the associated completion
+ /// queue. This call is optional, but if it is used, it cannot be used
+ /// concurrently with or after the \a Finish method.
+ ///
+ /// \param[in] tag Tag identifying this request.
+ virtual void SendInitialMetadata(void* tag) = 0;
+
+ private:
+ friend class ::grpc::ServerInterface;
+ virtual void BindCall(Call* call) = 0;
+};
+} // namespace internal
+
+/// Desriptor of an RPC service and its various RPC methods
+class Service {
+ public:
+ Service() : server_(nullptr) {}
+ virtual ~Service() {}
+
+ bool has_async_methods() const {
+ for (auto it = methods_.begin(); it != methods_.end(); ++it) {
+ if (*it && (*it)->handler() == nullptr) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool has_synchronous_methods() const {
+ for (auto it = methods_.begin(); it != methods_.end(); ++it) {
+ if (*it && (*it)->handler() != nullptr) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool has_generic_methods() const {
+ for (auto it = methods_.begin(); it != methods_.end(); ++it) {
+ if (it->get() == nullptr) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected:
+ template <class Message>
+ void RequestAsyncUnary(int index, ServerContext* context, Message* request,
+ internal::ServerAsyncStreamingInterface* stream,
+ CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+ notification_cq, tag, request);
+ }
+ void RequestAsyncClientStreaming(
+ int index, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+ notification_cq, tag);
+ }
+ template <class Message>
+ void RequestAsyncServerStreaming(
+ int index, ServerContext* context, Message* request,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+ notification_cq, tag, request);
+ }
+ void RequestAsyncBidiStreaming(
+ int index, ServerContext* context,
+ internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
+ ServerCompletionQueue* notification_cq, void* tag) {
+ server_->RequestAsyncCall(methods_[index].get(), context, stream, call_cq,
+ notification_cq, tag);
+ }
+
+ void AddMethod(internal::RpcServiceMethod* method) {
+ methods_.emplace_back(method);
+ }
+
+ void MarkMethodAsync(int index) {
+ GPR_CODEGEN_ASSERT(
+ methods_[index].get() != nullptr &&
+ "Cannot mark the method as 'async' because it has already been "
+ "marked as 'generic'.");
+ methods_[index]->ResetHandler();
+ }
+
+ void MarkMethodGeneric(int index) {
+ GPR_CODEGEN_ASSERT(
+ methods_[index]->handler() != nullptr &&
+ "Cannot mark the method as 'generic' because it has already been "
+ "marked as 'async'.");
+ methods_[index].reset();
+ }
+
+ void MarkMethodStreamed(int index, internal::MethodHandler* streamed_method) {
+ GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
+ "Cannot mark an async or generic method Streamed");
+ methods_[index]->SetHandler(streamed_method);
+
+ // From the server's point of view, streamed unary is a special
+ // case of BIDI_STREAMING that has 1 read and 1 write, in that order,
+ // and split server-side streaming is BIDI_STREAMING with 1 read and
+ // any number of writes, in that order.
+ methods_[index]->SetMethodType(internal::RpcMethod::BIDI_STREAMING);
+ }
+
+ private:
+ friend class Server;
+ friend class ServerInterface;
+ ServerInterface* server_;
+ std::vector<std::unique_ptr<internal::RpcServiceMethod>> methods_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SERVICE_TYPE_H
diff --git a/include/grpcpp/impl/codegen/slice.h b/include/grpcpp/impl/codegen/slice.h
new file mode 100644
index 0000000000..fcccd4b68e
--- /dev/null
+++ b/include/grpcpp/impl/codegen/slice.h
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SLICE_H
+#define GRPCPP_IMPL_CODEGEN_SLICE_H
+
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/string_ref.h>
+
+#include <grpc/impl/codegen/slice.h>
+
+namespace grpc {
+
+/// A wrapper around \a grpc_slice.
+///
+/// A slice represents a contiguous reference counted array of bytes.
+/// It is cheap to take references to a slice, and it is cheap to create a
+/// slice pointing to a subset of another slice.
+class Slice final {
+ public:
+ /// Construct an empty slice.
+ Slice();
+ /// Destructor - drops one reference.
+ ~Slice();
+
+ enum AddRef { ADD_REF };
+ /// Construct a slice from \a slice, adding a reference.
+ Slice(grpc_slice slice, AddRef);
+
+ enum StealRef { STEAL_REF };
+ /// Construct a slice from \a slice, stealing a reference.
+ Slice(grpc_slice slice, StealRef);
+
+ /// Allocate a slice of specified size
+ Slice(size_t len);
+
+ /// Construct a slice from a copied buffer
+ Slice(const void* buf, size_t len);
+
+ /// Construct a slice from a copied string
+ Slice(const grpc::string& str);
+
+ enum StaticSlice { STATIC_SLICE };
+
+ /// Construct a slice from a static buffer
+ Slice(const void* buf, size_t len, StaticSlice);
+
+ /// Copy constructor, adds a reference.
+ Slice(const Slice& other);
+
+ /// Assignment, reference count is unchanged.
+ Slice& operator=(Slice other) {
+ std::swap(slice_, other.slice_);
+ return *this;
+ }
+
+ /// Create a slice pointing at some data. Calls malloc to allocate a refcount
+ /// for the object, and arranges that destroy will be called with the
+ /// user data pointer passed in at destruction. Can be the same as buf or
+ /// different (e.g., if data is part of a larger structure that must be
+ /// destroyed when the data is no longer needed)
+ Slice(void* buf, size_t len, void (*destroy)(void*), void* user_data);
+
+ /// Specialization of above for common case where buf == user_data
+ Slice(void* buf, size_t len, void (*destroy)(void*))
+ : Slice(buf, len, destroy, buf) {}
+
+ /// Similar to the above but has a destroy that also takes slice length
+ Slice(void* buf, size_t len, void (*destroy)(void*, size_t));
+
+ /// Byte size.
+ size_t size() const { return GRPC_SLICE_LENGTH(slice_); }
+
+ /// Raw pointer to the beginning (first element) of the slice.
+ const uint8_t* begin() const { return GRPC_SLICE_START_PTR(slice_); }
+
+ /// Raw pointer to the end (one byte \em past the last element) of the slice.
+ const uint8_t* end() const { return GRPC_SLICE_END_PTR(slice_); }
+
+ /// Raw C slice. Caller needs to call grpc_slice_unref when done.
+ grpc_slice c_slice() const;
+
+ private:
+ friend class ByteBuffer;
+
+ grpc_slice slice_;
+};
+
+inline grpc::string_ref StringRefFromSlice(const grpc_slice* slice) {
+ return grpc::string_ref(
+ reinterpret_cast<const char*>(GRPC_SLICE_START_PTR(*slice)),
+ GRPC_SLICE_LENGTH(*slice));
+}
+
+inline grpc::string StringFromCopiedSlice(grpc_slice slice) {
+ return grpc::string(reinterpret_cast<char*>(GRPC_SLICE_START_PTR(slice)),
+ GRPC_SLICE_LENGTH(slice));
+}
+
+inline grpc_slice SliceReferencingString(const grpc::string& str) {
+ return g_core_codegen_interface->grpc_slice_from_static_buffer(str.data(),
+ str.length());
+}
+
+inline grpc_slice SliceFromCopiedString(const grpc::string& str) {
+ return g_core_codegen_interface->grpc_slice_from_copied_buffer(str.data(),
+ str.length());
+}
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SLICE_H
diff --git a/include/grpcpp/impl/codegen/status.h b/include/grpcpp/impl/codegen/status.h
new file mode 100644
index 0000000000..9f409eb9bd
--- /dev/null
+++ b/include/grpcpp/impl/codegen/status.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_STATUS_H
+#define GRPCPP_IMPL_CODEGEN_STATUS_H
+
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/status_code_enum.h>
+
+namespace grpc {
+
+/// Did it work? If it didn't, why?
+///
+/// See \a grpc::StatusCode for details on the available code and their meaning.
+class Status {
+ public:
+ /// Construct an OK instance.
+ Status() : code_(StatusCode::OK) {}
+
+ /// Construct an instance with associated \a code and \a error_message.
+ /// It is an error to construct an OK status with non-empty \a error_message.
+ Status(StatusCode code, const grpc::string& error_message)
+ : code_(code), error_message_(error_message) {}
+
+ /// Construct an instance with \a code, \a error_message and
+ /// \a error_details. It is an error to construct an OK status with non-empty
+ /// \a error_message and/or \a error_details.
+ Status(StatusCode code, const grpc::string& error_message,
+ const grpc::string& error_details)
+ : code_(code),
+ error_message_(error_message),
+ binary_error_details_(error_details) {}
+
+ // Pre-defined special status objects.
+ /// An OK pre-defined instance.
+ static const Status& OK;
+ /// A CANCELLED pre-defined instance.
+ static const Status& CANCELLED;
+
+ /// Return the instance's error code.
+ StatusCode error_code() const { return code_; }
+ /// Return the instance's error message.
+ grpc::string error_message() const { return error_message_; }
+ /// Return the (binary) error details.
+ // Usually it contains a serialized google.rpc.Status proto.
+ grpc::string error_details() const { return binary_error_details_; }
+
+ /// Is the status OK?
+ bool ok() const { return code_ == StatusCode::OK; }
+
+ // Ignores any errors. This method does nothing except potentially suppress
+ // complaints from any tools that are checking that errors are not dropped on
+ // the floor.
+ void IgnoreError() const {}
+
+ private:
+ StatusCode code_;
+ grpc::string error_message_;
+ grpc::string binary_error_details_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_STATUS_H
diff --git a/include/grpcpp/impl/codegen/status_code_enum.h b/include/grpcpp/impl/codegen/status_code_enum.h
new file mode 100644
index 0000000000..09943f10de
--- /dev/null
+++ b/include/grpcpp/impl/codegen/status_code_enum.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_STATUS_CODE_ENUM_H
+#define GRPCPP_IMPL_CODEGEN_STATUS_CODE_ENUM_H
+
+namespace grpc {
+
+enum StatusCode {
+ /// Not an error; returned on success.
+ OK = 0,
+
+ /// The operation was cancelled (typically by the caller).
+ CANCELLED = 1,
+
+ /// Unknown error. An example of where this error may be returned is if a
+ /// Status value received from another address space belongs to an error-space
+ /// that is not known in this address space. Also errors raised by APIs that
+ /// do not return enough error information may be converted to this error.
+ UNKNOWN = 2,
+
+ /// Client specified an invalid argument. Note that this differs from
+ /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
+ /// problematic regardless of the state of the system (e.g., a malformed file
+ /// name).
+ INVALID_ARGUMENT = 3,
+
+ /// Deadline expired before operation could complete. For operations that
+ /// change the state of the system, this error may be returned even if the
+ /// operation has completed successfully. For example, a successful response
+ /// from a server could have been delayed long enough for the deadline to
+ /// expire.
+ DEADLINE_EXCEEDED = 4,
+
+ /// Some requested entity (e.g., file or directory) was not found.
+ NOT_FOUND = 5,
+
+ /// Some entity that we attempted to create (e.g., file or directory) already
+ /// exists.
+ ALREADY_EXISTS = 6,
+
+ /// The caller does not have permission to execute the specified operation.
+ /// PERMISSION_DENIED must not be used for rejections caused by exhausting
+ /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
+ /// PERMISSION_DENIED must not be used if the caller can not be identified
+ /// (use UNAUTHENTICATED instead for those errors).
+ PERMISSION_DENIED = 7,
+
+ /// The request does not have valid authentication credentials for the
+ /// operation.
+ UNAUTHENTICATED = 16,
+
+ /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+ /// entire file system is out of space.
+ RESOURCE_EXHAUSTED = 8,
+
+ /// Operation was rejected because the system is not in a state required for
+ /// the operation's execution. For example, directory to be deleted may be
+ /// non-empty, an rmdir operation is applied to a non-directory, etc.
+ ///
+ /// A litmus test that may help a service implementor in deciding
+ /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+ /// (a) Use UNAVAILABLE if the client can retry just the failing call.
+ /// (b) Use ABORTED if the client should retry at a higher-level
+ /// (e.g., restarting a read-modify-write sequence).
+ /// (c) Use FAILED_PRECONDITION if the client should not retry until
+ /// the system state has been explicitly fixed. E.g., if an "rmdir"
+ /// fails because the directory is non-empty, FAILED_PRECONDITION
+ /// should be returned since the client should not retry unless
+ /// they have first fixed up the directory by deleting files from it.
+ /// (d) Use FAILED_PRECONDITION if the client performs conditional
+ /// REST Get/Update/Delete on a resource and the resource on the
+ /// server does not match the condition. E.g., conflicting
+ /// read-modify-write on the same resource.
+ FAILED_PRECONDITION = 9,
+
+ /// The operation was aborted, typically due to a concurrency issue like
+ /// sequencer check failures, transaction aborts, etc.
+ ///
+ /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+ /// and UNAVAILABLE.
+ ABORTED = 10,
+
+ /// Operation was attempted past the valid range. E.g., seeking or reading
+ /// past end of file.
+ ///
+ /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
+ /// if the system state changes. For example, a 32-bit file system will
+ /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
+ /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
+ /// an offset past the current file size.
+ ///
+ /// There is a fair bit of overlap between FAILED_PRECONDITION and
+ /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
+ /// when it applies so that callers who are iterating through a space can
+ /// easily look for an OUT_OF_RANGE error to detect when they are done.
+ OUT_OF_RANGE = 11,
+
+ /// Operation is not implemented or not supported/enabled in this service.
+ UNIMPLEMENTED = 12,
+
+ /// Internal errors. Means some invariants expected by underlying System has
+ /// been broken. If you see one of these errors, Something is very broken.
+ INTERNAL = 13,
+
+ /// The service is currently unavailable. This is a most likely a transient
+ /// condition and may be corrected by retrying with a backoff.
+ ///
+ /// \warning Although data MIGHT not have been transmitted when this
+ /// status occurs, there is NOT A GUARANTEE that the server has not seen
+ /// anything. So in general it is unsafe to retry on this status code
+ /// if the call is non-idempotent.
+ ///
+ /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+ /// and UNAVAILABLE.
+ UNAVAILABLE = 14,
+
+ /// Unrecoverable data loss or corruption.
+ DATA_LOSS = 15,
+
+ /// Force users to include a default branch:
+ DO_NOT_USE = -1
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_STATUS_CODE_ENUM_H
diff --git a/include/grpcpp/impl/codegen/string_ref.h b/include/grpcpp/impl/codegen/string_ref.h
new file mode 100644
index 0000000000..5d55fc4180
--- /dev/null
+++ b/include/grpcpp/impl/codegen/string_ref.h
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_STRING_REF_H
+#define GRPCPP_IMPL_CODEGEN_STRING_REF_H
+
+#include <string.h>
+
+#include <algorithm>
+#include <iosfwd>
+#include <iostream>
+#include <iterator>
+
+#include <grpcpp/impl/codegen/config.h>
+
+namespace grpc {
+
+/// This class is a non owning reference to a string.
+///
+/// It should be a strict subset of the upcoming std::string_ref.
+///
+/// \see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
+///
+/// The constexpr is dropped or replaced with const for legacy compiler
+/// compatibility.
+class string_ref {
+ public:
+ /// types
+ typedef const char* const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ /// constants
+ const static size_t npos;
+
+ /// construct/copy.
+ string_ref() : data_(nullptr), length_(0) {}
+ string_ref(const string_ref& other)
+ : data_(other.data_), length_(other.length_) {}
+ string_ref& operator=(const string_ref& rhs) {
+ data_ = rhs.data_;
+ length_ = rhs.length_;
+ return *this;
+ }
+
+ string_ref(const char* s) : data_(s), length_(strlen(s)) {}
+ string_ref(const char* s, size_t l) : data_(s), length_(l) {}
+ string_ref(const grpc::string& s) : data_(s.data()), length_(s.length()) {}
+
+ /// iterators
+ const_iterator begin() const { return data_; }
+ const_iterator end() const { return data_ + length_; }
+ const_iterator cbegin() const { return data_; }
+ const_iterator cend() const { return data_ + length_; }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin());
+ }
+ const_reverse_iterator crbegin() const {
+ return const_reverse_iterator(end());
+ }
+ const_reverse_iterator crend() const {
+ return const_reverse_iterator(begin());
+ }
+
+ /// capacity
+ size_t size() const { return length_; }
+ size_t length() const { return length_; }
+ size_t max_size() const { return length_; }
+ bool empty() const { return length_ == 0; }
+
+ /// element access
+ const char* data() const { return data_; }
+
+ /// string operations
+ int compare(string_ref x) const {
+ size_t min_size = length_ < x.length_ ? length_ : x.length_;
+ int r = memcmp(data_, x.data_, min_size);
+ if (r < 0) return -1;
+ if (r > 0) return 1;
+ if (length_ < x.length_) return -1;
+ if (length_ > x.length_) return 1;
+ return 0;
+ }
+
+ bool starts_with(string_ref x) const {
+ return length_ >= x.length_ && (memcmp(data_, x.data_, x.length_) == 0);
+ }
+
+ bool ends_with(string_ref x) const {
+ return length_ >= x.length_ &&
+ (memcmp(data_ + (length_ - x.length_), x.data_, x.length_) == 0);
+ }
+
+ size_t find(string_ref s) const {
+ auto it = std::search(cbegin(), cend(), s.cbegin(), s.cend());
+ return it == cend() ? npos : std::distance(cbegin(), it);
+ }
+
+ size_t find(char c) const {
+ auto it = std::find(cbegin(), cend(), c);
+ return it == cend() ? npos : std::distance(cbegin(), it);
+ }
+
+ string_ref substr(size_t pos, size_t n = npos) const {
+ if (pos > length_) pos = length_;
+ if (n > (length_ - pos)) n = length_ - pos;
+ return string_ref(data_ + pos, n);
+ }
+
+ private:
+ const char* data_;
+ size_t length_;
+};
+
+/// Comparison operators
+inline bool operator==(string_ref x, string_ref y) { return x.compare(y) == 0; }
+inline bool operator!=(string_ref x, string_ref y) { return x.compare(y) != 0; }
+inline bool operator<(string_ref x, string_ref y) { return x.compare(y) < 0; }
+inline bool operator<=(string_ref x, string_ref y) { return x.compare(y) <= 0; }
+inline bool operator>(string_ref x, string_ref y) { return x.compare(y) > 0; }
+inline bool operator>=(string_ref x, string_ref y) { return x.compare(y) >= 0; }
+
+inline std::ostream& operator<<(std::ostream& out, const string_ref& string) {
+ return out << grpc::string(string.begin(), string.end());
+}
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_STRING_REF_H
diff --git a/include/grpcpp/impl/codegen/stub_options.h b/include/grpcpp/impl/codegen/stub_options.h
new file mode 100644
index 0000000000..a56695a8f8
--- /dev/null
+++ b/include/grpcpp/impl/codegen/stub_options.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_STUB_OPTIONS_H
+#define GRPCPP_IMPL_CODEGEN_STUB_OPTIONS_H
+
+namespace grpc {
+
+/// Useful interface for generated stubs
+class StubOptions {};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_STUB_OPTIONS_H
diff --git a/include/grpcpp/impl/codegen/sync_stream.h b/include/grpcpp/impl/codegen/sync_stream.h
new file mode 100644
index 0000000000..7152eaf41f
--- /dev/null
+++ b/include/grpcpp/impl/codegen/sync_stream.h
@@ -0,0 +1,934 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H
+#define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H
+
+#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/channel_interface.h>
+#include <grpcpp/impl/codegen/client_context.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/server_context.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+
+namespace grpc {
+
+namespace internal {
+/// Common interface for all synchronous client side streaming.
+class ClientStreamingInterface {
+ public:
+ virtual ~ClientStreamingInterface() {}
+
+ /// Block waiting until the stream finishes and a final status of the call is
+ /// available.
+ ///
+ /// It is appropriate to call this method when both:
+ /// * the calling code (client-side) has no more message to send
+ /// (this can be declared implicitly by calling this method, or
+ /// explicitly through an earlier call to <i>WritesDone</i> method of the
+ /// class in use, e.g. \a ClientWriterInterface::WritesDone or
+ /// \a ClientReaderWriterInterface::WritesDone).
+ /// * there are no more messages to be received from the server (which can
+ /// be known implicitly, or explicitly from an earlier call to \a
+ /// ReaderInterface::Read that returned "false").
+ ///
+ /// This function will return either:
+ /// - when all incoming messages have been read and the server has
+ /// returned status.
+ /// - when the server has returned a non-OK status.
+ /// - OR when the call failed for some reason and the library generated a
+ /// status.
+ ///
+ /// Return values:
+ /// - \a Status contains the status code, message and details for the call
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible trailing metadata sent from the server.
+ virtual Status Finish() = 0;
+};
+
+/// Common interface for all synchronous server side streaming.
+class ServerStreamingInterface {
+ public:
+ virtual ~ServerStreamingInterface() {}
+
+ /// Block to send initial metadata to client.
+ /// This call is optional, but if it is used, it cannot be used concurrently
+ /// with or after the \a Finish method.
+ ///
+ /// The initial metadata that will be sent to the client will be
+ /// taken from the \a ServerContext associated with the call.
+ virtual void SendInitialMetadata() = 0;
+};
+
+/// An interface that yields a sequence of messages of type \a R.
+template <class R>
+class ReaderInterface {
+ public:
+ virtual ~ReaderInterface() {}
+
+ /// Get an upper bound on the next message size available for reading on this
+ /// stream.
+ virtual bool NextMessageSize(uint32_t* sz) = 0;
+
+ /// Block to read a message and parse to \a msg. Returns \a true on success.
+ /// This is thread-safe with respect to \a Write or \WritesDone methods on
+ /// the same stream. It should not be called concurrently with another \a
+ /// Read on the same stream as the order of delivery will not be defined.
+ ///
+ /// \param[out] msg The read message.
+ ///
+ /// \return \a false when there will be no more incoming messages, either
+ /// because the other side has called \a WritesDone() or the stream has failed
+ /// (or been cancelled).
+ virtual bool Read(R* msg) = 0;
+};
+
+/// An interface that can be fed a sequence of messages of type \a W.
+template <class W>
+class WriterInterface {
+ public:
+ virtual ~WriterInterface() {}
+
+ /// Block to write \a msg to the stream with WriteOptions \a options.
+ /// This is thread-safe with respect to \a ReaderInterface::Read
+ ///
+ /// \param msg The message to be written to the stream.
+ /// \param options The WriteOptions affecting the write operation.
+ ///
+ /// \return \a true on success, \a false when the stream has been closed.
+ virtual bool Write(const W& msg, WriteOptions options) = 0;
+
+ /// Block to write \a msg to the stream with default write options.
+ /// This is thread-safe with respect to \a ReaderInterface::Read
+ ///
+ /// \param msg The message to be written to the stream.
+ ///
+ /// \return \a true on success, \a false when the stream has been closed.
+ inline bool Write(const W& msg) { return Write(msg, WriteOptions()); }
+
+ /// Write \a msg and coalesce it with the writing of trailing metadata, using
+ /// WriteOptions \a options.
+ ///
+ /// For client, WriteLast is equivalent of performing Write and WritesDone in
+ /// a single step. \a msg and trailing metadata are coalesced and sent on wire
+ /// by calling this function. For server, WriteLast buffers the \a msg.
+ /// The writing of \a msg is held until the service handler returns,
+ /// where \a msg and trailing metadata are coalesced and sent on wire.
+ /// Note that WriteLast can only buffer \a msg up to the flow control window
+ /// size. If \a msg size is larger than the window size, it will be sent on
+ /// wire without buffering.
+ ///
+ /// \param[in] msg The message to be written to the stream.
+ /// \param[in] options The WriteOptions to be used to write this message.
+ void WriteLast(const W& msg, WriteOptions options) {
+ Write(msg, options.set_last_message());
+ }
+};
+
+} // namespace internal
+
+/// Client-side interface for streaming reads of message of type \a R.
+template <class R>
+class ClientReaderInterface : public internal::ClientStreamingInterface,
+ public internal::ReaderInterface<R> {
+ public:
+ /// Block to wait for initial metadata from server. The received metadata
+ /// can only be accessed after this call returns. Should only be called before
+ /// the first read. Calling this method is optional, and if it is not called
+ /// the metadata will be available in ClientContext after the first read.
+ virtual void WaitForInitialMetadata() = 0;
+};
+
+namespace internal {
+template <class R>
+class ClientReaderFactory {
+ public:
+ template <class W>
+ static ClientReader<R>* Create(ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request) {
+ return new ClientReader<R>(channel, method, context, request);
+ }
+};
+} // namespace internal
+
+/// Synchronous (blocking) client-side API for doing server-streaming RPCs,
+/// where the stream of messages coming from the server has messages
+/// of type \a R.
+template <class R>
+class ClientReader final : public ClientReaderInterface<R> {
+ public:
+ /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
+ /// semantics.
+ ///
+ // Side effect:
+ /// Once complete, the initial metadata read from
+ /// the server will be accessable through the \a ClientContext used to
+ /// construct this object.
+ void WaitForInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
+ ops.RecvInitialMetadata(context_);
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops); /// status ignored
+ }
+
+ bool NextMessageSize(uint32_t* sz) override {
+ *sz = call_.max_receive_message_size();
+ return true;
+ }
+
+ /// See the \a ReaderInterface.Read method for semantics.
+ /// Side effect:
+ /// This also receives initial metadata from the server, if not
+ /// already received (if initial metadata is received, it can be then
+ /// accessed through the \a ClientContext associated with this call).
+ bool Read(R* msg) override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ ops;
+ if (!context_->initial_metadata_received_) {
+ ops.RecvInitialMetadata(context_);
+ }
+ ops.RecvMessage(msg);
+ call_.PerformOps(&ops);
+ return cq_.Pluck(&ops) && ops.got_message;
+ }
+
+ /// See the \a ClientStreamingInterface.Finish method for semantics.
+ ///
+ /// Side effect:
+ /// The \a ClientContext associated with this call is updated with
+ /// possible metadata received from the server.
+ Status Finish() override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientRecvStatus> ops;
+ Status status;
+ ops.ClientRecvStatus(context_, &status);
+ call_.PerformOps(&ops);
+ GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
+ return status;
+ }
+
+ private:
+ friend class internal::ClientReaderFactory<R>;
+ ClientContext* context_;
+ CompletionQueue cq_;
+ ::grpc::internal::Call call_;
+
+ /// Block to create a stream and write the initial metadata and \a request
+ /// out. Note that \a context will be used to fill in custom initial
+ /// metadata used to send to the server when starting the call.
+ template <class W>
+ ClientReader(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const W& request)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ // TODO(ctiller): don't assert
+ GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
+ ops.ClientSendClose();
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+};
+
+/// Client-side interface for streaming writes of message type \a W.
+template <class W>
+class ClientWriterInterface : public internal::ClientStreamingInterface,
+ public internal::WriterInterface<W> {
+ public:
+ /// Half close writing from the client. (signal that the stream of messages
+ /// coming from the client is complete).
+ /// Blocks until currently-pending writes are completed.
+ /// Thread safe with respect to \a ReaderInterface::Read operations only
+ ///
+ /// \return Whether the writes were successful.
+ virtual bool WritesDone() = 0;
+};
+
+namespace internal {
+template <class W>
+class ClientWriterFactory {
+ public:
+ template <class R>
+ static ClientWriter<W>* Create(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response) {
+ return new ClientWriter<W>(channel, method, context, response);
+ }
+};
+} // namespace internal
+
+/// Synchronous (blocking) client-side API for doing client-streaming RPCs,
+/// where the outgoing message stream coming from the client has messages of
+/// type \a W.
+template <class W>
+class ClientWriter : public ClientWriterInterface<W> {
+ public:
+ /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
+ /// semantics.
+ ///
+ // Side effect:
+ /// Once complete, the initial metadata read from the server will be
+ /// accessable through the \a ClientContext used to construct this object.
+ void WaitForInitialMetadata() {
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
+ ops.RecvInitialMetadata(context_);
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops); // status ignored
+ }
+
+ /// See the WriterInterface.Write(const W& msg, WriteOptions options) method
+ /// for semantics.
+ ///
+ /// Side effect:
+ /// Also sends initial metadata if not already sent (using the
+ /// \a ClientContext associated with this call).
+ using ::grpc::internal::WriterInterface<W>::Write;
+ bool Write(const W& msg, WriteOptions options) override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ ops;
+
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ ops.ClientSendClose();
+ }
+ if (context_->initial_metadata_corked_) {
+ ops.SendInitialMetadata(context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ context_->set_initial_metadata_corked(false);
+ }
+ if (!ops.SendMessage(msg, options).ok()) {
+ return false;
+ }
+
+ call_.PerformOps(&ops);
+ return cq_.Pluck(&ops);
+ }
+
+ bool WritesDone() override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
+ ops.ClientSendClose();
+ call_.PerformOps(&ops);
+ return cq_.Pluck(&ops);
+ }
+
+ /// See the ClientStreamingInterface.Finish method for semantics.
+ /// Side effects:
+ /// - Also receives initial metadata if not already received.
+ /// - Attempts to fill in the \a response parameter passed
+ /// to the constructor of this instance with the response
+ /// message from the server.
+ Status Finish() override {
+ Status status;
+ if (!context_->initial_metadata_received_) {
+ finish_ops_.RecvInitialMetadata(context_);
+ }
+ finish_ops_.ClientRecvStatus(context_, &status);
+ call_.PerformOps(&finish_ops_);
+ GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_));
+ return status;
+ }
+
+ private:
+ friend class internal::ClientWriterFactory<W>;
+
+ /// Block to create a stream (i.e. send request headers and other initial
+ /// metadata to the server). Note that \a context will be used to fill
+ /// in custom initial metadata. \a response will be filled in with the
+ /// single expected response message from the server upon a successful
+ /// call to the \a Finish method of this instance.
+ template <class R>
+ ClientWriter(ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, R* response)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ finish_ops_.RecvMessage(response);
+ finish_ops_.AllowNoMessage();
+
+ if (!context_->initial_metadata_corked_) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+ }
+
+ ClientContext* context_;
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpGenericRecvMessage,
+ ::grpc::internal::CallOpClientRecvStatus>
+ finish_ops_;
+ CompletionQueue cq_;
+ ::grpc::internal::Call call_;
+};
+
+/// Client-side interface for bi-directional streaming with
+/// client-to-server stream messages of type \a W and
+/// server-to-client stream messages of type \a R.
+template <class W, class R>
+class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
+ public internal::WriterInterface<W>,
+ public internal::ReaderInterface<R> {
+ public:
+ /// Block to wait for initial metadata from server. The received metadata
+ /// can only be accessed after this call returns. Should only be called before
+ /// the first read. Calling this method is optional, and if it is not called
+ /// the metadata will be available in ClientContext after the first read.
+ virtual void WaitForInitialMetadata() = 0;
+
+ /// Half close writing from the client. (signal that the stream of messages
+ /// coming from the clinet is complete).
+ /// Blocks until currently-pending writes are completed.
+ /// Thread-safe with respect to \a ReaderInterface::Read
+ ///
+ /// \return Whether the writes were successful.
+ virtual bool WritesDone() = 0;
+};
+
+namespace internal {
+template <class W, class R>
+class ClientReaderWriterFactory {
+ public:
+ static ClientReaderWriter<W, R>* Create(
+ ::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method, ClientContext* context) {
+ return new ClientReaderWriter<W, R>(channel, method, context);
+ }
+};
+} // namespace internal
+
+/// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
+/// where the outgoing message stream coming from the client has messages of
+/// type \a W, and the incoming messages stream coming from the server has
+/// messages of type \a R.
+template <class W, class R>
+class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
+ public:
+ /// Block waiting to read initial metadata from the server.
+ /// This call is optional, but if it is used, it cannot be used concurrently
+ /// with or after the \a Finish method.
+ ///
+ /// Once complete, the initial metadata read from the server will be
+ /// accessable through the \a ClientContext used to construct this object.
+ void WaitForInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
+ ops;
+ ops.RecvInitialMetadata(context_);
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops); // status ignored
+ }
+
+ bool NextMessageSize(uint32_t* sz) override {
+ *sz = call_.max_receive_message_size();
+ return true;
+ }
+
+ /// See the \a ReaderInterface.Read method for semantics.
+ /// Side effect:
+ /// Also receives initial metadata if not already received (updates the \a
+ /// ClientContext associated with this call in that case).
+ bool Read(R* msg) override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpRecvMessage<R>>
+ ops;
+ if (!context_->initial_metadata_received_) {
+ ops.RecvInitialMetadata(context_);
+ }
+ ops.RecvMessage(msg);
+ call_.PerformOps(&ops);
+ return cq_.Pluck(&ops) && ops.got_message;
+ }
+
+ /// See the \a WriterInterface.Write method for semantics.
+ ///
+ /// Side effect:
+ /// Also sends initial metadata if not already sent (using the
+ /// \a ClientContext associated with this call to fill in values).
+ using ::grpc::internal::WriterInterface<W>::Write;
+ bool Write(const W& msg, WriteOptions options) override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
+ ::grpc::internal::CallOpSendMessage,
+ ::grpc::internal::CallOpClientSendClose>
+ ops;
+
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ ops.ClientSendClose();
+ }
+ if (context_->initial_metadata_corked_) {
+ ops.SendInitialMetadata(context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ context_->set_initial_metadata_corked(false);
+ }
+ if (!ops.SendMessage(msg, options).ok()) {
+ return false;
+ }
+
+ call_.PerformOps(&ops);
+ return cq_.Pluck(&ops);
+ }
+
+ bool WritesDone() override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpClientSendClose> ops;
+ ops.ClientSendClose();
+ call_.PerformOps(&ops);
+ return cq_.Pluck(&ops);
+ }
+
+ /// See the ClientStreamingInterface.Finish method for semantics.
+ ///
+ /// Side effect:
+ /// - the \a ClientContext associated with this call is updated with
+ /// possible trailing metadata sent from the server.
+ Status Finish() override {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
+ ::grpc::internal::CallOpClientRecvStatus>
+ ops;
+ if (!context_->initial_metadata_received_) {
+ ops.RecvInitialMetadata(context_);
+ }
+ Status status;
+ ops.ClientRecvStatus(context_, &status);
+ call_.PerformOps(&ops);
+ GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
+ return status;
+ }
+
+ private:
+ friend class internal::ClientReaderWriterFactory<W, R>;
+
+ ClientContext* context_;
+ CompletionQueue cq_;
+ ::grpc::internal::Call call_;
+
+ /// Block to create a stream and write the initial metadata and \a request
+ /// out. Note that \a context will be used to fill in custom initial metadata
+ /// used to send to the server when starting the call.
+ ClientReaderWriter(::grpc::ChannelInterface* channel,
+ const ::grpc::internal::RpcMethod& method,
+ ClientContext* context)
+ : context_(context),
+ cq_(grpc_completion_queue_attributes{
+ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK,
+ GRPC_CQ_DEFAULT_POLLING}), // Pluckable cq
+ call_(channel->CreateCall(method, context, &cq_)) {
+ if (!context_->initial_metadata_corked_) {
+ ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
+ ops;
+ ops.SendInitialMetadata(context->send_initial_metadata_,
+ context->initial_metadata_flags());
+ call_.PerformOps(&ops);
+ cq_.Pluck(&ops);
+ }
+ }
+};
+
+/// Server-side interface for streaming reads of message of type \a R.
+template <class R>
+class ServerReaderInterface : public internal::ServerStreamingInterface,
+ public internal::ReaderInterface<R> {};
+
+/// Synchronous (blocking) server-side API for doing client-streaming RPCs,
+/// where the incoming message stream coming from the client has messages of
+/// type \a R.
+template <class R>
+class ServerReader final : public ServerReaderInterface<R> {
+ public:
+ /// See the \a ServerStreamingInterface.SendInitialMetadata method
+ /// for semantics. Note that initial metadata will be affected by the
+ /// \a ServerContext associated with this call.
+ void SendInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
+ ops.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ops.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_->PerformOps(&ops);
+ call_->cq()->Pluck(&ops);
+ }
+
+ bool NextMessageSize(uint32_t* sz) override {
+ *sz = call_->max_receive_message_size();
+ return true;
+ }
+
+ bool Read(R* msg) override {
+ internal::CallOpSet<internal::CallOpRecvMessage<R>> ops;
+ ops.RecvMessage(msg);
+ call_->PerformOps(&ops);
+ return call_->cq()->Pluck(&ops) && ops.got_message;
+ }
+
+ private:
+ internal::Call* const call_;
+ ServerContext* const ctx_;
+
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ClientStreamingHandler;
+
+ ServerReader(internal::Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
+};
+
+/// Server-side interface for streaming writes of message of type \a W.
+template <class W>
+class ServerWriterInterface : public internal::ServerStreamingInterface,
+ public internal::WriterInterface<W> {};
+
+/// Synchronous (blocking) server-side API for doing for doing a
+/// server-streaming RPCs, where the outgoing message stream coming from the
+/// server has messages of type \a W.
+template <class W>
+class ServerWriter final : public ServerWriterInterface<W> {
+ public:
+ /// See the \a ServerStreamingInterface.SendInitialMetadata method
+ /// for semantics.
+ /// Note that initial metadata will be affected by the
+ /// \a ServerContext associated with this call.
+ void SendInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ internal::CallOpSet<internal::CallOpSendInitialMetadata> ops;
+ ops.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ops.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_->PerformOps(&ops);
+ call_->cq()->Pluck(&ops);
+ }
+
+ /// See the \a WriterInterface.Write method for semantics.
+ ///
+ /// Side effect:
+ /// Also sends initial metadata if not already sent (using the
+ /// \a ClientContext associated with this call to fill in values).
+ using internal::WriterInterface<W>::Write;
+ bool Write(const W& msg, WriteOptions options) override {
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ }
+
+ if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) {
+ return false;
+ }
+ if (!ctx_->sent_initial_metadata_) {
+ ctx_->pending_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ call_->PerformOps(&ctx_->pending_ops_);
+ // if this is the last message we defer the pluck until AFTER we start
+ // the trailing md op. This prevents hangs. See
+ // https://github.com/grpc/grpc/issues/11546
+ if (options.is_last_message()) {
+ ctx_->has_pending_ops_ = true;
+ return true;
+ }
+ ctx_->has_pending_ops_ = false;
+ return call_->cq()->Pluck(&ctx_->pending_ops_);
+ }
+
+ private:
+ internal::Call* const call_;
+ ServerContext* const ctx_;
+
+ template <class ServiceType, class RequestType, class ResponseType>
+ friend class internal::ServerStreamingHandler;
+
+ ServerWriter(internal::Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
+};
+
+/// Server-side interface for bi-directional streaming.
+template <class W, class R>
+class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
+ public internal::WriterInterface<W>,
+ public internal::ReaderInterface<R> {};
+
+/// Actual implementation of bi-directional streaming
+namespace internal {
+template <class W, class R>
+class ServerReaderWriterBody final {
+ public:
+ ServerReaderWriterBody(Call* call, ServerContext* ctx)
+ : call_(call), ctx_(ctx) {}
+
+ void SendInitialMetadata() {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+ CallOpSet<CallOpSendInitialMetadata> ops;
+ ops.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ops.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ call_->PerformOps(&ops);
+ call_->cq()->Pluck(&ops);
+ }
+
+ bool NextMessageSize(uint32_t* sz) {
+ *sz = call_->max_receive_message_size();
+ return true;
+ }
+
+ bool Read(R* msg) {
+ CallOpSet<CallOpRecvMessage<R>> ops;
+ ops.RecvMessage(msg);
+ call_->PerformOps(&ops);
+ return call_->cq()->Pluck(&ops) && ops.got_message;
+ }
+
+ bool Write(const W& msg, WriteOptions options) {
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ }
+ if (!ctx_->pending_ops_.SendMessage(msg, options).ok()) {
+ return false;
+ }
+ if (!ctx_->sent_initial_metadata_) {
+ ctx_->pending_ops_.SendInitialMetadata(ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ call_->PerformOps(&ctx_->pending_ops_);
+ // if this is the last message we defer the pluck until AFTER we start
+ // the trailing md op. This prevents hangs. See
+ // https://github.com/grpc/grpc/issues/11546
+ if (options.is_last_message()) {
+ ctx_->has_pending_ops_ = true;
+ return true;
+ }
+ ctx_->has_pending_ops_ = false;
+ return call_->cq()->Pluck(&ctx_->pending_ops_);
+ }
+
+ private:
+ Call* const call_;
+ ServerContext* const ctx_;
+};
+
+} // namespace internal
+
+/// Synchronous (blocking) server-side API for a bidirectional
+/// streaming call, where the incoming message stream coming from the client has
+/// messages of type \a R, and the outgoing message streaming coming from
+/// the server has messages of type \a W.
+template <class W, class R>
+class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
+ public:
+ /// See the \a ServerStreamingInterface.SendInitialMetadata method
+ /// for semantics. Note that initial metadata will be affected by the
+ /// \a ServerContext associated with this call.
+ void SendInitialMetadata() override { body_.SendInitialMetadata(); }
+
+ bool NextMessageSize(uint32_t* sz) override {
+ return body_.NextMessageSize(sz);
+ }
+
+ bool Read(R* msg) override { return body_.Read(msg); }
+
+ /// See the \a WriterInterface.Write(const W& msg, WriteOptions options)
+ /// method for semantics.
+ /// Side effect:
+ /// Also sends initial metadata if not already sent (using the \a
+ /// ServerContext associated with this call).
+ using internal::WriterInterface<W>::Write;
+ bool Write(const W& msg, WriteOptions options) override {
+ return body_.Write(msg, options);
+ }
+
+ private:
+ internal::ServerReaderWriterBody<W, R> body_;
+
+ friend class internal::TemplatedBidiStreamingHandler<ServerReaderWriter<W, R>,
+ false>;
+ ServerReaderWriter(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx) {}
+};
+
+/// A class to represent a flow-controlled unary call. This is something
+/// of a hybrid between conventional unary and streaming. This is invoked
+/// through a unary call on the client side, but the server responds to it
+/// as though it were a single-ping-pong streaming call. The server can use
+/// the \a NextMessageSize method to determine an upper-bound on the size of
+/// the message. A key difference relative to streaming: ServerUnaryStreamer
+/// must have exactly 1 Read and exactly 1 Write, in that order, to function
+/// correctly. Otherwise, the RPC is in error.
+template <class RequestType, class ResponseType>
+class ServerUnaryStreamer final
+ : public ServerReaderWriterInterface<ResponseType, RequestType> {
+ public:
+ /// Block to send initial metadata to client.
+ /// Implicit input parameter:
+ /// - the \a ServerContext associated with this call will be used for
+ /// sending initial metadata.
+ void SendInitialMetadata() override { body_.SendInitialMetadata(); }
+
+ /// Get an upper bound on the request message size from the client.
+ bool NextMessageSize(uint32_t* sz) override {
+ return body_.NextMessageSize(sz);
+ }
+
+ /// Read a message of type \a R into \a msg. Completion will be notified by \a
+ /// tag on the associated completion queue.
+ /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
+ /// should not be called concurrently with other streaming APIs
+ /// on the same stream. It is not meaningful to call it concurrently
+ /// with another \a ReaderInterface::Read on the same stream since reads on
+ /// the same stream are delivered in order.
+ ///
+ /// \param[out] msg Where to eventually store the read message.
+ /// \param[in] tag The tag identifying the operation.
+ bool Read(RequestType* request) override {
+ if (read_done_) {
+ return false;
+ }
+ read_done_ = true;
+ return body_.Read(request);
+ }
+
+ /// Block to write \a msg to the stream with WriteOptions \a options.
+ /// This is thread-safe with respect to \a ReaderInterface::Read
+ ///
+ /// \param msg The message to be written to the stream.
+ /// \param options The WriteOptions affecting the write operation.
+ ///
+ /// \return \a true on success, \a false when the stream has been closed.
+ using internal::WriterInterface<ResponseType>::Write;
+ bool Write(const ResponseType& response, WriteOptions options) override {
+ if (write_done_ || !read_done_) {
+ return false;
+ }
+ write_done_ = true;
+ return body_.Write(response, options);
+ }
+
+ private:
+ internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
+ bool read_done_;
+ bool write_done_;
+
+ friend class internal::TemplatedBidiStreamingHandler<
+ ServerUnaryStreamer<RequestType, ResponseType>, true>;
+ ServerUnaryStreamer(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx), read_done_(false), write_done_(false) {}
+};
+
+/// A class to represent a flow-controlled server-side streaming call.
+/// This is something of a hybrid between server-side and bidi streaming.
+/// This is invoked through a server-side streaming call on the client side,
+/// but the server responds to it as though it were a bidi streaming call that
+/// must first have exactly 1 Read and then any number of Writes.
+template <class RequestType, class ResponseType>
+class ServerSplitStreamer final
+ : public ServerReaderWriterInterface<ResponseType, RequestType> {
+ public:
+ /// Block to send initial metadata to client.
+ /// Implicit input parameter:
+ /// - the \a ServerContext associated with this call will be used for
+ /// sending initial metadata.
+ void SendInitialMetadata() override { body_.SendInitialMetadata(); }
+
+ /// Get an upper bound on the request message size from the client.
+ bool NextMessageSize(uint32_t* sz) override {
+ return body_.NextMessageSize(sz);
+ }
+
+ /// Read a message of type \a R into \a msg. Completion will be notified by \a
+ /// tag on the associated completion queue.
+ /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
+ /// should not be called concurrently with other streaming APIs
+ /// on the same stream. It is not meaningful to call it concurrently
+ /// with another \a ReaderInterface::Read on the same stream since reads on
+ /// the same stream are delivered in order.
+ ///
+ /// \param[out] msg Where to eventually store the read message.
+ /// \param[in] tag The tag identifying the operation.
+ bool Read(RequestType* request) override {
+ if (read_done_) {
+ return false;
+ }
+ read_done_ = true;
+ return body_.Read(request);
+ }
+
+ /// Block to write \a msg to the stream with WriteOptions \a options.
+ /// This is thread-safe with respect to \a ReaderInterface::Read
+ ///
+ /// \param msg The message to be written to the stream.
+ /// \param options The WriteOptions affecting the write operation.
+ ///
+ /// \return \a true on success, \a false when the stream has been closed.
+ using internal::WriterInterface<ResponseType>::Write;
+ bool Write(const ResponseType& response, WriteOptions options) override {
+ return read_done_ && body_.Write(response, options);
+ }
+
+ private:
+ internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
+ bool read_done_;
+
+ friend class internal::TemplatedBidiStreamingHandler<
+ ServerSplitStreamer<RequestType, ResponseType>, false>;
+ ServerSplitStreamer(internal::Call* call, ServerContext* ctx)
+ : body_(call, ctx), read_done_(false) {}
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H
diff --git a/include/grpcpp/impl/codegen/time.h b/include/grpcpp/impl/codegen/time.h
new file mode 100644
index 0000000000..c32f2544fa
--- /dev/null
+++ b/include/grpcpp/impl/codegen/time.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_CODEGEN_TIME_H
+#define GRPCPP_IMPL_CODEGEN_TIME_H
+
+#include <chrono>
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpcpp/impl/codegen/config.h>
+
+namespace grpc {
+
+/** If you are trying to use CompletionQueue::AsyncNext with a time class that
+ isn't either gpr_timespec or std::chrono::system_clock::time_point, you
+ will most likely be looking at this comment as your compiler will have
+ fired an error below. In order to fix this issue, you have two potential
+ solutions:
+
+ 1. Use gpr_timespec or std::chrono::system_clock::time_point instead
+ 2. Specialize the TimePoint class with whichever time class that you
+ want to use here. See below for two examples of how to do this.
+ */
+template <typename T>
+class TimePoint {
+ public:
+ TimePoint(const T& time) { you_need_a_specialization_of_TimePoint(); }
+ gpr_timespec raw_time() {
+ gpr_timespec t;
+ return t;
+ }
+
+ private:
+ void you_need_a_specialization_of_TimePoint();
+};
+
+template <>
+class TimePoint<gpr_timespec> {
+ public:
+ TimePoint(const gpr_timespec& time) : time_(time) {}
+ gpr_timespec raw_time() { return time_; }
+
+ private:
+ gpr_timespec time_;
+};
+
+} // namespace grpc
+
+namespace grpc {
+
+// from and to should be absolute time.
+void Timepoint2Timespec(const std::chrono::system_clock::time_point& from,
+ gpr_timespec* to);
+void TimepointHR2Timespec(
+ const std::chrono::high_resolution_clock::time_point& from,
+ gpr_timespec* to);
+
+std::chrono::system_clock::time_point Timespec2Timepoint(gpr_timespec t);
+
+template <>
+class TimePoint<std::chrono::system_clock::time_point> {
+ public:
+ TimePoint(const std::chrono::system_clock::time_point& time) {
+ Timepoint2Timespec(time, &time_);
+ }
+ gpr_timespec raw_time() const { return time_; }
+
+ private:
+ gpr_timespec time_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_CODEGEN_TIME_H
diff --git a/include/grpcpp/impl/grpc_library.h b/include/grpcpp/impl/grpc_library.h
new file mode 100644
index 0000000000..d1f3ff1297
--- /dev/null
+++ b/include/grpcpp/impl/grpc_library.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_GRPC_LIBRARY_H
+#define GRPCPP_IMPL_GRPC_LIBRARY_H
+
+#include <iostream>
+
+#include <grpc/grpc.h>
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/core_codegen.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+
+namespace grpc {
+
+namespace internal {
+class GrpcLibrary final : public GrpcLibraryInterface {
+ public:
+ void init() override { grpc_init(); }
+ void shutdown() override { grpc_shutdown(); }
+};
+
+static GrpcLibrary g_gli;
+static CoreCodegen g_core_codegen;
+
+/// Instantiating this class ensures the proper initialization of gRPC.
+class GrpcLibraryInitializer final {
+ public:
+ GrpcLibraryInitializer() {
+ if (grpc::g_glip == nullptr) {
+ grpc::g_glip = &g_gli;
+ }
+ if (grpc::g_core_codegen_interface == nullptr) {
+ grpc::g_core_codegen_interface = &g_core_codegen;
+ }
+ }
+
+ /// A no-op method to force the linker to reference this class, which will
+ /// take care of initializing and shutting down the gRPC runtime.
+ int summon() { return 0; }
+};
+
+} // namespace internal
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_GRPC_LIBRARY_H
diff --git a/include/grpcpp/impl/method_handler_impl.h b/include/grpcpp/impl/method_handler_impl.h
new file mode 100644
index 0000000000..7f3be6428b
--- /dev/null
+++ b/include/grpcpp/impl/method_handler_impl.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_METHOD_HANDLER_IMPL_H
+#define GRPCPP_IMPL_METHOD_HANDLER_IMPL_H
+
+#include <grpcpp/impl/codegen/method_handler_impl.h>
+
+#endif // GRPCPP_IMPL_METHOD_HANDLER_IMPL_H
diff --git a/include/grpcpp/impl/rpc_method.h b/include/grpcpp/impl/rpc_method.h
new file mode 100644
index 0000000000..5da7041671
--- /dev/null
+++ b/include/grpcpp/impl/rpc_method.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_RPC_METHOD_H
+#define GRPCPP_IMPL_RPC_METHOD_H
+
+#include <grpcpp/impl/codegen/rpc_method.h>
+
+#endif // GRPCPP_IMPL_RPC_METHOD_H
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h b/include/grpcpp/impl/rpc_service_method.h
index 0a2edb0e3d..ef70a3a100 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h
+++ b/include/grpcpp/impl/rpc_service_method.h
@@ -16,14 +16,9 @@
*
*/
-#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H
-#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H
+#ifndef GRPCPP_IMPL_RPC_SERVICE_METHOD_H
+#define GRPCPP_IMPL_RPC_SERVICE_METHOD_H
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include <grpcpp/impl/codegen/rpc_service_method.h>
-/** Returns a load balancing factory for the glb policy, which tries to connect
- * to a load balancing server to decide the next successfully connected
- * subchannel to pick. */
-grpc_lb_policy_factory* grpc_glb_lb_factory_create();
-
-#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_H */
+#endif // GRPCPP_IMPL_RPC_SERVICE_METHOD_H
diff --git a/include/grpcpp/impl/serialization_traits.h b/include/grpcpp/impl/serialization_traits.h
new file mode 100644
index 0000000000..95194fbd89
--- /dev/null
+++ b/include/grpcpp/impl/serialization_traits.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_SERIALIZATION_TRAITS_H
+#define GRPCPP_IMPL_SERIALIZATION_TRAITS_H
+
+#include <grpcpp/impl/codegen/serialization_traits.h>
+
+#endif // GRPCPP_IMPL_SERIALIZATION_TRAITS_H
diff --git a/include/grpcpp/impl/server_builder_option.h b/include/grpcpp/impl/server_builder_option.h
new file mode 100644
index 0000000000..c7b7801dab
--- /dev/null
+++ b/include/grpcpp/impl/server_builder_option.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_SERVER_BUILDER_OPTION_H
+#define GRPCPP_IMPL_SERVER_BUILDER_OPTION_H
+
+#include <map>
+#include <memory>
+
+#include <grpcpp/impl/server_builder_plugin.h>
+#include <grpcpp/support/channel_arguments.h>
+
+namespace grpc {
+
+/// Interface to pass an option to a \a ServerBuilder.
+class ServerBuilderOption {
+ public:
+ virtual ~ServerBuilderOption() {}
+ /// Alter the \a ChannelArguments used to create the gRPC server.
+ virtual void UpdateArguments(ChannelArguments* args) = 0;
+ /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder.
+ virtual void UpdatePlugins(
+ std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) = 0;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_SERVER_BUILDER_OPTION_H
diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h
new file mode 100644
index 0000000000..d73511e465
--- /dev/null
+++ b/include/grpcpp/impl/server_builder_plugin.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_SERVER_BUILDER_PLUGIN_H
+#define GRPCPP_IMPL_SERVER_BUILDER_PLUGIN_H
+
+#include <memory>
+
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+
+class ServerBuilder;
+class ServerInitializer;
+class ChannelArguments;
+
+/// This interface is meant for internal usage only. Implementations of this
+/// interface should add themselves to a \a ServerBuilder instance through the
+/// \a InternalAddPluginFactory method.
+class ServerBuilderPlugin {
+ public:
+ virtual ~ServerBuilderPlugin() {}
+ virtual grpc::string name() = 0;
+
+ /// UpdateServerBuilder will be called at the beginning of
+ /// \a ServerBuilder::BuildAndStart().
+ virtual void UpdateServerBuilder(ServerBuilder* builder) {}
+
+ /// InitServer will be called in ServerBuilder::BuildAndStart(), after the
+ /// Server instance is created.
+ virtual void InitServer(ServerInitializer* si) = 0;
+
+ /// Finish will be called at the end of ServerBuilder::BuildAndStart().
+ virtual void Finish(ServerInitializer* si) = 0;
+
+ /// ChangeArguments is an interface that can be used in
+ /// ServerBuilderOption::UpdatePlugins
+ virtual void ChangeArguments(const grpc::string& name, void* value) = 0;
+
+ /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(),
+ /// before the Server instance is created.
+ virtual void UpdateChannelArguments(ChannelArguments* args) {}
+
+ virtual bool has_sync_methods() const { return false; }
+ virtual bool has_async_methods() const { return false; }
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_SERVER_BUILDER_PLUGIN_H
diff --git a/include/grpcpp/impl/server_initializer.h b/include/grpcpp/impl/server_initializer.h
new file mode 100644
index 0000000000..f949fabfe6
--- /dev/null
+++ b/include/grpcpp/impl/server_initializer.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_SERVER_INITIALIZER_H
+#define GRPCPP_IMPL_SERVER_INITIALIZER_H
+
+#include <memory>
+#include <vector>
+
+#include <grpcpp/server.h>
+
+namespace grpc {
+
+class Server;
+class Service;
+
+class ServerInitializer {
+ public:
+ ServerInitializer(Server* server) : server_(server) {}
+
+ bool RegisterService(std::shared_ptr<Service> service) {
+ if (!server_->RegisterService(nullptr, service.get())) {
+ return false;
+ }
+ default_services_.push_back(service);
+ return true;
+ }
+
+ const std::vector<grpc::string>* GetServiceList() {
+ return &server_->services_;
+ }
+
+ private:
+ Server* server_;
+ std::vector<std::shared_ptr<Service> > default_services_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_IMPL_SERVER_INITIALIZER_H
diff --git a/include/grpcpp/impl/service_type.h b/include/grpcpp/impl/service_type.h
new file mode 100644
index 0000000000..250bc8cd56
--- /dev/null
+++ b/include/grpcpp/impl/service_type.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_SERVICE_TYPE_H
+#define GRPCPP_IMPL_SERVICE_TYPE_H
+
+#include <grpcpp/impl/codegen/service_type.h>
+
+#endif // GRPCPP_IMPL_SERVICE_TYPE_H
diff --git a/src/core/lib/gpr/thd_internal.h b/include/grpcpp/impl/sync_cxx11.h
index 692c00c8e1..76dcfe391c 100644
--- a/src/core/lib/gpr/thd_internal.h
+++ b/include/grpcpp/impl/sync_cxx11.h
@@ -16,15 +16,9 @@
*
*/
-#ifndef GRPC_CORE_LIB_GPR_THD_INTERNAL_H
-#define GRPC_CORE_LIB_GPR_THD_INTERNAL_H
+#ifndef GRPCPP_IMPL_SYNC_CXX11_H
+#define GRPCPP_IMPL_SYNC_CXX11_H
-#include <grpc/support/time.h>
+#include <grpcpp/impl/codegen/sync_cxx11.h>
-/* Internal interfaces between modules within the gpr support library. */
-void gpr_thd_init();
-
-/* Wait for all outstanding threads to finish, up to deadline */
-int gpr_await_threads(gpr_timespec deadline);
-
-#endif /* GRPC_CORE_LIB_GPR_THD_INTERNAL_H */
+#endif // GRPCPP_IMPL_SYNC_CXX11_H
diff --git a/include/grpcpp/impl/sync_no_cxx11.h b/include/grpcpp/impl/sync_no_cxx11.h
new file mode 100644
index 0000000000..cc2d4f104c
--- /dev/null
+++ b/include/grpcpp/impl/sync_no_cxx11.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_IMPL_SYNC_NO_CXX11_H
+#define GRPCPP_IMPL_SYNC_NO_CXX11_H
+
+#include <grpcpp/impl/codegen/sync_no_cxx11.h>
+
+#endif // GRPCPP_IMPL_SYNC_NO_CXX11_H
diff --git a/include/grpcpp/resource_quota.h b/include/grpcpp/resource_quota.h
new file mode 100644
index 0000000000..554437a40d
--- /dev/null
+++ b/include/grpcpp/resource_quota.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_RESOURCE_QUOTA_H
+#define GRPCPP_RESOURCE_QUOTA_H
+
+struct grpc_resource_quota;
+
+#include <grpcpp/impl/codegen/config.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+
+namespace grpc {
+
+/// ResourceQuota represents a bound on memory usage by the gRPC library.
+/// A ResourceQuota can be attached to a server (via \a ServerBuilder),
+/// or a client channel (via \a ChannelArguments).
+/// gRPC will attempt to keep memory used by all attached entities
+/// below the ResourceQuota bound.
+class ResourceQuota final : private GrpcLibraryCodegen {
+ public:
+ /// \param name - a unique name for this ResourceQuota.
+ explicit ResourceQuota(const grpc::string& name);
+ ResourceQuota();
+ ~ResourceQuota();
+
+ /// Resize this \a ResourceQuota to a new size. If \a new_size is smaller
+ /// than the current size of the pool, memory usage will be monotonically
+ /// decreased until it falls under \a new_size.
+ /// No time bound is given for this to occur however.
+ ResourceQuota& Resize(size_t new_size);
+
+ grpc_resource_quota* c_resource_quota() const { return impl_; }
+
+ private:
+ ResourceQuota(const ResourceQuota& rhs);
+ ResourceQuota& operator=(const ResourceQuota& rhs);
+
+ grpc_resource_quota* const impl_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_RESOURCE_QUOTA_H
diff --git a/include/grpcpp/security/auth_context.h b/include/grpcpp/security/auth_context.h
new file mode 100644
index 0000000000..7a6f2cb718
--- /dev/null
+++ b/include/grpcpp/security/auth_context.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SECURITY_AUTH_CONTEXT_H
+#define GRPCPP_SECURITY_AUTH_CONTEXT_H
+
+#include <grpcpp/impl/codegen/security/auth_context.h>
+
+#endif // GRPCPP_SECURITY_AUTH_CONTEXT_H
diff --git a/include/grpcpp/security/auth_metadata_processor.h b/include/grpcpp/security/auth_metadata_processor.h
new file mode 100644
index 0000000000..30e24c9f0b
--- /dev/null
+++ b/include/grpcpp/security/auth_metadata_processor.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H
+#define GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H
+
+#include <map>
+
+#include <grpcpp/security/auth_context.h>
+#include <grpcpp/support/status.h>
+#include <grpcpp/support/string_ref.h>
+
+namespace grpc {
+
+/// Interface allowing custom server-side authorization based on credentials
+/// encoded in metadata. Objects of this type can be passed to
+/// \a ServerCredentials::SetAuthMetadataProcessor().
+class AuthMetadataProcessor {
+ public:
+ typedef std::multimap<grpc::string_ref, grpc::string_ref> InputMetadata;
+ typedef std::multimap<grpc::string, grpc::string> OutputMetadata;
+
+ virtual ~AuthMetadataProcessor() {}
+
+ /// If this method returns true, the \a Process function will be scheduled in
+ /// a different thread from the one processing the call.
+ virtual bool IsBlocking() const { return true; }
+
+ /// context is read/write: it contains the properties of the channel peer and
+ /// it is the job of the Process method to augment it with properties derived
+ /// from the passed-in auth_metadata.
+ /// consumed_auth_metadata needs to be filled with metadata that has been
+ /// consumed by the processor and will be removed from the call.
+ /// response_metadata is the metadata that will be sent as part of the
+ /// response.
+ /// If the return value is not Status::OK, the rpc call will be aborted with
+ /// the error code and error message sent back to the client.
+ virtual Status Process(const InputMetadata& auth_metadata,
+ AuthContext* context,
+ OutputMetadata* consumed_auth_metadata,
+ OutputMetadata* response_metadata) = 0;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_SECURITY_AUTH_METADATA_PROCESSOR_H
diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h
new file mode 100644
index 0000000000..837a0e43ed
--- /dev/null
+++ b/include/grpcpp/security/credentials.h
@@ -0,0 +1,224 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SECURITY_CREDENTIALS_H
+#define GRPCPP_SECURITY_CREDENTIALS_H
+
+#include <map>
+#include <memory>
+
+#include <grpcpp/impl/codegen/grpc_library.h>
+#include <grpcpp/security/auth_context.h>
+#include <grpcpp/support/status.h>
+#include <grpcpp/support/string_ref.h>
+
+struct grpc_call;
+
+namespace grpc {
+class ChannelArguments;
+class Channel;
+class SecureChannelCredentials;
+class CallCredentials;
+class SecureCallCredentials;
+
+/// A channel credentials object encapsulates all the state needed by a client
+/// to authenticate with a server for a given channel.
+/// It can make various assertions, e.g., about the client’s identity, role
+/// for all the calls on that channel.
+///
+/// \see https://grpc.io/docs/guides/auth.html
+class ChannelCredentials : private GrpcLibraryCodegen {
+ public:
+ ChannelCredentials();
+ ~ChannelCredentials();
+
+ protected:
+ friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+ const std::shared_ptr<ChannelCredentials>& channel_creds,
+ const std::shared_ptr<CallCredentials>& call_creds);
+
+ virtual SecureChannelCredentials* AsSecureCredentials() = 0;
+
+ private:
+ friend std::shared_ptr<Channel> CreateCustomChannel(
+ const grpc::string& target,
+ const std::shared_ptr<ChannelCredentials>& creds,
+ const ChannelArguments& args);
+
+ virtual std::shared_ptr<Channel> CreateChannel(
+ const grpc::string& target, const ChannelArguments& args) = 0;
+};
+
+/// A call credentials object encapsulates the state needed by a client to
+/// authenticate with a server for a given call on a channel.
+///
+/// \see https://grpc.io/docs/guides/auth.html
+class CallCredentials : private GrpcLibraryCodegen {
+ public:
+ CallCredentials();
+ ~CallCredentials();
+
+ /// Apply this instance's credentials to \a call.
+ virtual bool ApplyToCall(grpc_call* call) = 0;
+
+ protected:
+ friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+ const std::shared_ptr<ChannelCredentials>& channel_creds,
+ const std::shared_ptr<CallCredentials>& call_creds);
+
+ friend std::shared_ptr<CallCredentials> CompositeCallCredentials(
+ const std::shared_ptr<CallCredentials>& creds1,
+ const std::shared_ptr<CallCredentials>& creds2);
+
+ virtual SecureCallCredentials* AsSecureCredentials() = 0;
+};
+
+/// Options used to build SslCredentials.
+struct SslCredentialsOptions {
+ /// The buffer containing the PEM encoding of the server root certificates. If
+ /// this parameter is empty, the default roots will be used. The default
+ /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH
+ /// environment variable pointing to a file on the file system containing the
+ /// roots.
+ grpc::string pem_root_certs;
+
+ /// The buffer containing the PEM encoding of the client's private key. This
+ /// parameter can be empty if the client does not have a private key.
+ grpc::string pem_private_key;
+
+ /// The buffer containing the PEM encoding of the client's certificate chain.
+ /// This parameter can be empty if the client does not have a certificate
+ /// chain.
+ grpc::string pem_cert_chain;
+};
+
+// Factories for building different types of Credentials The functions may
+// return empty shared_ptr when credentials cannot be created. If a
+// Credentials pointer is returned, it can still be invalid when used to create
+// a channel. A lame channel will be created then and all rpcs will fail on it.
+
+/// Builds credentials with reasonable defaults.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
+std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials();
+
+/// Builds SSL Credentials given SSL specific options
+std::shared_ptr<ChannelCredentials> SslCredentials(
+ const SslCredentialsOptions& options);
+
+/// Builds credentials for use when running in GCE
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
+std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials();
+
+/// Constant for maximum auth token lifetime.
+constexpr long kMaxAuthTokenLifetimeSecs = 3600;
+
+/// Builds Service Account JWT Access credentials.
+/// json_key is the JSON key string containing the client's private key.
+/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
+/// (JWT) created with this credentials. It should not exceed
+/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value.
+std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
+ const grpc::string& json_key,
+ long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs);
+
+/// Builds refresh token credentials.
+/// json_refresh_token is the JSON string containing the refresh token along
+/// with a client_id and client_secret.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
+std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
+ const grpc::string& json_refresh_token);
+
+/// Builds access token credentials.
+/// access_token is an oauth2 access token that was fetched using an out of band
+/// mechanism.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
+std::shared_ptr<CallCredentials> AccessTokenCredentials(
+ const grpc::string& access_token);
+
+/// Builds IAM credentials.
+///
+/// \warning Only use these credentials when connecting to a Google endpoint.
+/// Using these credentials to connect to any other service may result in this
+/// service being able to impersonate your client for requests to Google
+/// services.
+std::shared_ptr<CallCredentials> GoogleIAMCredentials(
+ const grpc::string& authorization_token,
+ const grpc::string& authority_selector);
+
+/// Combines a channel credentials and a call credentials into a composite
+/// channel credentials.
+std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+ const std::shared_ptr<ChannelCredentials>& channel_creds,
+ const std::shared_ptr<CallCredentials>& call_creds);
+
+/// Combines two call credentials objects into a composite call credentials.
+std::shared_ptr<CallCredentials> CompositeCallCredentials(
+ const std::shared_ptr<CallCredentials>& creds1,
+ const std::shared_ptr<CallCredentials>& creds2);
+
+/// Credentials for an unencrypted, unauthenticated channel
+std::shared_ptr<ChannelCredentials> InsecureChannelCredentials();
+
+/// Credentials for a channel using Cronet.
+std::shared_ptr<ChannelCredentials> CronetChannelCredentials(void* engine);
+
+/// User defined metadata credentials.
+class MetadataCredentialsPlugin {
+ public:
+ virtual ~MetadataCredentialsPlugin() {}
+
+ /// If this method returns true, the Process function will be scheduled in
+ /// a different thread from the one processing the call.
+ virtual bool IsBlocking() const { return true; }
+
+ /// Type of credentials this plugin is implementing.
+ virtual const char* GetType() const { return ""; }
+
+ /// Gets the auth metatada produced by this plugin.
+ /// The fully qualified method name is:
+ /// service_url + "/" + method_name.
+ /// The channel_auth_context contains (among other things), the identity of
+ /// the server.
+ virtual Status GetMetadata(
+ grpc::string_ref service_url, grpc::string_ref method_name,
+ const AuthContext& channel_auth_context,
+ std::multimap<grpc::string, grpc::string>* metadata) = 0;
+};
+
+std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
+ std::unique_ptr<MetadataCredentialsPlugin> plugin);
+
+} // namespace grpc
+
+#endif // GRPCPP_SECURITY_CREDENTIALS_H
diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h
new file mode 100644
index 0000000000..892863ef54
--- /dev/null
+++ b/include/grpcpp/security/server_credentials.h
@@ -0,0 +1,91 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SECURITY_SERVER_CREDENTIALS_H
+#define GRPCPP_SECURITY_SERVER_CREDENTIALS_H
+
+#include <memory>
+#include <vector>
+
+#include <grpc/grpc_security_constants.h>
+#include <grpcpp/security/auth_metadata_processor.h>
+#include <grpcpp/support/config.h>
+
+struct grpc_server;
+
+namespace grpc {
+class Server;
+
+/// Wrapper around \a grpc_server_credentials, a way to authenticate a server.
+class ServerCredentials {
+ public:
+ virtual ~ServerCredentials();
+
+ /// This method is not thread-safe and has to be called before the server is
+ /// started. The last call to this function wins.
+ virtual void SetAuthMetadataProcessor(
+ const std::shared_ptr<AuthMetadataProcessor>& processor) = 0;
+
+ private:
+ friend class ::grpc::Server;
+
+ /// Tries to bind \a server to the given \a addr (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.)
+ ///
+ /// \return bound port number on sucess, 0 on failure.
+ // TODO(dgq): the "port" part seems to be a misnomer.
+ virtual int AddPortToServer(const grpc::string& addr,
+ grpc_server* server) = 0;
+};
+
+/// Options to create ServerCredentials with SSL
+struct SslServerCredentialsOptions {
+ /// \warning Deprecated
+ SslServerCredentialsOptions()
+ : force_client_auth(false),
+ client_certificate_request(GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE) {}
+ SslServerCredentialsOptions(
+ grpc_ssl_client_certificate_request_type request_type)
+ : force_client_auth(false), client_certificate_request(request_type) {}
+
+ struct PemKeyCertPair {
+ grpc::string private_key;
+ grpc::string cert_chain;
+ };
+ grpc::string pem_root_certs;
+ std::vector<PemKeyCertPair> pem_key_cert_pairs;
+ /// \warning Deprecated
+ bool force_client_auth;
+
+ /// If both \a force_client_auth and \a client_certificate_request
+ /// fields are set, \a force_client_auth takes effect, i.e.
+ /// \a REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
+ /// will be enforced.
+ grpc_ssl_client_certificate_request_type client_certificate_request;
+};
+
+/// Builds SSL ServerCredentials given SSL specific options
+std::shared_ptr<ServerCredentials> SslServerCredentials(
+ const SslServerCredentialsOptions& options);
+
+/// Builds insecure server credentials.
+std::shared_ptr<ServerCredentials> InsecureServerCredentials();
+
+} // namespace grpc
+
+#endif // GRPCPP_SECURITY_SERVER_CREDENTIALS_H
diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h
new file mode 100644
index 0000000000..f99a6c26b4
--- /dev/null
+++ b/include/grpcpp/server.h
@@ -0,0 +1,227 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SERVER_H
+#define GRPCPP_SERVER_H
+
+#include <condition_variable>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <vector>
+
+#include <grpc/compression.h>
+#include <grpcpp/completion_queue.h>
+#include <grpcpp/impl/call.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+#include <grpcpp/impl/codegen/server_interface.h>
+#include <grpcpp/impl/rpc_service_method.h>
+#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/support/channel_arguments.h>
+#include <grpcpp/support/config.h>
+#include <grpcpp/support/status.h>
+
+struct grpc_server;
+
+namespace grpc {
+
+class AsyncGenericService;
+class HealthCheckServiceInterface;
+class ServerContext;
+class ServerInitializer;
+
+/// Represents a gRPC server.
+///
+/// Use a \a grpc::ServerBuilder to create, configure, and start
+/// \a Server instances.
+class Server final : public ServerInterface, private GrpcLibraryCodegen {
+ public:
+ ~Server();
+
+ /// Block until the server shuts down.
+ ///
+ /// \warning The server must be either shutting down or some other thread must
+ /// call \a Shutdown for this function to ever return.
+ void Wait() override;
+
+ /// Global callbacks are a set of hooks that are called when server
+ /// events occur. \a SetGlobalCallbacks method is used to register
+ /// the hooks with gRPC. Note that
+ /// the \a GlobalCallbacks instance will be shared among all
+ /// \a Server instances in an application and can be set exactly
+ /// once per application.
+ class GlobalCallbacks {
+ public:
+ virtual ~GlobalCallbacks() {}
+ /// Called before server is created.
+ virtual void UpdateArguments(ChannelArguments* args) {}
+ /// Called before application callback for each synchronous server request
+ virtual void PreSynchronousRequest(ServerContext* context) = 0;
+ /// Called after application callback for each synchronous server request
+ virtual void PostSynchronousRequest(ServerContext* context) = 0;
+ /// Called before server is started.
+ virtual void PreServerStart(Server* server) {}
+ /// Called after a server port is added.
+ virtual void AddPort(Server* server, const grpc::string& addr,
+ ServerCredentials* creds, int port) {}
+ };
+ /// Set the global callback object. Can only be called once per application.
+ /// Does not take ownership of callbacks, and expects the pointed to object
+ /// to be alive until all server objects in the process have been destroyed.
+ /// The same \a GlobalCallbacks object will be used throughout the
+ /// application and is shared among all \a Server objects.
+ static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
+
+ // Returns a \em raw pointer to the underlying \a grpc_server instance.
+ grpc_server* c_server();
+
+ /// Returns the health check service.
+ HealthCheckServiceInterface* GetHealthCheckService() const {
+ return health_check_service_.get();
+ }
+
+ /// Establish a channel for in-process communication
+ std::shared_ptr<Channel> InProcessChannel(const ChannelArguments& args);
+
+ private:
+ friend class AsyncGenericService;
+ friend class ServerBuilder;
+ friend class ServerInitializer;
+
+ class SyncRequest;
+ class AsyncRequest;
+ class ShutdownRequest;
+
+ /// SyncRequestThreadManager is an implementation of ThreadManager. This class
+ /// is responsible for polling for incoming RPCs and calling the RPC handlers.
+ /// This is only used in case of a Sync server (i.e a server exposing a sync
+ /// interface)
+ class SyncRequestThreadManager;
+
+ class UnimplementedAsyncRequestContext;
+ class UnimplementedAsyncRequest;
+ class UnimplementedAsyncResponse;
+
+ /// Server constructors. To be used by \a ServerBuilder only.
+ ///
+ /// \param max_message_size Maximum message length that the channel can
+ /// receive.
+ ///
+ /// \param args The channel args
+ ///
+ /// \param sync_server_cqs The completion queues to use if the server is a
+ /// synchronous server (or a hybrid server). The server polls for new RPCs on
+ /// these queues
+ ///
+ /// \param min_pollers The minimum number of polling threads per server
+ /// completion queue (in param sync_server_cqs) to use for listening to
+ /// incoming requests (used only in case of sync server)
+ ///
+ /// \param max_pollers The maximum number of polling threads per server
+ /// completion queue (in param sync_server_cqs) to use for listening to
+ /// incoming requests (used only in case of sync server)
+ ///
+ /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on
+ /// server completion queues passed via sync_server_cqs param.
+ Server(int max_message_size, ChannelArguments* args,
+ std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
+ sync_server_cqs,
+ int min_pollers, int max_pollers, int sync_cq_timeout_msec);
+
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the Server instance.
+ bool RegisterService(const grpc::string* host, Service* service) override;
+
+ /// Register a generic service. This call does not take ownership of the
+ /// service. The service must exist for the lifetime of the Server instance.
+ void RegisterAsyncGenericService(AsyncGenericService* service) override;
+
+ /// Try binding the server to the given \a addr endpoint
+ /// (port, and optionally including IP address to bind to).
+ ///
+ /// It can be invoked multiple times. Should be used before
+ /// starting the server.
+ ///
+ /// \param addr The address to try to bind to the server (eg, localhost:1234,
+ /// 192.168.1.1:31416, [::1]:27182, etc.).
+ /// \param creds The credentials associated with the server.
+ ///
+ /// \return bound port number on success, 0 on failure.
+ ///
+ /// \warning It is an error to call this method on an already started server.
+ int AddListeningPort(const grpc::string& addr,
+ ServerCredentials* creds) override;
+
+ /// Start the server.
+ ///
+ /// \param cqs Completion queues for handling asynchronous services. The
+ /// caller is required to keep all completion queues live until the server is
+ /// destroyed.
+ /// \param num_cqs How many completion queues does \a cqs hold.
+ void Start(ServerCompletionQueue** cqs, size_t num_cqs) override;
+
+ void PerformOpsOnCall(internal::CallOpSetInterface* ops,
+ internal::Call* call) override;
+
+ void ShutdownInternal(gpr_timespec deadline) override;
+
+ int max_receive_message_size() const override {
+ return max_receive_message_size_;
+ };
+
+ grpc_server* server() override { return server_; };
+
+ ServerInitializer* initializer();
+
+ const int max_receive_message_size_;
+
+ /// The following completion queues are ONLY used in case of Sync API
+ /// i.e. if the server has any services with sync methods. The server uses
+ /// these completion queues to poll for new RPCs
+ std::shared_ptr<std::vector<std::unique_ptr<ServerCompletionQueue>>>
+ sync_server_cqs_;
+
+ /// List of \a ThreadManager instances (one for each cq in
+ /// the \a sync_server_cqs)
+ std::vector<std::unique_ptr<SyncRequestThreadManager>> sync_req_mgrs_;
+
+ // Sever status
+ std::mutex mu_;
+ bool started_;
+ bool shutdown_;
+ bool shutdown_notified_; // Was notify called on the shutdown_cv_
+
+ std::condition_variable shutdown_cv_;
+
+ std::shared_ptr<GlobalCallbacks> global_callbacks_;
+
+ std::vector<grpc::string> services_;
+ bool has_generic_service_;
+
+ // Pointer to the wrapped grpc_server.
+ grpc_server* server_;
+
+ std::unique_ptr<ServerInitializer> server_initializer_;
+
+ std::unique_ptr<HealthCheckServiceInterface> health_check_service_;
+ bool health_check_service_disabled_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_SERVER_H
diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h
new file mode 100644
index 0000000000..c35a6cf98a
--- /dev/null
+++ b/include/grpcpp/server_builder.h
@@ -0,0 +1,278 @@
+/*
+ *
+ * Copyright 2015-2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SERVER_BUILDER_H
+#define GRPCPP_SERVER_BUILDER_H
+
+#include <climits>
+#include <map>
+#include <memory>
+#include <vector>
+
+#include <grpc/compression.h>
+#include <grpc/support/cpu.h>
+#include <grpc/support/workaround_list.h>
+#include <grpcpp/impl/channel_argument_option.h>
+#include <grpcpp/impl/server_builder_option.h>
+#include <grpcpp/impl/server_builder_plugin.h>
+#include <grpcpp/support/config.h>
+
+struct grpc_resource_quota;
+
+namespace grpc {
+
+class AsyncGenericService;
+class ResourceQuota;
+class CompletionQueue;
+class Server;
+class ServerCompletionQueue;
+class ServerCredentials;
+class Service;
+
+namespace testing {
+class ServerBuilderPluginTest;
+} // namespace testing
+
+/// A builder class for the creation and startup of \a grpc::Server instances.
+class ServerBuilder {
+ public:
+ ServerBuilder();
+ ~ServerBuilder();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Primary API's
+
+ /// Return a running server which is ready for processing calls.
+ /// Before calling, one typically needs to ensure that:
+ /// 1. a service is registered - so that the server knows what to serve
+ /// (via RegisterService, or RegisterAsyncGenericService)
+ /// 2. a listening port has been added - so the server knows where to receive
+ /// traffic (via AddListeningPort)
+ /// 3. [for async api only] completion queues have been added via
+ /// AddCompletionQueue
+ std::unique_ptr<Server> BuildAndStart();
+
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the \a Server instance returned
+ /// by \a BuildAndStart().
+ /// Matches requests with any :authority
+ ServerBuilder& RegisterService(Service* service);
+
+ /// Enlists an endpoint \a addr (port with an optional IP address) to
+ /// bind the \a grpc::Server object to be created to.
+ ///
+ /// It can be invoked multiple times.
+ ///
+ /// \param addr_uri The address to try to bind to the server in URI form. If
+ /// the scheme name is omitted, "dns:///" is assumed. To bind to any address,
+ /// please use IPv6 any, i.e., [::]:<port>, which also accepts IPv4
+ /// connections. Valid values include dns:///localhost:1234, /
+ /// 192.168.1.1:31416, dns:///[::1]:27182, etc.).
+ /// \param creds The credentials associated with the server.
+ /// \param selected_port[out] If not `nullptr`, gets populated with the port
+ /// number bound to the \a grpc::Server for the corresponding endpoint after
+ /// it is successfully bound, 0 otherwise.
+ ///
+ ServerBuilder& AddListeningPort(const grpc::string& addr_uri,
+ std::shared_ptr<ServerCredentials> creds,
+ int* selected_port = nullptr);
+
+ /// Add a completion queue for handling asynchronous services.
+ ///
+ /// Best performance is typically obtained by using one thread per polling
+ /// completion queue.
+ ///
+ /// Caller is required to shutdown the server prior to shutting down the
+ /// returned completion queue. Caller is also required to drain the
+ /// completion queue after shutting it down. A typical usage scenario:
+ ///
+ /// // While building the server:
+ /// ServerBuilder builder;
+ /// ...
+ /// cq_ = builder.AddCompletionQueue();
+ /// server_ = builder.BuildAndStart();
+ ///
+ /// // While shutting down the server;
+ /// server_->Shutdown();
+ /// cq_->Shutdown(); // Always *after* the associated server's Shutdown()!
+ /// // Drain the cq_ that was created
+ /// void* ignored_tag;
+ /// bool ignored_ok;
+ /// while (cq_->Next(&ignored_tag, &ignored_ok)) { }
+ ///
+ /// \param is_frequently_polled This is an optional parameter to inform gRPC
+ /// library about whether this completion queue would be frequently polled
+ /// (i.e. by calling \a Next() or \a AsyncNext()). The default value is
+ /// 'true' and is the recommended setting. Setting this to 'false' (i.e.
+ /// not polling the completion queue frequently) will have a significantly
+ /// negative performance impact and hence should not be used in production
+ /// use cases.
+ std::unique_ptr<ServerCompletionQueue> AddCompletionQueue(
+ bool is_frequently_polled = true);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Less commonly used RegisterService variants
+
+ /// Register a service. This call does not take ownership of the service.
+ /// The service must exist for the lifetime of the \a Server instance returned
+ /// by \a BuildAndStart().
+ /// Only matches requests with :authority \a host
+ ServerBuilder& RegisterService(const grpc::string& host, Service* service);
+
+ /// Register a generic service.
+ /// Matches requests with any :authority
+ /// This is mostly useful for writing generic gRPC Proxies where the exact
+ /// serialization format is unknown
+ ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service);
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Fine control knobs
+
+ /// Set max receive message size in bytes.
+ ServerBuilder& SetMaxReceiveMessageSize(int max_receive_message_size) {
+ max_receive_message_size_ = max_receive_message_size;
+ return *this;
+ }
+
+ /// Set max send message size in bytes.
+ ServerBuilder& SetMaxSendMessageSize(int max_send_message_size) {
+ max_send_message_size_ = max_send_message_size;
+ return *this;
+ }
+
+ /// \deprecated For backward compatibility.
+ ServerBuilder& SetMaxMessageSize(int max_message_size) {
+ return SetMaxReceiveMessageSize(max_message_size);
+ }
+
+ /// Set the support status for compression algorithms. All algorithms are
+ /// enabled by default.
+ ///
+ /// Incoming calls compressed with an unsupported algorithm will fail with
+ /// \a GRPC_STATUS_UNIMPLEMENTED.
+ ServerBuilder& SetCompressionAlgorithmSupportStatus(
+ grpc_compression_algorithm algorithm, bool enabled);
+
+ /// The default compression level to use for all channel calls in the
+ /// absence of a call-specific level.
+ ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level);
+
+ /// The default compression algorithm to use for all channel calls in the
+ /// absence of a call-specific level. Note that it overrides any compression
+ /// level set by \a SetDefaultCompressionLevel.
+ ServerBuilder& SetDefaultCompressionAlgorithm(
+ grpc_compression_algorithm algorithm);
+
+ /// Set the attached buffer pool for this server
+ ServerBuilder& SetResourceQuota(const ResourceQuota& resource_quota);
+
+ ServerBuilder& SetOption(std::unique_ptr<ServerBuilderOption> option);
+
+ /// Options for synchronous servers.
+ enum SyncServerOption {
+ NUM_CQS, ///< Number of completion queues.
+ MIN_POLLERS, ///< Minimum number of polling threads.
+ MAX_POLLERS, ///< Maximum number of polling threads.
+ CQ_TIMEOUT_MSEC ///< Completion queue timeout in milliseconds.
+ };
+
+ /// Only useful if this is a Synchronous server.
+ ServerBuilder& SetSyncServerOption(SyncServerOption option, int value);
+
+ /// Add a channel argument (an escape hatch to tuning core library parameters
+ /// directly)
+ template <class T>
+ ServerBuilder& AddChannelArgument(const grpc::string& arg, const T& value) {
+ return SetOption(MakeChannelArgumentOption(arg, value));
+ }
+
+ /// For internal use only: Register a ServerBuilderPlugin factory function.
+ static void InternalAddPluginFactory(
+ std::unique_ptr<ServerBuilderPlugin> (*CreatePlugin)());
+
+ /// Enable a server workaround. Do not use unless you know what the workaround
+ /// does. For explanation and detailed descriptions of workarounds, see
+ /// doc/workarounds.md.
+ ServerBuilder& EnableWorkaround(grpc_workaround_list id);
+
+ private:
+ friend class ::grpc::testing::ServerBuilderPluginTest;
+
+ struct Port {
+ grpc::string addr;
+ std::shared_ptr<ServerCredentials> creds;
+ int* selected_port;
+ };
+
+ struct SyncServerSettings {
+ SyncServerSettings()
+ : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {}
+
+ /// Number of server completion queues to create to listen to incoming RPCs.
+ int num_cqs;
+
+ /// Minimum number of threads per completion queue that should be listening
+ /// to incoming RPCs.
+ int min_pollers;
+
+ /// Maximum number of threads per completion queue that can be listening to
+ /// incoming RPCs.
+ int max_pollers;
+
+ /// The timeout for server completion queue's AsyncNext call.
+ int cq_timeout_msec;
+ };
+
+ typedef std::unique_ptr<grpc::string> HostString;
+ struct NamedService {
+ explicit NamedService(Service* s) : service(s) {}
+ NamedService(const grpc::string& h, Service* s)
+ : host(new grpc::string(h)), service(s) {}
+ HostString host;
+ Service* service;
+ };
+
+ int max_receive_message_size_;
+ int max_send_message_size_;
+ std::vector<std::unique_ptr<ServerBuilderOption>> options_;
+ std::vector<std::unique_ptr<NamedService>> services_;
+ std::vector<Port> ports_;
+
+ SyncServerSettings sync_server_settings_;
+
+ /// List of completion queues added via \a AddCompletionQueue method.
+ std::vector<ServerCompletionQueue*> cqs_;
+
+ std::shared_ptr<ServerCredentials> creds_;
+ std::vector<std::unique_ptr<ServerBuilderPlugin>> plugins_;
+ grpc_resource_quota* resource_quota_;
+ AsyncGenericService* generic_service_;
+ struct {
+ bool is_set;
+ grpc_compression_level level;
+ } maybe_default_compression_level_;
+ struct {
+ bool is_set;
+ grpc_compression_algorithm algorithm;
+ } maybe_default_compression_algorithm_;
+ uint32_t enabled_compression_algorithms_bitset_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_SERVER_BUILDER_H
diff --git a/include/grpcpp/server_context.h b/include/grpcpp/server_context.h
new file mode 100644
index 0000000000..45f2614994
--- /dev/null
+++ b/include/grpcpp/server_context.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SERVER_CONTEXT_H
+#define GRPCPP_SERVER_CONTEXT_H
+
+#include <grpcpp/impl/codegen/server_context.h>
+
+#endif // GRPCPP_SERVER_CONTEXT_H
diff --git a/include/grpcpp/server_posix.h b/include/grpcpp/server_posix.h
new file mode 100644
index 0000000000..ef3ee01a5c
--- /dev/null
+++ b/include/grpcpp/server_posix.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SERVER_POSIX_H
+#define GRPCPP_SERVER_POSIX_H
+
+#include <memory>
+
+#include <grpc/support/port_platform.h>
+#include <grpcpp/server.h>
+
+namespace grpc {
+
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
+
+/// Add a new client to a \a Server communicating over the given
+/// file descriptor.
+///
+/// \param server The server to add the client to.
+/// \param fd The file descriptor representing a socket.
+void AddInsecureChannelFromFd(Server* server, int fd);
+
+#endif // GPR_SUPPORT_CHANNELS_FROM_FD
+
+} // namespace grpc
+
+#endif // GRPCPP_SERVER_POSIX_H
diff --git a/include/grpcpp/support/async_stream.h b/include/grpcpp/support/async_stream.h
new file mode 100644
index 0000000000..ff9e455679
--- /dev/null
+++ b/include/grpcpp/support/async_stream.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_ASYNC_STREAM_H
+#define GRPCPP_SUPPORT_ASYNC_STREAM_H
+
+#include <grpcpp/impl/codegen/async_stream.h>
+
+#endif // GRPCPP_SUPPORT_ASYNC_STREAM_H
diff --git a/include/grpcpp/support/async_unary_call.h b/include/grpcpp/support/async_unary_call.h
new file mode 100644
index 0000000000..2e5181c557
--- /dev/null
+++ b/include/grpcpp/support/async_unary_call.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_ASYNC_UNARY_CALL_H
+#define GRPCPP_SUPPORT_ASYNC_UNARY_CALL_H
+
+#include <grpcpp/impl/codegen/async_unary_call.h>
+
+#endif // GRPCPP_SUPPORT_ASYNC_UNARY_CALL_H
diff --git a/include/grpcpp/support/byte_buffer.h b/include/grpcpp/support/byte_buffer.h
new file mode 100644
index 0000000000..53aeff19f7
--- /dev/null
+++ b/include/grpcpp/support/byte_buffer.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_BYTE_BUFFER_H
+#define GRPCPP_SUPPORT_BYTE_BUFFER_H
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpcpp/impl/codegen/byte_buffer.h>
+#include <grpcpp/impl/serialization_traits.h>
+#include <grpcpp/support/config.h>
+#include <grpcpp/support/slice.h>
+#include <grpcpp/support/status.h>
+
+#endif // GRPCPP_SUPPORT_BYTE_BUFFER_H
diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h
new file mode 100644
index 0000000000..1eead4e1a4
--- /dev/null
+++ b/include/grpcpp/support/channel_arguments.h
@@ -0,0 +1,142 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H
+#define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H
+
+#include <list>
+#include <vector>
+
+#include <grpc/compression.h>
+#include <grpc/grpc.h>
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+namespace testing {
+class ChannelArgumentsTest;
+} // namespace testing
+
+class ResourceQuota;
+
+/// Options for channel creation. The user can use generic setters to pass
+/// key value pairs down to C channel creation code. For gRPC related options,
+/// concrete setters are provided.
+class ChannelArguments {
+ public:
+ ChannelArguments();
+ ~ChannelArguments();
+
+ ChannelArguments(const ChannelArguments& other);
+ ChannelArguments& operator=(ChannelArguments other) {
+ Swap(other);
+ return *this;
+ }
+
+ void Swap(ChannelArguments& other);
+
+ /// Dump arguments in this instance to \a channel_args. Does not take
+ /// ownership of \a channel_args.
+ ///
+ /// Note that the underlying arguments are shared. Changes made to either \a
+ /// channel_args or this instance would be reflected on both.
+ void SetChannelArgs(grpc_channel_args* channel_args) const;
+
+ // gRPC specific channel argument setters
+ /// Set target name override for SSL host name checking. This option is for
+ /// testing only and should never be used in production.
+ void SetSslTargetNameOverride(const grpc::string& name);
+ // TODO(yangg) add flow control options
+ /// Set the compression algorithm for the channel.
+ void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
+
+ /// Set the grpclb fallback timeout (in ms) for the channel. If this amount
+ /// of time has passed but we have not gotten any non-empty \a serverlist from
+ /// the balancer, we will fall back to use the backend address(es) returned by
+ /// the resolver.
+ void SetGrpclbFallbackTimeout(int fallback_timeout);
+
+ /// Set the socket mutator for the channel.
+ void SetSocketMutator(grpc_socket_mutator* mutator);
+
+ /// Set the string to prepend to the user agent.
+ void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
+
+ /// Set the buffer pool to be attached to the constructed channel.
+ void SetResourceQuota(const ResourceQuota& resource_quota);
+
+ /// Set the max receive and send message sizes.
+ void SetMaxReceiveMessageSize(int size);
+ void SetMaxSendMessageSize(int size);
+
+ /// Set LB policy name.
+ /// Note that if the name resolver returns only balancer addresses, the
+ /// grpclb LB policy will be used, regardless of what is specified here.
+ void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name);
+
+ /// Set service config in JSON form.
+ /// Primarily meant for use in unit tests.
+ void SetServiceConfigJSON(const grpc::string& service_config_json);
+
+ // Generic channel argument setters. Only for advanced use cases.
+ /// Set an integer argument \a value under \a key.
+ void SetInt(const grpc::string& key, int value);
+
+ // Generic channel argument setter. Only for advanced use cases.
+ /// Set a pointer argument \a value under \a key. Owership is not transferred.
+ void SetPointer(const grpc::string& key, void* value);
+
+ void SetPointerWithVtable(const grpc::string& key, void* value,
+ const grpc_arg_pointer_vtable* vtable);
+
+ /// Set a textual argument \a value under \a key.
+ void SetString(const grpc::string& key, const grpc::string& value);
+
+ /// Return (by value) a C \a grpc_channel_args structure which points to
+ /// arguments owned by this \a ChannelArguments instance
+ grpc_channel_args c_channel_args() const {
+ grpc_channel_args out;
+ out.num_args = args_.size();
+ out.args = args_.empty() ? NULL : const_cast<grpc_arg*>(&args_[0]);
+ return out;
+ }
+
+ private:
+ friend class SecureChannelCredentials;
+ friend class testing::ChannelArgumentsTest;
+
+ /// Default pointer argument operations.
+ struct PointerVtableMembers {
+ static void* Copy(void* in) { return in; }
+ static void Destroy(void* in) {}
+ static int Compare(void* a, void* b) {
+ if (a < b) return -1;
+ if (a > b) return 1;
+ return 0;
+ }
+ };
+
+ // Returns empty string when it is not set.
+ grpc::string GetSslTargetNameOverride() const;
+
+ std::vector<grpc_arg> args_;
+ std::list<grpc::string> strings_;
+};
+
+} // namespace grpc
+
+#endif // GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H
diff --git a/include/grpcpp/support/config.h b/include/grpcpp/support/config.h
new file mode 100644
index 0000000000..16bdab6427
--- /dev/null
+++ b/include/grpcpp/support/config.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_CONFIG_H
+#define GRPCPP_SUPPORT_CONFIG_H
+
+#include <grpcpp/impl/codegen/config.h>
+
+#endif // GRPCPP_SUPPORT_CONFIG_H
diff --git a/include/grpcpp/support/error_details.h b/include/grpcpp/support/error_details.h
new file mode 100644
index 0000000000..84931d98f1
--- /dev/null
+++ b/include/grpcpp/support/error_details.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_ERROR_DETAILS_H
+#define GRPCPP_SUPPORT_ERROR_DETAILS_H
+
+#include <grpcpp/support/status.h>
+
+namespace google {
+namespace rpc {
+class Status;
+} // namespace rpc
+} // namespace google
+
+namespace grpc {
+
+/// Map a \a grpc::Status to a \a google::rpc::Status.
+/// The given \a to object will be cleared.
+/// On success, returns status with OK.
+/// Returns status with \a INVALID_ARGUMENT, if failed to deserialize.
+/// Returns status with \a FAILED_PRECONDITION, if \a to is nullptr.
+Status ExtractErrorDetails(const Status& from, ::google::rpc::Status* to);
+
+/// Map \a google::rpc::Status to a \a grpc::Status.
+/// Returns OK on success.
+/// Returns status with \a FAILED_PRECONDITION if \a to is nullptr.
+Status SetErrorDetails(const ::google::rpc::Status& from, Status* to);
+
+} // namespace grpc
+
+#endif // GRPCPP_SUPPORT_ERROR_DETAILS_H
diff --git a/include/grpcpp/support/slice.h b/include/grpcpp/support/slice.h
new file mode 100644
index 0000000000..eaeb29a40b
--- /dev/null
+++ b/include/grpcpp/support/slice.h
@@ -0,0 +1,26 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_SLICE_H
+#define GRPCPP_SUPPORT_SLICE_H
+
+#include <grpc/slice.h>
+#include <grpcpp/impl/codegen/slice.h>
+#include <grpcpp/support/config.h>
+
+#endif // GRPCPP_SUPPORT_SLICE_H
diff --git a/include/grpcpp/support/status.h b/include/grpcpp/support/status.h
new file mode 100644
index 0000000000..91b629f167
--- /dev/null
+++ b/include/grpcpp/support/status.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_STATUS_H
+#define GRPCPP_SUPPORT_STATUS_H
+
+#include <grpcpp/impl/codegen/status.h>
+
+#endif // GRPCPP_SUPPORT_STATUS_H
diff --git a/include/grpcpp/support/status_code_enum.h b/include/grpcpp/support/status_code_enum.h
new file mode 100644
index 0000000000..bfb47f39c0
--- /dev/null
+++ b/include/grpcpp/support/status_code_enum.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_STATUS_CODE_ENUM_H
+#define GRPCPP_SUPPORT_STATUS_CODE_ENUM_H
+
+#include <grpcpp/impl/codegen/status_code_enum.h>
+
+#endif // GRPCPP_SUPPORT_STATUS_CODE_ENUM_H
diff --git a/include/grpcpp/support/string_ref.h b/include/grpcpp/support/string_ref.h
new file mode 100644
index 0000000000..0e0d3d4389
--- /dev/null
+++ b/include/grpcpp/support/string_ref.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_STRING_REF_H
+#define GRPCPP_SUPPORT_STRING_REF_H
+
+#include <grpcpp/impl/codegen/string_ref.h>
+
+#endif // GRPCPP_SUPPORT_STRING_REF_H
diff --git a/include/grpcpp/support/stub_options.h b/include/grpcpp/support/stub_options.h
new file mode 100644
index 0000000000..e9700ea492
--- /dev/null
+++ b/include/grpcpp/support/stub_options.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_STUB_OPTIONS_H
+#define GRPCPP_SUPPORT_STUB_OPTIONS_H
+
+#include <grpcpp/impl/codegen/stub_options.h>
+
+#endif // GRPCPP_SUPPORT_STUB_OPTIONS_H
diff --git a/include/grpcpp/support/sync_stream.h b/include/grpcpp/support/sync_stream.h
new file mode 100644
index 0000000000..ea60b6da6b
--- /dev/null
+++ b/include/grpcpp/support/sync_stream.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_SYNC_STREAM_H
+#define GRPCPP_SUPPORT_SYNC_STREAM_H
+
+#include <grpcpp/impl/codegen/sync_stream.h>
+
+#endif // GRPCPP_SUPPORT_SYNC_STREAM_H
diff --git a/include/grpcpp/support/time.h b/include/grpcpp/support/time.h
new file mode 100644
index 0000000000..c7408ff27d
--- /dev/null
+++ b/include/grpcpp/support/time.h
@@ -0,0 +1,24 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_SUPPORT_TIME_H
+#define GRPCPP_SUPPORT_TIME_H
+
+#include <grpcpp/impl/codegen/time.h>
+
+#endif // GRPCPP_SUPPORT_TIME_H
diff --git a/include/grpcpp/test/mock_stream.h b/include/grpcpp/test/mock_stream.h
new file mode 100644
index 0000000000..93963f7dbb
--- /dev/null
+++ b/include/grpcpp/test/mock_stream.h
@@ -0,0 +1,148 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_TEST_MOCK_STREAM_H
+#define GRPCPP_TEST_MOCK_STREAM_H
+
+#include <stdint.h>
+
+#include <gmock/gmock.h>
+#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/support/async_stream.h>
+#include <grpcpp/support/async_unary_call.h>
+#include <grpcpp/support/sync_stream.h>
+
+namespace grpc {
+namespace testing {
+
+template <class R>
+class MockClientReader : public ClientReaderInterface<R> {
+ public:
+ MockClientReader() = default;
+
+ /// ClientStreamingInterface
+ MOCK_METHOD0_T(Finish, Status());
+
+ /// ReaderInterface
+ MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
+ MOCK_METHOD1_T(Read, bool(R*));
+
+ /// ClientReaderInterface
+ MOCK_METHOD0_T(WaitForInitialMetadata, void());
+};
+
+template <class W>
+class MockClientWriter : public ClientWriterInterface<W> {
+ public:
+ MockClientWriter() = default;
+
+ /// ClientStreamingInterface
+ MOCK_METHOD0_T(Finish, Status());
+
+ /// WriterInterface
+ MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
+
+ /// ClientWriterInterface
+ MOCK_METHOD0_T(WritesDone, bool());
+};
+
+template <class W, class R>
+class MockClientReaderWriter : public ClientReaderWriterInterface<W, R> {
+ public:
+ MockClientReaderWriter() = default;
+
+ /// ClientStreamingInterface
+ MOCK_METHOD0_T(Finish, Status());
+
+ /// ReaderInterface
+ MOCK_METHOD1_T(NextMessageSize, bool(uint32_t*));
+ MOCK_METHOD1_T(Read, bool(R*));
+
+ /// WriterInterface
+ MOCK_METHOD2_T(Write, bool(const W&, const WriteOptions));
+
+ /// ClientReaderWriterInterface
+ MOCK_METHOD0_T(WaitForInitialMetadata, void());
+ MOCK_METHOD0_T(WritesDone, bool());
+};
+
+/// TODO: We do not support mocking an async RPC for now.
+
+template <class R>
+class MockClientAsyncResponseReader
+ : public ClientAsyncResponseReaderInterface<R> {
+ public:
+ MockClientAsyncResponseReader() = default;
+
+ MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+ MOCK_METHOD3_T(Finish, void(R*, Status*, void*));
+};
+
+template <class R>
+class MockClientAsyncReader : public ClientAsyncReaderInterface<R> {
+ public:
+ MockClientAsyncReader() = default;
+
+ /// ClientAsyncStreamingInterface
+ MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+ MOCK_METHOD2_T(Finish, void(Status*, void*));
+
+ /// AsyncReaderInterface
+ MOCK_METHOD2_T(Read, void(R*, void*));
+};
+
+template <class W>
+class MockClientAsyncWriter : public ClientAsyncWriterInterface<W> {
+ public:
+ MockClientAsyncWriter() = default;
+
+ /// ClientAsyncStreamingInterface
+ MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+ MOCK_METHOD2_T(Finish, void(Status*, void*));
+
+ /// AsyncWriterInterface
+ MOCK_METHOD2_T(Write, void(const W&, void*));
+
+ /// ClientAsyncWriterInterface
+ MOCK_METHOD1_T(WritesDone, void(void*));
+};
+
+template <class W, class R>
+class MockClientAsyncReaderWriter
+ : public ClientAsyncReaderWriterInterface<W, R> {
+ public:
+ MockClientAsyncReaderWriter() = default;
+
+ /// ClientAsyncStreamingInterface
+ MOCK_METHOD1_T(ReadInitialMetadata, void(void*));
+ MOCK_METHOD2_T(Finish, void(Status*, void*));
+
+ /// AsyncWriterInterface
+ MOCK_METHOD2_T(Write, void(const W&, void*));
+
+ /// AsyncReaderInterface
+ MOCK_METHOD2_T(Read, void(R*, void*));
+
+ /// ClientAsyncReaderWriterInterface
+ MOCK_METHOD1_T(WritesDone, void(void*));
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPCPP_TEST_MOCK_STREAM_H
diff --git a/include/grpcpp/test/server_context_test_spouse.h b/include/grpcpp/test/server_context_test_spouse.h
new file mode 100644
index 0000000000..f5ca552ea5
--- /dev/null
+++ b/include/grpcpp/test/server_context_test_spouse.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPCPP_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
+#define GRPCPP_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
+
+#include <map>
+
+#include <grpcpp/server_context.h>
+
+namespace grpc {
+namespace testing {
+
+/// A test-only class to access private members and methods of ServerContext.
+class ServerContextTestSpouse {
+ public:
+ explicit ServerContextTestSpouse(ServerContext* ctx) : ctx_(ctx) {}
+
+ /// Inject client metadata to the ServerContext for the test. The test spouse
+ /// must be alive when \a ServerContext::client_metadata is called.
+ void AddClientMetadata(const grpc::string& key, const grpc::string& value) {
+ client_metadata_storage_.insert(
+ std::pair<grpc::string, grpc::string>(key, value));
+ ctx_->client_metadata_.map()->clear();
+ for (auto iter = client_metadata_storage_.begin();
+ iter != client_metadata_storage_.end(); ++iter) {
+ ctx_->client_metadata_.map()->insert(
+ std::pair<grpc::string_ref, grpc::string_ref>(
+ iter->first.c_str(),
+ grpc::string_ref(iter->second.data(), iter->second.size())));
+ }
+ }
+
+ std::multimap<grpc::string, grpc::string> GetInitialMetadata() const {
+ return ctx_->initial_metadata_;
+ }
+
+ std::multimap<grpc::string, grpc::string> GetTrailingMetadata() const {
+ return ctx_->trailing_metadata_;
+ }
+
+ private:
+ ServerContext* ctx_; // not owned
+ std::multimap<grpc::string, grpc::string> client_metadata_storage_;
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPCPP_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
diff --git a/package.xml b/package.xml
index 59579493ab..7e095e9c16 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
- <release>1.10.0dev</release>
- <api>1.10.0dev</api>
+ <release>1.11.0dev</release>
+ <api>1.11.0dev</api>
</version>
<stability>
<release>beta</release>
@@ -66,7 +66,7 @@
<file baseinstalldir="/" name="include/grpc/support/sync_generic.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync_posix.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/sync_windows.h" role="src" />
- <file baseinstalldir="/" name="include/grpc/support/thd.h" role="src" />
+ <file baseinstalldir="/" name="include/grpc/support/thd_id.h" role="src" />
<file baseinstalldir="/" name="include/grpc/support/time.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm.h" role="src" />
<file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
@@ -90,7 +90,7 @@
<file baseinstalldir="/" name="src/core/lib/gpr/spinlock.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/string.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/string_windows.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/gpr/thd_internal.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/gpr/thd.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/time_precise.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/tls.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/gpr/tls_gcc.h" role="src" />
@@ -216,11 +216,11 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
- <file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/security/transport/target_authority_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
@@ -241,6 +241,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.h" role="src" />
@@ -248,6 +249,7 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/status_util.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" />
@@ -354,6 +356,7 @@
<file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_internal.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/slice/slice_weak_hash_table.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/call.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/call_test_only.h" role="src" />
@@ -378,12 +381,12 @@
<file baseinstalldir="/" name="src/core/lib/transport/service_config.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/static_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_conversion.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/transport/status_metadata.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/timeout_encoding.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/transport.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/transport_impl.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/debug/trace.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" />
@@ -505,7 +508,6 @@
<file baseinstalldir="/" name="src/core/lib/slice/percent_encoding.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_buffer.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/slice/slice_hash_table.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_intern.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/slice/slice_string_helpers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/api_trace.cc" role="src" />
@@ -536,6 +538,7 @@
<file baseinstalldir="/" name="src/core/lib/transport/service_config.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/static_metadata.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/status_conversion.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/transport/status_metadata.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/timeout_encoding.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/transport.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/transport_op_string.cc" role="src" />
@@ -583,12 +586,12 @@
<file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/security/transport/lb_targets_info.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" />
- <file baseinstalldir="/" name="src/core/lib/security/transport/security_connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/server_auth_filter.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/security/transport/target_authority_table.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/transport/tsi_error.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/security/util/json_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/surface/init_secure.cc" role="src" />
@@ -611,12 +614,14 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/status_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.cc" role="src" />
@@ -664,20 +669,80 @@
<file baseinstalldir="/" name="third_party/boringssl/crypto/curve25519/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/err/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/evp/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/aes/aes.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/aes/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/add.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/asm/x86_64-gcc.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/bn.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/bytes.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/cmp.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/ctx.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/div.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/gcd.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/generic.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/jacobi.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/montgomery.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/mul.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/prime.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/random.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/shift.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/bn/sqrt.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/cipher/aead.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/cipher/cipher.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/cipher/e_des.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/cipher/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/delocate.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/des/des.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/des/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/digest/digest.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/digest/digests.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/digest/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/digest/md32_common.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/ec.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/ec_key.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/oct.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/p224-64.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/p256-64.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/simple.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/util-64.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ec/wnaf.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/hmac/hmac.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/md4/md4.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/md5/md5.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/cbc.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/cfb.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/ctr.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/gcm.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/ofb.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/modes/polyval.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rand/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rand/rand.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rand/urandom.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rsa/blinding.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rsa/internal.h" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rsa/padding.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rsa/rsa.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/sha/sha1-altivec.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/sha/sha1.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/sha/sha256.c" role="src" />
+ <file baseinstalldir="/" name="third_party/boringssl/crypto/fipsmodule/sha/sha512.c" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/internal.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/obj/obj_dat.h" role="src" />
<file baseinstalldir="/" name="third_party/boringssl/crypto/pkcs7/internal.h" role="src" />
diff --git a/src/boringssl/gen_build_yaml.py b/src/boringssl/gen_build_yaml.py
index 221cbe7fd5..593b66dc4d 100755
--- a/src/boringssl/gen_build_yaml.py
+++ b/src/boringssl/gen_build_yaml.py
@@ -67,7 +67,9 @@ class Grpc(object):
),
'headers': sorted(
map_dir(f)
- for f in files['ssl_headers'] + files['ssl_internal_headers'] + files['crypto_headers'] + files['crypto_internal_headers']
+ # We want to include files['fips_fragments'], but not build them as objects.
+ # See https://boringssl-review.googlesource.com/c/boringssl/+/16946
+ for f in files['ssl_headers'] + files['ssl_internal_headers'] + files['crypto_headers'] + files['crypto_internal_headers'] + files['fips_fragments']
),
'boringssl': True,
'defaults': 'boringssl',
diff --git a/src/compiler/config.h b/src/compiler/config.h
index 36d28df8b6..cfdc303624 100644
--- a/src/compiler/config.h
+++ b/src/compiler/config.h
@@ -19,7 +19,7 @@
#ifndef SRC_COMPILER_CONFIG_H
#define SRC_COMPILER_CONFIG_H
-#include <grpc++/impl/codegen/config_protobuf.h>
+#include <grpcpp/impl/codegen/config_protobuf.h>
#ifndef GRPC_CUSTOM_CODEGENERATOR
#include <google/protobuf/compiler/code_generator.h>
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 3a15a601cb..30d66b444f 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -128,15 +128,15 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
"");
}
static const char* headers_strs[] = {
- "grpc++/impl/codegen/async_stream.h",
- "grpc++/impl/codegen/async_unary_call.h",
- "grpc++/impl/codegen/method_handler_impl.h",
- "grpc++/impl/codegen/proto_utils.h",
- "grpc++/impl/codegen/rpc_method.h",
- "grpc++/impl/codegen/service_type.h",
- "grpc++/impl/codegen/status.h",
- "grpc++/impl/codegen/stub_options.h",
- "grpc++/impl/codegen/sync_stream.h"};
+ "grpcpp/impl/codegen/async_stream.h",
+ "grpcpp/impl/codegen/async_unary_call.h",
+ "grpcpp/impl/codegen/method_handler_impl.h",
+ "grpcpp/impl/codegen/proto_utils.h",
+ "grpcpp/impl/codegen/rpc_method.h",
+ "grpcpp/impl/codegen/service_type.h",
+ "grpcpp/impl/codegen/status.h",
+ "grpcpp/impl/codegen/stub_options.h",
+ "grpcpp/impl/codegen/sync_stream.h"};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params.use_system_headers,
params.grpc_search_path);
@@ -1148,14 +1148,14 @@ grpc::string GetSourceIncludes(grpc_generator::File* file,
std::map<grpc::string, grpc::string> vars;
static const char* headers_strs[] = {
- "grpc++/impl/codegen/async_stream.h",
- "grpc++/impl/codegen/async_unary_call.h",
- "grpc++/impl/codegen/channel_interface.h",
- "grpc++/impl/codegen/client_unary_call.h",
- "grpc++/impl/codegen/method_handler_impl.h",
- "grpc++/impl/codegen/rpc_service_method.h",
- "grpc++/impl/codegen/service_type.h",
- "grpc++/impl/codegen/sync_stream.h"};
+ "grpcpp/impl/codegen/async_stream.h",
+ "grpcpp/impl/codegen/async_unary_call.h",
+ "grpcpp/impl/codegen/channel_interface.h",
+ "grpcpp/impl/codegen/client_unary_call.h",
+ "grpcpp/impl/codegen/method_handler_impl.h",
+ "grpcpp/impl/codegen/rpc_service_method.h",
+ "grpcpp/impl/codegen/service_type.h",
+ "grpcpp/impl/codegen/sync_stream.h"};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params.use_system_headers,
params.grpc_search_path);
@@ -1571,8 +1571,8 @@ grpc::string GetMockIncludes(grpc_generator::File* file,
std::map<grpc::string, grpc::string> vars;
static const char* headers_strs[] = {
- "grpc++/impl/codegen/async_stream.h",
- "grpc++/impl/codegen/sync_stream.h",
+ "grpcpp/impl/codegen/async_stream.h",
+ "grpcpp/impl/codegen/sync_stream.h",
};
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
PrintIncludes(printer.get(), headers, params.use_system_headers,
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 7c97056402..6e2730579a 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -451,8 +451,10 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service) {
out->Print(
"public virtual $response$ $methodname$($request$ request, "
"grpc::Metadata "
- "headers = null, DateTime? deadline = null, CancellationToken "
- "cancellationToken = default(CancellationToken))\n",
+ "headers = null, global::System.DateTime? deadline = null, "
+ "global::System.Threading.CancellationToken "
+ "cancellationToken = "
+ "default(global::System.Threading.CancellationToken))\n",
"methodname", method->name(), "request",
GetClassName(method->input_type()), "response",
GetClassName(method->output_type()));
@@ -492,8 +494,10 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor* service) {
out->Print(
"public virtual $returntype$ "
"$methodname$($request_maybe$grpc::Metadata "
- "headers = null, DateTime? deadline = null, CancellationToken "
- "cancellationToken = default(CancellationToken))\n",
+ "headers = null, global::System.DateTime? deadline = null, "
+ "global::System.Threading.CancellationToken "
+ "cancellationToken = "
+ "default(global::System.Threading.CancellationToken))\n",
"methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method), "returntype",
GetMethodReturnTypeClient(method));
@@ -675,9 +679,6 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client,
out.Print("#pragma warning disable 1591\n");
out.Print("#region Designer generated code\n");
out.Print("\n");
- out.Print("using System;\n");
- out.Print("using System.Threading;\n");
- out.Print("using System.Threading.Tasks;\n");
out.Print("using grpc = global::Grpc.Core;\n");
out.Print("\n");
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index ab7d869758..ffdeb8f6b0 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -212,37 +212,49 @@ void PrintMethodImplementations(Printer* printer,
return output;
}
-::grpc::string GetHeader(const ServiceDescriptor* service) {
+::grpc::string GetProtocol(const ServiceDescriptor* service) {
::grpc::string output;
- {
- // Scope the output stream so it closes and finalizes output to the string.
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- Printer printer(&output_stream, '$');
-
- map< ::grpc::string, ::grpc::string> vars = {
- {"service_class", ServiceClassName(service)}};
- printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ Printer printer(&output_stream, '$');
- for (int i = 0; i < service->method_count(); i++) {
- PrintMethodDeclarations(&printer, service->method(i));
- }
- printer.Print("@end\n\n");
+ map< ::grpc::string, ::grpc::string> vars = {
+ {"service_class", ServiceClassName(service)}};
- printer.Print(
- "/**\n"
- " * Basic service implementation, over gRPC, that only does\n"
- " * marshalling and parsing.\n"
- " */\n");
- printer.Print(vars,
- "@interface $service_class$ :"
- " GRPCProtoService<$service_class$>\n");
- printer.Print(
- "- (instancetype)initWithHost:(NSString *)host"
- " NS_DESIGNATED_INITIALIZER;\n");
- printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n");
- printer.Print("@end\n");
+ printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintMethodDeclarations(&printer, service->method(i));
}
+ printer.Print("@end\n\n");
+
+ return output;
+}
+
+::grpc::string GetInterface(const ServiceDescriptor* service) {
+ ::grpc::string output;
+
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ Printer printer(&output_stream, '$');
+
+ map< ::grpc::string, ::grpc::string> vars = {
+ {"service_class", ServiceClassName(service)}};
+
+ printer.Print(vars,
+ "/**\n"
+ " * Basic service implementation, over gRPC, that only does\n"
+ " * marshalling and parsing.\n"
+ " */\n");
+ printer.Print(vars,
+ "@interface $service_class$ :"
+ " GRPCProtoService<$service_class$>\n");
+ printer.Print(
+ "- (instancetype)initWithHost:(NSString *)host"
+ " NS_DESIGNATED_INITIALIZER;\n");
+ printer.Print("+ (instancetype)serviceWithHost:(NSString *)host;\n");
+ printer.Print("@end\n");
+
return output;
}
@@ -258,26 +270,32 @@ void PrintMethodImplementations(Printer* printer,
{"service_class", ServiceClassName(service)},
{"package", service->file()->package()}};
- printer.Print(vars, "@implementation $service_class$\n\n");
+ printer.Print(vars,
+ "@implementation $service_class$\n\n"
+ "// Designated initializer\n"
+ "- (instancetype)initWithHost:(NSString *)host {\n"
+ " self = [super initWithHost:host\n"
+ " packageName:@\"$package$\"\n"
+ " serviceName:@\"$service_name$\"];\n"
+ " return self;\n"
+ "}\n\n");
- printer.Print("// Designated initializer\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
- printer.Print(
- vars,
- " return (self = [super initWithHost:host"
- " packageName:@\"$package$\" serviceName:@\"$service_name$\"]);\n");
- printer.Print("}\n\n");
printer.Print(
"// Override superclass initializer to disallow different"
- " package and service names.\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host\n");
- printer.Print(" packageName:(NSString *)packageName\n");
- printer.Print(" serviceName:(NSString *)serviceName {\n");
- printer.Print(" return [self initWithHost:host];\n");
- printer.Print("}\n\n");
- printer.Print("+ (instancetype)serviceWithHost:(NSString *)host {\n");
- printer.Print(" return [[self alloc] initWithHost:host];\n");
- printer.Print("}\n\n\n");
+ " package and service names.\n"
+ "- (instancetype)initWithHost:(NSString *)host\n"
+ " packageName:(NSString *)packageName\n"
+ " serviceName:(NSString *)serviceName {\n"
+ " return [self initWithHost:host];\n"
+ "}\n\n");
+
+ printer.Print(
+ "#pragma mark - Class Methods\n\n"
+ "+ (instancetype)serviceWithHost:(NSString *)host {\n"
+ " return [[self alloc] initWithHost:host];\n"
+ "}\n\n");
+
+ printer.Print("#pragma mark - Method Implementations\n\n");
for (int i = 0; i < service->method_count(); i++) {
PrintMethodImplementations(&printer, service->method(i));
diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h
index d3aed76c4f..eb1c7ff005 100644
--- a/src/compiler/objective_c_generator.h
+++ b/src/compiler/objective_c_generator.h
@@ -31,9 +31,13 @@ using ::grpc::string;
// Returns forward declaration of classes in the generated header file.
string GetAllMessageClasses(const FileDescriptor* file);
-// Returns the content to be included in the "global_scope" insertion point of
-// the generated header file.
-string GetHeader(const ServiceDescriptor* service);
+// Returns the content to be included defining the @protocol segment at the
+// insertion point of the generated implementation file.
+string GetProtocol(const ServiceDescriptor* service);
+
+// Returns the content to be included defining the @interface segment at the
+// insertion point of the generated implementation file.
+string GetInterface(const ServiceDescriptor* service);
// Returns the content to be included in the "global_scope" insertion point of
// the generated implementation file.
diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h
index 4004e6aef8..a284da97f4 100644
--- a/src/compiler/objective_c_generator_helpers.h
+++ b/src/compiler/objective_c_generator_helpers.h
@@ -40,5 +40,45 @@ inline string ServiceClassName(const ServiceDescriptor* service) {
string prefix = file->options().objc_class_prefix();
return prefix + service->name();
}
+
+inline ::grpc::string LocalImport(const ::grpc::string& import) {
+ return ::grpc::string("#import \"" + import + "\"\n");
+}
+
+inline ::grpc::string SystemImport(const ::grpc::string& import) {
+ return ::grpc::string("#import <" + import + ">\n");
+}
+
+inline ::grpc::string PreprocConditional(::grpc::string symbol, bool invert) {
+ return invert ? "!defined(" + symbol + ") || !" + symbol
+ : "defined(" + symbol + ") && " + symbol;
+}
+
+inline ::grpc::string PreprocIf(const ::grpc::string& symbol,
+ const ::grpc::string& if_true) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, false) + "\n" +
+ if_true + "#endif\n");
+}
+
+inline ::grpc::string PreprocIfNot(const ::grpc::string& symbol,
+ const ::grpc::string& if_true) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, true) + "\n" +
+ if_true + "#endif\n");
+}
+
+inline ::grpc::string PreprocIfElse(const ::grpc::string& symbol,
+ const ::grpc::string& if_true,
+ const ::grpc::string& if_false) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, false) + "\n" +
+ if_true + "#else\n" + if_false + "#endif\n");
+}
+
+inline ::grpc::string PreprocIfNotElse(const ::grpc::string& symbol,
+ const ::grpc::string& if_true,
+ const ::grpc::string& if_false) {
+ return ::grpc::string("#if " + PreprocConditional(symbol, true) + "\n" +
+ if_true + "#else\n" + if_false + "#endif\n");
+}
+
} // namespace grpc_objective_c_generator
#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index d5d488e84d..76703d79cd 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -29,12 +29,42 @@
using ::google::protobuf::compiler::objectivec::
IsProtobufLibraryBundledProtoFile;
using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
+using ::grpc_objective_c_generator::LocalImport;
+using ::grpc_objective_c_generator::PreprocIfElse;
+using ::grpc_objective_c_generator::PreprocIfNot;
+using ::grpc_objective_c_generator::SystemImport;
+
+namespace {
+
+inline ::grpc::string ImportProtoHeaders(
+ const grpc::protobuf::FileDescriptor* dep, const char* indent) {
+ ::grpc::string header = grpc_objective_c_generator::MessageHeaderName(dep);
+
+ if (!IsProtobufLibraryBundledProtoFile(dep)) {
+ return indent + LocalImport(header);
+ }
+
+ ::grpc::string base_name = header;
+ grpc_generator::StripPrefix(&base_name, "google/protobuf/");
+ // create the import code snippet
+ ::grpc::string framework_header =
+ ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name;
+
+ static const ::grpc::string kFrameworkImportsCondition =
+ "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS";
+ return PreprocIfElse(kFrameworkImportsCondition,
+ indent + SystemImport(framework_header),
+ indent + LocalImport(header));
+}
+
+} // namespace
class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
public:
ObjectiveCGrpcGenerator() {}
virtual ~ObjectiveCGrpcGenerator() {}
+ public:
virtual bool Generate(const grpc::protobuf::FileDescriptor* file,
const ::grpc::string& parameter,
grpc::protobuf::compiler::GeneratorContext* context,
@@ -44,97 +74,68 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
return true;
}
+ static const ::grpc::string kNonNullBegin = "NS_ASSUME_NONNULL_BEGIN\n";
+ static const ::grpc::string kNonNullEnd = "NS_ASSUME_NONNULL_END\n";
+ static const ::grpc::string kProtocolOnly = "GPB_GRPC_PROTOCOL_ONLY";
+ static const ::grpc::string kForwardDeclare =
+ "GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO";
+
::grpc::string file_name =
google::protobuf::compiler::objectivec::FilePath(file);
- ::grpc::string prefix = file->options().objc_class_prefix();
{
// Generate .pbrpc.h
- ::grpc::string imports =
- ::grpc::string("#if !GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO\n") +
- "#import \"" + file_name +
- ".pbobjc.h\"\n"
- "#endif\n\n"
- "#import <ProtoRPC/ProtoService.h>\n"
- "#import <ProtoRPC/ProtoRPC.h>\n"
- "#import <RxLibrary/GRXWriteable.h>\n"
- "#import <RxLibrary/GRXWriter.h>\n";
-
- ::grpc::string proto_imports;
- proto_imports += "#if GPB_GRPC_FORWARD_DECLARE_MESSAGE_PROTO\n" +
- grpc_objective_c_generator::GetAllMessageClasses(file) +
- "#else\n";
+ ::grpc::string imports = LocalImport(file_name + ".pbobjc.h");
+
+ ::grpc::string system_imports = SystemImport("ProtoRPC/ProtoService.h") +
+ SystemImport("ProtoRPC/ProtoRPC.h") +
+ SystemImport("RxLibrary/GRXWriteable.h") +
+ SystemImport("RxLibrary/GRXWriter.h");
+
+ ::grpc::string forward_declarations = "@class GRPCProtoCall;\n\n";
+
+ ::grpc::string class_declarations =
+ grpc_objective_c_generator::GetAllMessageClasses(file);
+
+ ::grpc::string class_imports;
for (int i = 0; i < file->dependency_count(); i++) {
- ::grpc::string header =
- grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
- const grpc::protobuf::FileDescriptor* dependency = file->dependency(i);
- if (IsProtobufLibraryBundledProtoFile(dependency)) {
- ::grpc::string base_name = header;
- grpc_generator::StripPrefix(&base_name, "google/protobuf/");
- // create the import code snippet
- proto_imports +=
- " #if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
- " #import <" +
- ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
- ">\n"
- " #else\n"
- " #import \"" +
- header +
- "\"\n"
- " #endif\n";
- } else {
- proto_imports += ::grpc::string(" #import \"") + header + "\"\n";
- }
+ class_imports += ImportProtoHeaders(file->dependency(i), " ");
}
- proto_imports += "#endif\n";
- ::grpc::string declarations;
+ ::grpc::string protocols;
for (int i = 0; i < file->service_count(); i++) {
const grpc::protobuf::ServiceDescriptor* service = file->service(i);
- declarations += grpc_objective_c_generator::GetHeader(service);
+ protocols += grpc_objective_c_generator::GetProtocol(service);
}
- static const ::grpc::string kNonNullBegin =
- "\nNS_ASSUME_NONNULL_BEGIN\n\n";
- static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n";
+ ::grpc::string interfaces;
+ for (int i = 0; i < file->service_count(); i++) {
+ const grpc::protobuf::ServiceDescriptor* service = file->service(i);
+ interfaces += grpc_objective_c_generator::GetInterface(service);
+ }
Write(context, file_name + ".pbrpc.h",
- imports + '\n' + proto_imports + '\n' + kNonNullBegin +
- declarations + kNonNullEnd);
+ PreprocIfNot(kForwardDeclare, imports) + "\n" +
+ PreprocIfNot(kProtocolOnly, system_imports) + "\n" +
+ PreprocIfElse(kForwardDeclare, class_declarations,
+ class_imports) +
+ "\n" + forward_declarations + "\n" + kNonNullBegin + "\n" +
+ protocols + "\n" + PreprocIfNot(kProtocolOnly, interfaces) +
+ "\n" + kNonNullEnd + "\n");
}
{
// Generate .pbrpc.m
- ::grpc::string imports = ::grpc::string("#import \"") + file_name +
- ".pbrpc.h\"\n"
- "#import \"" +
- file_name +
- ".pbobjc.h\"\n\n"
- "#import <ProtoRPC/ProtoRPC.h>\n"
- "#import <RxLibrary/GRXWriter+Immediate.h>\n";
+ ::grpc::string imports = LocalImport(file_name + ".pbrpc.h") +
+ LocalImport(file_name + ".pbobjc.h") +
+ SystemImport("ProtoRPC/ProtoRPC.h") +
+ SystemImport("RxLibrary/GRXWriter+Immediate.h");
+
+ ::grpc::string class_imports;
for (int i = 0; i < file->dependency_count(); i++) {
- ::grpc::string header =
- grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
- const grpc::protobuf::FileDescriptor* dependency = file->dependency(i);
- if (IsProtobufLibraryBundledProtoFile(dependency)) {
- ::grpc::string base_name = header;
- grpc_generator::StripPrefix(&base_name, "google/protobuf/");
- // create the import code snippet
- imports +=
- "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
- " #import <" +
- ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
- ">\n"
- "#else\n"
- " #import \"" +
- header +
- "\"\n"
- "#endif\n";
- } else {
- imports += ::grpc::string("#import \"") + header + "\"\n";
- }
+ class_imports += ImportProtoHeaders(file->dependency(i), "");
}
::grpc::string definitions;
@@ -143,7 +144,9 @@ class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
definitions += grpc_objective_c_generator::GetSource(service);
}
- Write(context, file_name + ".pbrpc.m", imports + '\n' + definitions);
+ Write(context, file_name + ".pbrpc.m",
+ PreprocIfNot(kProtocolOnly,
+ imports + "\n" + class_imports + "\n" + definitions));
}
return true;
diff --git a/src/core/ext/census/grpc_context.cc b/src/core/ext/census/grpc_context.cc
index 069e8f1486..599a798dda 100644
--- a/src/core/ext/census/grpc_context.cc
+++ b/src/core/ext/census/grpc_context.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/census.h>
#include <grpc/grpc.h>
#include "src/core/lib/surface/api_trace.h"
diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc
index ee90b499eb..3e2faa57bc 100644
--- a/src/core/ext/filters/client_channel/backup_poller.cc
+++ b/src/core/ext/filters/client_channel/backup_poller.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include <grpc/grpc.h>
@@ -125,13 +127,7 @@ static void run_poller(void* arg, grpc_error* error) {
&p->run_poller_closure);
}
-void grpc_client_channel_start_backup_polling(
- grpc_pollset_set* interested_parties) {
- gpr_once_init(&g_once, init_globals);
- if (g_poll_interval_ms == 0) {
- return;
- }
- gpr_mu_lock(&g_poller_mu);
+static void g_poller_init_locked() {
if (g_poller == nullptr) {
g_poller = static_cast<backup_poller*>(gpr_zalloc(sizeof(backup_poller)));
g_poller->pollset =
@@ -147,7 +143,16 @@ void grpc_client_channel_start_backup_polling(
grpc_core::ExecCtx::Get()->Now() + g_poll_interval_ms,
&g_poller->run_poller_closure);
}
+}
+void grpc_client_channel_start_backup_polling(
+ grpc_pollset_set* interested_parties) {
+ gpr_once_init(&g_once, init_globals);
+ if (g_poll_interval_ms == 0) {
+ return;
+ }
+ gpr_mu_lock(&g_poller_mu);
+ g_poller_init_locked();
gpr_ref(&g_poller->refs);
/* Get a reference to g_poller->pollset before releasing g_poller_mu to make
* TSAN happy. Otherwise, reading from g_poller (i.e g_poller->pollset) after
diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h
index 551e0331dc..7285b9b93e 100644
--- a/src/core/ext/filters/client_channel/backup_poller.h
+++ b/src/core/ext/filters/client_channel/backup_poller.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_BACKUP_POLLER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_BACKUP_POLLER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/filters/client_channel/channel_connectivity.cc b/src/core/ext/filters/client_channel/channel_connectivity.cc
index 31a5c31124..37860e82e3 100644
--- a/src/core/ext/filters/client_channel/channel_connectivity.cc
+++ b/src/core/ext/filters/client_channel/channel_connectivity.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/channel.h"
#include <inttypes.h>
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 50d562f946..90b93fbe23 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -21,6 +21,7 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
@@ -33,153 +34,74 @@
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/method_params.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
+#include "src/core/ext/filters/client_channel/status_util.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/deadline/deadline_filter.h"
+#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/gprpp/manual_constructor.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/transport/connectivity_state.h"
+#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/service_config.h"
#include "src/core/lib/transport/static_metadata.h"
+#include "src/core/lib/transport/status_metadata.h"
+
+using grpc_core::internal::ClientChannelMethodParams;
/* Client channel implementation */
+// By default, we buffer 256 KiB per RPC for retries.
+// TODO(roth): Do we have any data to suggest a better value?
+#define DEFAULT_PER_RPC_RETRY_BUFFER_SIZE (256 << 10)
+
+// This value was picked arbitrarily. It can be changed if there is
+// any even moderately compelling reason to do so.
+#define RETRY_BACKOFF_JITTER 0.2
+
grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel");
/*************************************************************************
- * METHOD-CONFIG TABLE
+ * CHANNEL-WIDE FUNCTIONS
*/
-typedef enum {
- /* zero so it can be default initialized */
- WAIT_FOR_READY_UNSET = 0,
- WAIT_FOR_READY_FALSE,
- WAIT_FOR_READY_TRUE
-} wait_for_ready_value;
-
-typedef struct {
- gpr_refcount refs;
- grpc_millis timeout;
- wait_for_ready_value wait_for_ready;
-} method_parameters;
-
-static method_parameters* method_parameters_ref(
- method_parameters* method_params) {
- gpr_ref(&method_params->refs);
- return method_params;
-}
-
-static void method_parameters_unref(method_parameters* method_params) {
- if (gpr_unref(&method_params->refs)) {
- gpr_free(method_params);
- }
-}
-
-// Wrappers to pass to grpc_service_config_create_method_config_table().
-static void* method_parameters_ref_wrapper(void* value) {
- return method_parameters_ref(static_cast<method_parameters*>(value));
-}
-static void method_parameters_unref_wrapper(void* value) {
- method_parameters_unref(static_cast<method_parameters*>(value));
-}
-
-static bool parse_wait_for_ready(grpc_json* field,
- wait_for_ready_value* wait_for_ready) {
- if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
- return false;
- }
- *wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE
- : WAIT_FOR_READY_FALSE;
- return true;
-}
-
-static bool parse_timeout(grpc_json* field, grpc_millis* timeout) {
- if (field->type != GRPC_JSON_STRING) return false;
- size_t len = strlen(field->value);
- if (field->value[len - 1] != 's') return false;
- char* buf = gpr_strdup(field->value);
- buf[len - 1] = '\0'; // Remove trailing 's'.
- char* decimal_point = strchr(buf, '.');
- int nanos = 0;
- if (decimal_point != nullptr) {
- *decimal_point = '\0';
- nanos = gpr_parse_nonnegative_int(decimal_point + 1);
- if (nanos == -1) {
- gpr_free(buf);
- return false;
- }
- int num_digits = static_cast<int>(strlen(decimal_point + 1));
- if (num_digits > 9) { // We don't accept greater precision than nanos.
- gpr_free(buf);
- return false;
- }
- for (int i = 0; i < (9 - num_digits); ++i) {
- nanos *= 10;
- }
- }
- int seconds = decimal_point == buf ? 0 : gpr_parse_nonnegative_int(buf);
- gpr_free(buf);
- if (seconds == -1) return false;
- *timeout = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
- return true;
-}
-
-static void* method_parameters_create_from_json(const grpc_json* json) {
- wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET;
- grpc_millis timeout = 0;
- for (grpc_json* field = json->child; field != nullptr; field = field->next) {
- if (field->key == nullptr) continue;
- if (strcmp(field->key, "waitForReady") == 0) {
- if (wait_for_ready != WAIT_FOR_READY_UNSET) return nullptr; // Duplicate.
- if (!parse_wait_for_ready(field, &wait_for_ready)) return nullptr;
- } else if (strcmp(field->key, "timeout") == 0) {
- if (timeout > 0) return nullptr; // Duplicate.
- if (!parse_timeout(field, &timeout)) return nullptr;
- }
- }
- method_parameters* value =
- static_cast<method_parameters*>(gpr_malloc(sizeof(method_parameters)));
- gpr_ref_init(&value->refs, 1);
- value->timeout = timeout;
- value->wait_for_ready = wait_for_ready;
- return value;
-}
-
struct external_connectivity_watcher;
-/*************************************************************************
- * CHANNEL-WIDE FUNCTIONS
- */
+typedef grpc_core::SliceHashTable<
+ grpc_core::RefCountedPtr<ClientChannelMethodParams>>
+ MethodParamsTable;
typedef struct client_channel_channel_data {
- /** resolver for this channel */
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver;
- /** have we started resolving this channel */
bool started_resolving;
- /** is deadline checking enabled? */
bool deadline_checking_enabled;
- /** client channel factory */
grpc_client_channel_factory* client_channel_factory;
+ bool enable_retries;
+ size_t per_rpc_retry_buffer_size;
/** combiner protecting all variables below in this data structure */
grpc_combiner* combiner;
/** currently active load balancer */
- grpc_lb_policy* lb_policy;
+ grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> lb_policy;
/** retry throttle data */
grpc_server_retry_throttle_data* retry_throttle_data;
/** maps method names to method_parameters structs */
- grpc_slice_hash_table* method_params_table;
+ grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
/** incoming resolver result - set by resolver.next() */
grpc_channel_args* resolver_result;
/** a list of closures that are all waiting for resolver result to come in */
@@ -200,7 +122,7 @@ typedef struct client_channel_channel_data {
gpr_mu external_connectivity_watcher_list_mu;
struct external_connectivity_watcher* external_connectivity_watcher_list_head;
- /* the following properties are guarded by a mutex since API's require them
+ /* the following properties are guarded by a mutex since APIs require them
to be instantaneously available */
gpr_mu info_mu;
char* info_lb_policy_name;
@@ -212,7 +134,7 @@ typedef struct {
channel_data* chand;
/** used as an identifier, don't dereference it because the LB policy may be
* non-existing when the callback is run */
- grpc_lb_policy* lb_policy;
+ grpc_core::LoadBalancingPolicy* lb_policy;
grpc_closure closure;
} reresolution_request_args;
@@ -223,11 +145,11 @@ typedef struct {
channel_data* chand;
grpc_closure on_changed;
grpc_connectivity_state state;
- grpc_lb_policy* lb_policy;
+ grpc_core::LoadBalancingPolicy* lb_policy;
} lb_policy_connectivity_watcher;
static void watch_lb_policy_locked(channel_data* chand,
- grpc_lb_policy* lb_policy,
+ grpc_core::LoadBalancingPolicy* lb_policy,
grpc_connectivity_state current_state);
static void set_channel_connectivity_state_locked(channel_data* chand,
@@ -241,15 +163,13 @@ static void set_channel_connectivity_state_locked(channel_data* chand,
if (chand->lb_policy != nullptr) {
if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
/* cancel picks with wait_for_ready=false */
- grpc_lb_policy_cancel_picks_locked(
- chand->lb_policy,
+ chand->lb_policy->CancelMatchingPicksLocked(
/* mask= */ GRPC_INITIAL_METADATA_WAIT_FOR_READY,
/* check= */ 0, GRPC_ERROR_REF(error));
} else if (state == GRPC_CHANNEL_SHUTDOWN) {
/* cancel all picks */
- grpc_lb_policy_cancel_picks_locked(chand->lb_policy,
- /* mask= */ 0, /* check= */ 0,
- GRPC_ERROR_REF(error));
+ chand->lb_policy->CancelMatchingPicksLocked(/* mask= */ 0, /* check= */ 0,
+ GRPC_ERROR_REF(error));
}
}
if (grpc_client_channel_trace.enabled()) {
@@ -263,7 +183,7 @@ static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) {
lb_policy_connectivity_watcher* w =
static_cast<lb_policy_connectivity_watcher*>(arg);
/* check if the notification is for the latest policy */
- if (w->lb_policy == w->chand->lb_policy) {
+ if (w->lb_policy == w->chand->lb_policy.get()) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: lb_policy=%p state changed to %s", w->chand,
w->lb_policy, grpc_connectivity_state_name(w->state));
@@ -279,7 +199,7 @@ static void on_lb_policy_state_changed_locked(void* arg, grpc_error* error) {
}
static void watch_lb_policy_locked(channel_data* chand,
- grpc_lb_policy* lb_policy,
+ grpc_core::LoadBalancingPolicy* lb_policy,
grpc_connectivity_state current_state) {
lb_policy_connectivity_watcher* w =
static_cast<lb_policy_connectivity_watcher*>(gpr_malloc(sizeof(*w)));
@@ -289,8 +209,7 @@ static void watch_lb_policy_locked(channel_data* chand,
grpc_combiner_scheduler(chand->combiner));
w->state = current_state;
w->lb_policy = lb_policy;
- grpc_lb_policy_notify_on_state_change_locked(lb_policy, &w->state,
- &w->on_changed);
+ lb_policy->NotifyOnStateChangeLocked(&w->state, &w->on_changed);
}
static void start_resolving_locked(channel_data* chand) {
@@ -309,9 +228,8 @@ typedef struct {
grpc_server_retry_throttle_data* retry_throttle_data;
} service_config_parsing_state;
-static void parse_retry_throttle_params(const grpc_json* field, void* arg) {
- service_config_parsing_state* parsing_state =
- static_cast<service_config_parsing_state*>(arg);
+static void parse_retry_throttle_params(
+ const grpc_json* field, service_config_parsing_state* parsing_state) {
if (strcmp(field->key, "retryThrottling") == 0) {
if (parsing_state->retry_throttle_data != nullptr) return; // Duplicate.
if (field->type != GRPC_JSON_OBJECT) return;
@@ -371,7 +289,7 @@ static void request_reresolution_locked(void* arg, grpc_error* error) {
channel_data* chand = args->chand;
// If this invocation is for a stale LB policy, treat it as an LB shutdown
// signal.
- if (args->lb_policy != chand->lb_policy || error != GRPC_ERROR_NONE ||
+ if (args->lb_policy != chand->lb_policy.get() || error != GRPC_ERROR_NONE ||
chand->resolver == nullptr) {
GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "re-resolution");
gpr_free(args);
@@ -382,7 +300,7 @@ static void request_reresolution_locked(void* arg, grpc_error* error) {
}
chand->resolver->RequestReresolutionLocked();
// Give back the closure to the LB policy.
- grpc_lb_policy_set_reresolve_closure_locked(chand->lb_policy, &args->closure);
+ chand->lb_policy->SetReresolutionClosureLocked(&args->closure);
}
static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
@@ -391,24 +309,21 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
gpr_log(GPR_DEBUG, "chand=%p: got resolver result: error=%s", chand,
grpc_error_string(error));
}
- // Extract the following fields from the resolver result, if non-NULL.
+ // Extract the following fields from the resolver result, if non-nullptr.
bool lb_policy_updated = false;
+ bool lb_policy_created = false;
char* lb_policy_name_dup = nullptr;
bool lb_policy_name_changed = false;
- grpc_lb_policy* new_lb_policy = nullptr;
+ grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> new_lb_policy;
char* service_config_json = nullptr;
grpc_server_retry_throttle_data* retry_throttle_data = nullptr;
- grpc_slice_hash_table* method_params_table = nullptr;
+ grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
if (chand->resolver_result != nullptr) {
if (chand->resolver != nullptr) {
// Find LB policy name.
- const char* lb_policy_name = nullptr;
const grpc_arg* channel_arg = grpc_channel_args_find(
chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
- if (channel_arg != nullptr) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- lb_policy_name = channel_arg->value.string;
- }
+ const char* lb_policy_name = grpc_channel_arg_get_string(channel_arg);
// Special case: If at least one balancer address is present, we use
// the grpclb policy, regardless of what the resolver actually specified.
channel_arg =
@@ -437,10 +352,6 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
// Use pick_first if nothing was specified and we didn't select grpclb
// above.
if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
- grpc_lb_policy_args lb_policy_args;
- lb_policy_args.args = chand->resolver_result;
- lb_policy_args.client_channel_factory = chand->client_channel_factory;
- lb_policy_args.combiner = chand->combiner;
// Check to see if we're already using the right LB policy.
// Note: It's safe to use chand->info_lb_policy_name here without
// taking a lock on chand->info_mu, because this function is the
@@ -452,59 +363,65 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
if (chand->lb_policy != nullptr && !lb_policy_name_changed) {
// Continue using the same LB policy. Update with new addresses.
lb_policy_updated = true;
- grpc_lb_policy_update_locked(chand->lb_policy, &lb_policy_args);
+ chand->lb_policy->UpdateLocked(*chand->resolver_result);
} else {
// Instantiate new LB policy.
- new_lb_policy = grpc_lb_policy_create(lb_policy_name, &lb_policy_args);
+ grpc_core::LoadBalancingPolicy::Args lb_policy_args;
+ lb_policy_args.combiner = chand->combiner;
+ lb_policy_args.client_channel_factory = chand->client_channel_factory;
+ lb_policy_args.args = chand->resolver_result;
+ new_lb_policy =
+ grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
+ lb_policy_name, lb_policy_args);
if (new_lb_policy == nullptr) {
gpr_log(GPR_ERROR, "could not create LB policy \"%s\"",
lb_policy_name);
} else {
+ lb_policy_created = true;
reresolution_request_args* args =
static_cast<reresolution_request_args*>(
gpr_zalloc(sizeof(*args)));
args->chand = chand;
- args->lb_policy = new_lb_policy;
+ args->lb_policy = new_lb_policy.get();
GRPC_CLOSURE_INIT(&args->closure, request_reresolution_locked, args,
grpc_combiner_scheduler(chand->combiner));
GRPC_CHANNEL_STACK_REF(chand->owning_stack, "re-resolution");
- grpc_lb_policy_set_reresolve_closure_locked(new_lb_policy,
- &args->closure);
+ new_lb_policy->SetReresolutionClosureLocked(&args->closure);
}
}
+ // Before we clean up, save a copy of lb_policy_name, since it might
+ // be pointing to data inside chand->resolver_result.
+ // The copy will be saved in chand->lb_policy_name below.
+ lb_policy_name_dup = gpr_strdup(lb_policy_name);
// Find service config.
channel_arg = grpc_channel_args_find(chand->resolver_result,
GRPC_ARG_SERVICE_CONFIG);
- if (channel_arg != nullptr) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- service_config_json = gpr_strdup(channel_arg->value.string);
- grpc_service_config* service_config =
- grpc_service_config_create(service_config_json);
+ service_config_json =
+ gpr_strdup(grpc_channel_arg_get_string(channel_arg));
+ if (service_config_json != nullptr) {
+ grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
+ grpc_core::ServiceConfig::Create(service_config_json);
if (service_config != nullptr) {
- channel_arg = grpc_channel_args_find(chand->resolver_result,
- GRPC_ARG_SERVER_URI);
- GPR_ASSERT(channel_arg != nullptr);
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- grpc_uri* uri = grpc_uri_parse(channel_arg->value.string, true);
- GPR_ASSERT(uri->path[0] != '\0');
- service_config_parsing_state parsing_state;
- memset(&parsing_state, 0, sizeof(parsing_state));
- parsing_state.server_name =
- uri->path[0] == '/' ? uri->path + 1 : uri->path;
- grpc_service_config_parse_global_params(
- service_config, parse_retry_throttle_params, &parsing_state);
- grpc_uri_destroy(uri);
- retry_throttle_data = parsing_state.retry_throttle_data;
- method_params_table = grpc_service_config_create_method_config_table(
- service_config, method_parameters_create_from_json,
- method_parameters_ref_wrapper, method_parameters_unref_wrapper);
- grpc_service_config_destroy(service_config);
+ if (chand->enable_retries) {
+ channel_arg = grpc_channel_args_find(chand->resolver_result,
+ GRPC_ARG_SERVER_URI);
+ const char* server_uri = grpc_channel_arg_get_string(channel_arg);
+ GPR_ASSERT(server_uri != nullptr);
+ grpc_uri* uri = grpc_uri_parse(server_uri, true);
+ GPR_ASSERT(uri->path[0] != '\0');
+ service_config_parsing_state parsing_state;
+ memset(&parsing_state, 0, sizeof(parsing_state));
+ parsing_state.server_name =
+ uri->path[0] == '/' ? uri->path + 1 : uri->path;
+ service_config->ParseGlobalParams(parse_retry_throttle_params,
+ &parsing_state);
+ grpc_uri_destroy(uri);
+ retry_throttle_data = parsing_state.retry_throttle_data;
+ }
+ method_params_table = service_config->CreateMethodConfigTable(
+ ClientChannelMethodParams::CreateFromJson);
}
}
- // Before we clean up, save a copy of lb_policy_name, since it might
- // be pointing to data inside chand->resolver_result.
- // The copy will be saved in chand->lb_policy_name below.
- lb_policy_name_dup = gpr_strdup(lb_policy_name);
}
grpc_channel_args_destroy(chand->resolver_result);
chand->resolver_result = nullptr;
@@ -517,7 +434,7 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
lb_policy_name_changed ? " (changed)" : "", service_config_json);
}
// Now swap out fields in chand. Note that the new values may still
- // be NULL if (e.g.) the resolver failed to return results or the
+ // be nullptr if (e.g.) the resolver failed to return results or the
// results did not contain the necessary data.
//
// First, swap out the data used by cc_get_channel_info().
@@ -537,29 +454,26 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
}
chand->retry_throttle_data = retry_throttle_data;
// Swap out the method params table.
- if (chand->method_params_table != nullptr) {
- grpc_slice_hash_table_unref(chand->method_params_table);
- }
- chand->method_params_table = method_params_table;
+ chand->method_params_table = std::move(method_params_table);
// If we have a new LB policy or are shutting down (in which case
- // new_lb_policy will be NULL), swap out the LB policy, unreffing the old one
- // and removing its fds from chand->interested_parties. Note that we do NOT do
- // this if either (a) we updated the existing LB policy above or (b) we failed
- // to create the new LB policy (in which case we want to continue using the
- // most recent one we had).
+ // new_lb_policy will be nullptr), swap out the LB policy, unreffing the
+ // old one and removing its fds from chand->interested_parties.
+ // Note that we do NOT do this if either (a) we updated the existing
+ // LB policy above or (b) we failed to create the new LB policy (in
+ // which case we want to continue using the most recent one we had).
if (new_lb_policy != nullptr || error != GRPC_ERROR_NONE ||
chand->resolver == nullptr) {
if (chand->lb_policy != nullptr) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: unreffing lb_policy=%p", chand,
- chand->lb_policy);
+ chand->lb_policy.get());
}
- grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties,
+ grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
chand->interested_parties);
- grpc_lb_policy_shutdown_locked(chand->lb_policy, new_lb_policy);
- GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel");
+ chand->lb_policy->HandOffPendingPicksLocked(new_lb_policy.get());
+ chand->lb_policy.reset();
}
- chand->lb_policy = new_lb_policy;
+ chand->lb_policy = std::move(new_lb_policy);
}
// Now that we've swapped out the relevant fields of chand, check for
// error or shutdown.
@@ -578,30 +492,29 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Got resolver result after disconnection", &error, 1),
"resolver_gone");
- GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "resolver");
grpc_closure_list_fail_all(&chand->waiting_for_resolver_result_closures,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Channel disconnected", &error, 1));
GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
+ GRPC_CHANNEL_STACK_UNREF(chand->owning_stack, "resolver");
} else { // Not shutting down.
grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE;
grpc_error* state_error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy");
- if (new_lb_policy != nullptr) {
+ if (lb_policy_created) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p: initializing new LB policy", chand);
}
GRPC_ERROR_UNREF(state_error);
- state =
- grpc_lb_policy_check_connectivity_locked(new_lb_policy, &state_error);
- grpc_pollset_set_add_pollset_set(new_lb_policy->interested_parties,
+ state = chand->lb_policy->CheckConnectivityLocked(&state_error);
+ grpc_pollset_set_add_pollset_set(chand->lb_policy->interested_parties(),
chand->interested_parties);
GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
if (chand->exit_idle_when_lb_policy_arrives) {
- grpc_lb_policy_exit_idle_locked(new_lb_policy);
+ chand->lb_policy->ExitIdleLocked();
chand->exit_idle_when_lb_policy_arrives = false;
}
- watch_lb_policy_locked(chand, new_lb_policy, state);
+ watch_lb_policy_locked(chand, chand->lb_policy.get(), state);
}
if (!lb_policy_updated) {
set_channel_connectivity_state_locked(
@@ -636,8 +549,8 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
op->send_ping.on_ack,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
} else {
- grpc_lb_policy_ping_one_locked(
- chand->lb_policy, op->send_ping.on_initiate, op->send_ping.on_ack);
+ chand->lb_policy->PingOneLocked(op->send_ping.on_initiate,
+ op->send_ping.on_ack);
op->bind_pollset = nullptr;
}
op->send_ping.on_initiate = nullptr;
@@ -656,11 +569,9 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
GRPC_CLOSURE_LIST_SCHED(&chand->waiting_for_resolver_result_closures);
}
if (chand->lb_policy != nullptr) {
- grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties,
+ grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
chand->interested_parties);
- grpc_lb_policy_shutdown_locked(chand->lb_policy, nullptr);
- GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel");
- chand->lb_policy = nullptr;
+ chand->lb_policy.reset();
}
}
GRPC_ERROR_UNREF(op->disconnect_with_error);
@@ -728,9 +639,17 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem,
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
grpc_client_channel_start_backup_polling(chand->interested_parties);
+ // Record max per-RPC retry buffer size.
+ const grpc_arg* arg = grpc_channel_args_find(
+ args->channel_args, GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE);
+ chand->per_rpc_retry_buffer_size = (size_t)grpc_channel_arg_get_integer(
+ arg, {DEFAULT_PER_RPC_RETRY_BUFFER_SIZE, 0, INT_MAX});
+ // Record enable_retries.
+ arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES);
+ chand->enable_retries = grpc_channel_arg_get_bool(arg, true);
// Record client channel factory.
- const grpc_arg* arg = grpc_channel_args_find(args->channel_args,
- GRPC_ARG_CLIENT_CHANNEL_FACTORY);
+ arg = grpc_channel_args_find(args->channel_args,
+ GRPC_ARG_CLIENT_CHANNEL_FACTORY);
if (arg == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Missing client channel factory in args for client channel filter");
@@ -790,10 +709,9 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) {
grpc_client_channel_factory_unref(chand->client_channel_factory);
}
if (chand->lb_policy != nullptr) {
- grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties,
+ grpc_pollset_set_del_pollset_set(chand->lb_policy->interested_parties(),
chand->interested_parties);
- grpc_lb_policy_shutdown_locked(chand->lb_policy, nullptr);
- GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel");
+ chand->lb_policy.reset();
}
gpr_free(chand->info_lb_policy_name);
gpr_free(chand->info_service_config_json);
@@ -801,7 +719,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) {
grpc_server_retry_throttle_data_unref(chand->retry_throttle_data);
}
if (chand->method_params_table != nullptr) {
- grpc_slice_hash_table_unref(chand->method_params_table);
+ chand->method_params_table.reset();
}
grpc_client_channel_stop_backup_polling(chand->interested_parties);
grpc_connectivity_state_destroy(&chand->state_tracker);
@@ -816,15 +734,122 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) {
*/
// Max number of batches that can be pending on a call at any given
-// time. This includes:
+// time. This includes one batch for each of the following ops:
// recv_initial_metadata
// send_initial_metadata
// recv_message
// send_message
// recv_trailing_metadata
// send_trailing_metadata
-// We also add room for a single cancel_stream batch.
-#define MAX_WAITING_BATCHES 7
+#define MAX_PENDING_BATCHES 6
+
+// Retry support:
+//
+// In order to support retries, we act as a proxy for stream op batches.
+// When we get a batch from the surface, we add it to our list of pending
+// batches, and we then use those batches to construct separate "child"
+// batches to be started on the subchannel call. When the child batches
+// return, we then decide which pending batches have been completed and
+// schedule their callbacks accordingly. If a subchannel call fails and
+// we want to retry it, we do a new pick and start again, constructing
+// new "child" batches for the new subchannel call.
+//
+// Note that retries are committed when receiving data from the server
+// (except for Trailers-Only responses). However, there may be many
+// send ops started before receiving any data, so we may have already
+// completed some number of send ops (and returned the completions up to
+// the surface) by the time we realize that we need to retry. To deal
+// with this, we cache data for send ops, so that we can replay them on a
+// different subchannel call even after we have completed the original
+// batches.
+//
+// There are two sets of data to maintain:
+// - In call_data (in the parent channel), we maintain a list of pending
+// ops and cached data for send ops.
+// - In the subchannel call, we maintain state to indicate what ops have
+// already been sent down to that call.
+//
+// When constructing the "child" batches, we compare those two sets of
+// data to see which batches need to be sent to the subchannel call.
+
+// TODO(roth): In subsequent PRs:
+// - add support for transparent retries (including initial metadata)
+// - figure out how to record stats in census for retries
+// (census filter is on top of this one)
+// - add census stats for retries
+
+// State used for starting a retryable batch on a subchannel call.
+// This provides its own grpc_transport_stream_op_batch and other data
+// structures needed to populate the ops in the batch.
+// We allocate one struct on the arena for each attempt at starting a
+// batch on a given subchannel call.
+typedef struct {
+ gpr_refcount refs;
+ grpc_call_element* elem;
+ grpc_subchannel_call* subchannel_call; // Holds a ref.
+ // The batch to use in the subchannel call.
+ // Its payload field points to subchannel_call_retry_state.batch_payload.
+ grpc_transport_stream_op_batch batch;
+ // For send_initial_metadata.
+ // Note that we need to make a copy of the initial metadata for each
+ // subchannel call instead of just referring to the copy in call_data,
+ // because filters in the subchannel stack will probably add entries,
+ // so we need to start in a pristine state for each attempt of the call.
+ grpc_linked_mdelem* send_initial_metadata_storage;
+ grpc_metadata_batch send_initial_metadata;
+ // For send_message.
+ grpc_caching_byte_stream send_message;
+ // For send_trailing_metadata.
+ grpc_linked_mdelem* send_trailing_metadata_storage;
+ grpc_metadata_batch send_trailing_metadata;
+ // For intercepting recv_initial_metadata.
+ grpc_metadata_batch recv_initial_metadata;
+ grpc_closure recv_initial_metadata_ready;
+ bool trailing_metadata_available;
+ // For intercepting recv_message.
+ grpc_closure recv_message_ready;
+ grpc_byte_stream* recv_message;
+ // For intercepting recv_trailing_metadata.
+ grpc_metadata_batch recv_trailing_metadata;
+ grpc_transport_stream_stats collect_stats;
+ // For intercepting on_complete.
+ grpc_closure on_complete;
+} subchannel_batch_data;
+
+// Retry state associated with a subchannel call.
+// Stored in the parent_data of the subchannel call object.
+typedef struct {
+ // subchannel_batch_data.batch.payload points to this.
+ grpc_transport_stream_op_batch_payload batch_payload;
+ // These fields indicate which ops have been started and completed on
+ // this subchannel call.
+ size_t started_send_message_count;
+ size_t completed_send_message_count;
+ size_t started_recv_message_count;
+ size_t completed_recv_message_count;
+ bool started_send_initial_metadata : 1;
+ bool completed_send_initial_metadata : 1;
+ bool started_send_trailing_metadata : 1;
+ bool completed_send_trailing_metadata : 1;
+ bool started_recv_initial_metadata : 1;
+ bool completed_recv_initial_metadata : 1;
+ bool started_recv_trailing_metadata : 1;
+ bool completed_recv_trailing_metadata : 1;
+ // State for callback processing.
+ bool retry_dispatched : 1;
+ bool recv_initial_metadata_ready_deferred : 1;
+ bool recv_message_ready_deferred : 1;
+ grpc_error* recv_initial_metadata_error;
+ grpc_error* recv_message_error;
+} subchannel_call_retry_state;
+
+// Pending batches stored in call data.
+typedef struct {
+ // The pending batch. If nullptr, this slot is empty.
+ grpc_transport_stream_op_batch* batch;
+ // Indicates whether payload for send ops has been cached in call data.
+ bool send_ops_cached;
+} pending_batch;
/** Call data. Holds a pointer to grpc_subchannel_call and the
associated machinery to create such a pointer.
@@ -848,159 +873,1592 @@ typedef struct client_channel_call_data {
grpc_call_combiner* call_combiner;
grpc_server_retry_throttle_data* retry_throttle_data;
- method_parameters* method_params;
+ grpc_core::RefCountedPtr<ClientChannelMethodParams> method_params;
grpc_subchannel_call* subchannel_call;
- grpc_error* error;
- grpc_lb_policy_pick_state pick;
- grpc_closure lb_pick_closure;
- grpc_closure lb_pick_cancel_closure;
+ // Set when we get a cancel_stream op.
+ grpc_error* cancel_error;
+
+ grpc_core::LoadBalancingPolicy::PickState pick;
+ grpc_closure pick_closure;
+ grpc_closure pick_cancel_closure;
grpc_polling_entity* pollent;
- grpc_transport_stream_op_batch* waiting_for_pick_batches[MAX_WAITING_BATCHES];
- size_t waiting_for_pick_batches_count;
- grpc_closure handle_pending_batch_in_call_combiner[MAX_WAITING_BATCHES];
+ // Batches are added to this list when received from above.
+ // They are removed when we are done handling the batch (i.e., when
+ // either we have invoked all of the batch's callbacks or we have
+ // passed the batch down to the subchannel call and are not
+ // intercepting any of its callbacks).
+ pending_batch pending_batches[MAX_PENDING_BATCHES];
+ bool pending_send_initial_metadata : 1;
+ bool pending_send_message : 1;
+ bool pending_send_trailing_metadata : 1;
+
+ // Retry state.
+ bool enable_retries : 1;
+ bool retry_committed : 1;
+ bool last_attempt_got_server_pushback : 1;
+ int num_attempts_completed;
+ size_t bytes_buffered_for_retry;
+ grpc_core::ManualConstructor<grpc_core::BackOff> retry_backoff;
+ grpc_timer retry_timer;
+
+ // Cached data for retrying send ops.
+ // send_initial_metadata
+ bool seen_send_initial_metadata;
+ grpc_linked_mdelem* send_initial_metadata_storage;
+ grpc_metadata_batch send_initial_metadata;
+ uint32_t send_initial_metadata_flags;
+ gpr_atm* peer_string;
+ // send_message
+ // When we get a send_message op, we replace the original byte stream
+ // with a grpc_caching_byte_stream that caches the slices to a
+ // local buffer for use in retries.
+ // Note: We inline the cache for the first 3 send_message ops and use
+ // dynamic allocation after that. This number was essentially picked
+ // at random; it could be changed in the future to tune performance.
+ grpc_core::InlinedVector<grpc_byte_stream_cache*, 3> send_messages;
+ // send_trailing_metadata
+ bool seen_send_trailing_metadata;
+ grpc_linked_mdelem* send_trailing_metadata_storage;
+ grpc_metadata_batch send_trailing_metadata;
+} call_data;
- grpc_transport_stream_op_batch* initial_metadata_batch;
+// Forward declarations.
+static void retry_commit(grpc_call_element* elem,
+ subchannel_call_retry_state* retry_state);
+static void start_internal_recv_trailing_metadata(grpc_call_element* elem);
+static void on_complete(void* arg, grpc_error* error);
+static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored);
+static void pick_after_resolver_result_start_locked(grpc_call_element* elem);
+static void start_pick_locked(void* arg, grpc_error* ignored);
+
+//
+// send op data caching
+//
+
+// Caches data for send ops so that it can be retried later, if not
+// already cached.
+static void maybe_cache_send_ops_for_batch(call_data* calld,
+ pending_batch* pending) {
+ if (pending->send_ops_cached) return;
+ pending->send_ops_cached = true;
+ grpc_transport_stream_op_batch* batch = pending->batch;
+ // Save a copy of metadata for send_initial_metadata ops.
+ if (batch->send_initial_metadata) {
+ calld->seen_send_initial_metadata = true;
+ GPR_ASSERT(calld->send_initial_metadata_storage == nullptr);
+ grpc_metadata_batch* send_initial_metadata =
+ batch->payload->send_initial_metadata.send_initial_metadata;
+ calld->send_initial_metadata_storage = (grpc_linked_mdelem*)gpr_arena_alloc(
+ calld->arena,
+ sizeof(grpc_linked_mdelem) * send_initial_metadata->list.count);
+ grpc_metadata_batch_copy(send_initial_metadata,
+ &calld->send_initial_metadata,
+ calld->send_initial_metadata_storage);
+ calld->send_initial_metadata_flags =
+ batch->payload->send_initial_metadata.send_initial_metadata_flags;
+ calld->peer_string = batch->payload->send_initial_metadata.peer_string;
+ }
+ // Set up cache for send_message ops.
+ if (batch->send_message) {
+ grpc_byte_stream_cache* cache = (grpc_byte_stream_cache*)gpr_arena_alloc(
+ calld->arena, sizeof(grpc_byte_stream_cache));
+ grpc_byte_stream_cache_init(cache,
+ batch->payload->send_message.send_message);
+ calld->send_messages.push_back(cache);
+ }
+ // Save metadata batch for send_trailing_metadata ops.
+ if (batch->send_trailing_metadata) {
+ calld->seen_send_trailing_metadata = true;
+ GPR_ASSERT(calld->send_trailing_metadata_storage == nullptr);
+ grpc_metadata_batch* send_trailing_metadata =
+ batch->payload->send_trailing_metadata.send_trailing_metadata;
+ calld->send_trailing_metadata_storage =
+ (grpc_linked_mdelem*)gpr_arena_alloc(
+ calld->arena,
+ sizeof(grpc_linked_mdelem) * send_trailing_metadata->list.count);
+ grpc_metadata_batch_copy(send_trailing_metadata,
+ &calld->send_trailing_metadata,
+ calld->send_trailing_metadata_storage);
+ }
+}
- grpc_closure on_complete;
- grpc_closure* original_on_complete;
-} call_data;
+// Frees cached send ops that have already been completed after
+// committing the call.
+static void free_cached_send_op_data_after_commit(
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (retry_state->completed_send_initial_metadata) {
+ grpc_metadata_batch_destroy(&calld->send_initial_metadata);
+ }
+ for (size_t i = 0; i < retry_state->completed_send_message_count; ++i) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR
+ "]",
+ chand, calld, i);
+ }
+ grpc_byte_stream_cache_destroy(calld->send_messages[i]);
+ }
+ if (retry_state->completed_send_trailing_metadata) {
+ grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
+ }
+}
-grpc_subchannel_call* grpc_client_channel_get_subchannel_call(
- grpc_call_element* elem) {
+// Frees cached send ops that were completed by the completed batch in
+// batch_data. Used when batches are completed after the call is committed.
+static void free_cached_send_op_data_for_completed_batch(
+ grpc_call_element* elem, subchannel_batch_data* batch_data,
+ subchannel_call_retry_state* retry_state) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
- return calld->subchannel_call;
+ if (batch_data->batch.send_initial_metadata) {
+ grpc_metadata_batch_destroy(&calld->send_initial_metadata);
+ }
+ if (batch_data->batch.send_message) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: destroying calld->send_messages[%" PRIuPTR
+ "]",
+ chand, calld, retry_state->completed_send_message_count - 1);
+ }
+ grpc_byte_stream_cache_destroy(
+ calld->send_messages[retry_state->completed_send_message_count - 1]);
+ }
+ if (batch_data->batch.send_trailing_metadata) {
+ grpc_metadata_batch_destroy(&calld->send_trailing_metadata);
+ }
+}
+
+//
+// pending_batches management
+//
+
+// Returns the index into calld->pending_batches to be used for batch.
+static size_t get_batch_index(grpc_transport_stream_op_batch* batch) {
+ // Note: It is important the send_initial_metadata be the first entry
+ // here, since the code in pick_subchannel_locked() assumes it will be.
+ if (batch->send_initial_metadata) return 0;
+ if (batch->send_message) return 1;
+ if (batch->send_trailing_metadata) return 2;
+ if (batch->recv_initial_metadata) return 3;
+ if (batch->recv_message) return 4;
+ if (batch->recv_trailing_metadata) return 5;
+ GPR_UNREACHABLE_CODE(return (size_t)-1);
}
// This is called via the call combiner, so access to calld is synchronized.
-static void waiting_for_pick_batches_add(
- call_data* calld, grpc_transport_stream_op_batch* batch) {
- if (batch->send_initial_metadata) {
- GPR_ASSERT(calld->initial_metadata_batch == nullptr);
- calld->initial_metadata_batch = batch;
- } else {
- GPR_ASSERT(calld->waiting_for_pick_batches_count < MAX_WAITING_BATCHES);
- calld->waiting_for_pick_batches[calld->waiting_for_pick_batches_count++] =
- batch;
+static void pending_batches_add(grpc_call_element* elem,
+ grpc_transport_stream_op_batch* batch) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ const size_t idx = get_batch_index(batch);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: adding pending batch at index %" PRIuPTR, chand,
+ calld, idx);
+ }
+ pending_batch* pending = &calld->pending_batches[idx];
+ GPR_ASSERT(pending->batch == nullptr);
+ pending->batch = batch;
+ pending->send_ops_cached = false;
+ if (calld->enable_retries) {
+ // Update state in calld about pending batches.
+ // Also check if the batch takes us over the retry buffer limit.
+ // Note: We don't check the size of trailing metadata here, because
+ // gRPC clients do not send trailing metadata.
+ if (batch->send_initial_metadata) {
+ calld->pending_send_initial_metadata = true;
+ calld->bytes_buffered_for_retry += grpc_metadata_batch_size(
+ batch->payload->send_initial_metadata.send_initial_metadata);
+ }
+ if (batch->send_message) {
+ calld->pending_send_message = true;
+ calld->bytes_buffered_for_retry +=
+ batch->payload->send_message.send_message->length;
+ }
+ if (batch->send_trailing_metadata) {
+ calld->pending_send_trailing_metadata = true;
+ }
+ if (calld->bytes_buffered_for_retry > chand->per_rpc_retry_buffer_size) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: exceeded retry buffer size, committing",
+ chand, calld);
+ }
+ subchannel_call_retry_state* retry_state =
+ calld->subchannel_call == nullptr
+ ? nullptr
+ : static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ calld->subchannel_call));
+ retry_commit(elem, retry_state);
+ // If we are not going to retry and have not yet started, pretend
+ // retries are disabled so that we don't bother with retry overhead.
+ if (calld->num_attempts_completed == 0) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: disabling retries before first attempt",
+ chand, calld);
+ }
+ calld->enable_retries = false;
+ }
+ }
+ }
+}
+
+static void pending_batch_clear(call_data* calld, pending_batch* pending) {
+ if (calld->enable_retries) {
+ if (pending->batch->send_initial_metadata) {
+ calld->pending_send_initial_metadata = false;
+ }
+ if (pending->batch->send_message) {
+ calld->pending_send_message = false;
+ }
+ if (pending->batch->send_trailing_metadata) {
+ calld->pending_send_trailing_metadata = false;
+ }
}
+ pending->batch = nullptr;
}
// This is called via the call combiner, so access to calld is synchronized.
static void fail_pending_batch_in_call_combiner(void* arg, grpc_error* error) {
- call_data* calld = static_cast<call_data*>(arg);
- if (calld->waiting_for_pick_batches_count > 0) {
- --calld->waiting_for_pick_batches_count;
- grpc_transport_stream_op_batch_finish_with_failure(
- calld->waiting_for_pick_batches[calld->waiting_for_pick_batches_count],
- GRPC_ERROR_REF(error), calld->call_combiner);
- }
+ grpc_transport_stream_op_batch* batch =
+ static_cast<grpc_transport_stream_op_batch*>(arg);
+ call_data* calld = static_cast<call_data*>(batch->handler_private.extra_arg);
+ // Note: This will release the call combiner.
+ grpc_transport_stream_op_batch_finish_with_failure(
+ batch, GRPC_ERROR_REF(error), calld->call_combiner);
}
// This is called via the call combiner, so access to calld is synchronized.
-static void waiting_for_pick_batches_fail(grpc_call_element* elem,
- grpc_error* error) {
+// If yield_call_combiner is true, assumes responsibility for yielding
+// the call combiner.
+static void pending_batches_fail(grpc_call_element* elem, grpc_error* error,
+ bool yield_call_combiner) {
+ GPR_ASSERT(error != GRPC_ERROR_NONE);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
+ size_t num_batches = 0;
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ if (calld->pending_batches[i].batch != nullptr) ++num_batches;
+ }
gpr_log(GPR_DEBUG,
"chand=%p calld=%p: failing %" PRIuPTR " pending batches: %s",
- elem->channel_data, calld, calld->waiting_for_pick_batches_count,
- grpc_error_string(error));
+ elem->channel_data, calld, num_batches, grpc_error_string(error));
+ }
+ grpc_transport_stream_op_batch*
+ batches[GPR_ARRAY_SIZE(calld->pending_batches)];
+ size_t num_batches = 0;
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ pending_batch* pending = &calld->pending_batches[i];
+ grpc_transport_stream_op_batch* batch = pending->batch;
+ if (batch != nullptr) {
+ batches[num_batches++] = batch;
+ pending_batch_clear(calld, pending);
+ }
}
- for (size_t i = 0; i < calld->waiting_for_pick_batches_count; ++i) {
- GRPC_CLOSURE_INIT(&calld->handle_pending_batch_in_call_combiner[i],
- fail_pending_batch_in_call_combiner, calld,
+ for (size_t i = yield_call_combiner ? 1 : 0; i < num_batches; ++i) {
+ grpc_transport_stream_op_batch* batch = batches[i];
+ batch->handler_private.extra_arg = calld;
+ GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+ fail_pending_batch_in_call_combiner, batch,
grpc_schedule_on_exec_ctx);
- GRPC_CALL_COMBINER_START(
- calld->call_combiner, &calld->handle_pending_batch_in_call_combiner[i],
- GRPC_ERROR_REF(error), "waiting_for_pick_batches_fail");
- }
- if (calld->initial_metadata_batch != nullptr) {
- grpc_transport_stream_op_batch_finish_with_failure(
- calld->initial_metadata_batch, GRPC_ERROR_REF(error),
- calld->call_combiner);
- } else {
- GRPC_CALL_COMBINER_STOP(calld->call_combiner,
- "waiting_for_pick_batches_fail");
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
+ &batch->handler_private.closure,
+ GRPC_ERROR_REF(error), "pending_batches_fail");
+ }
+ if (yield_call_combiner) {
+ if (num_batches > 0) {
+ // Note: This will release the call combiner.
+ grpc_transport_stream_op_batch_finish_with_failure(
+ batches[0], GRPC_ERROR_REF(error), calld->call_combiner);
+ } else {
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner, "pending_batches_fail");
+ }
}
GRPC_ERROR_UNREF(error);
}
// This is called via the call combiner, so access to calld is synchronized.
-static void run_pending_batch_in_call_combiner(void* arg, grpc_error* ignored) {
- call_data* calld = static_cast<call_data*>(arg);
- if (calld->waiting_for_pick_batches_count > 0) {
- --calld->waiting_for_pick_batches_count;
- grpc_subchannel_call_process_op(
- calld->subchannel_call,
- calld->waiting_for_pick_batches[calld->waiting_for_pick_batches_count]);
- }
+static void resume_pending_batch_in_call_combiner(void* arg,
+ grpc_error* ignored) {
+ grpc_transport_stream_op_batch* batch =
+ static_cast<grpc_transport_stream_op_batch*>(arg);
+ grpc_subchannel_call* subchannel_call =
+ static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg);
+ // Note: This will release the call combiner.
+ grpc_subchannel_call_process_op(subchannel_call, batch);
}
// This is called via the call combiner, so access to calld is synchronized.
-static void waiting_for_pick_batches_resume(grpc_call_element* elem) {
+static void pending_batches_resume(grpc_call_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (calld->enable_retries) {
+ start_retriable_subchannel_batches(elem, GRPC_ERROR_NONE);
+ return;
+ }
+ // Retries not enabled; send down batches as-is.
if (grpc_client_channel_trace.enabled()) {
+ size_t num_batches = 0;
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ if (calld->pending_batches[i].batch != nullptr) ++num_batches;
+ }
gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: sending %" PRIuPTR
- " pending batches to subchannel_call=%p",
- chand, calld, calld->waiting_for_pick_batches_count,
- calld->subchannel_call);
- }
- for (size_t i = 0; i < calld->waiting_for_pick_batches_count; ++i) {
- GRPC_CLOSURE_INIT(&calld->handle_pending_batch_in_call_combiner[i],
- run_pending_batch_in_call_combiner, calld,
+ "chand=%p calld=%p: starting %" PRIuPTR
+ " pending batches on subchannel_call=%p",
+ chand, calld, num_batches, calld->subchannel_call);
+ }
+ grpc_transport_stream_op_batch*
+ batches[GPR_ARRAY_SIZE(calld->pending_batches)];
+ size_t num_batches = 0;
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ pending_batch* pending = &calld->pending_batches[i];
+ grpc_transport_stream_op_batch* batch = pending->batch;
+ if (batch != nullptr) {
+ batches[num_batches++] = batch;
+ pending_batch_clear(calld, pending);
+ }
+ }
+ for (size_t i = 1; i < num_batches; ++i) {
+ grpc_transport_stream_op_batch* batch = batches[i];
+ batch->handler_private.extra_arg = calld->subchannel_call;
+ GRPC_CLOSURE_INIT(&batch->handler_private.closure,
+ resume_pending_batch_in_call_combiner, batch,
grpc_schedule_on_exec_ctx);
- GRPC_CALL_COMBINER_START(
- calld->call_combiner, &calld->handle_pending_batch_in_call_combiner[i],
- GRPC_ERROR_NONE, "waiting_for_pick_batches_resume");
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
+ &batch->handler_private.closure, GRPC_ERROR_NONE,
+ "pending_batches_resume");
}
- GPR_ASSERT(calld->initial_metadata_batch != nullptr);
- grpc_subchannel_call_process_op(calld->subchannel_call,
- calld->initial_metadata_batch);
+ GPR_ASSERT(num_batches > 0);
+ // Note: This will release the call combiner.
+ grpc_subchannel_call_process_op(calld->subchannel_call, batches[0]);
}
-// Applies service config to the call. Must be invoked once we know
-// that the resolver has returned results to the channel.
-static void apply_service_config_to_call_locked(grpc_call_element* elem) {
+static void maybe_clear_pending_batch(grpc_call_element* elem,
+ pending_batch* pending) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
+ grpc_transport_stream_op_batch* batch = pending->batch;
+ // We clear the pending batch if all of its callbacks have been
+ // scheduled and reset to nullptr.
+ if (batch->on_complete == nullptr &&
+ (!batch->recv_initial_metadata ||
+ batch->payload->recv_initial_metadata.recv_initial_metadata_ready ==
+ nullptr) &&
+ (!batch->recv_message ||
+ batch->payload->recv_message.recv_message_ready == nullptr)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: clearing pending batch", chand,
+ calld);
+ }
+ pending_batch_clear(calld, pending);
+ }
+}
+
+// Returns true if all ops in the pending batch have been completed.
+static bool pending_batch_is_completed(
+ pending_batch* pending, call_data* calld,
+ subchannel_call_retry_state* retry_state) {
+ if (pending->batch == nullptr || pending->batch->on_complete == nullptr) {
+ return false;
+ }
+ if (pending->batch->send_initial_metadata &&
+ !retry_state->completed_send_initial_metadata) {
+ return false;
+ }
+ if (pending->batch->send_message &&
+ retry_state->completed_send_message_count < calld->send_messages.size()) {
+ return false;
+ }
+ if (pending->batch->send_trailing_metadata &&
+ !retry_state->completed_send_trailing_metadata) {
+ return false;
+ }
+ if (pending->batch->recv_initial_metadata &&
+ !retry_state->completed_recv_initial_metadata) {
+ return false;
+ }
+ if (pending->batch->recv_message &&
+ retry_state->completed_recv_message_count <
+ retry_state->started_recv_message_count) {
+ return false;
+ }
+ if (pending->batch->recv_trailing_metadata &&
+ !retry_state->completed_recv_trailing_metadata) {
+ return false;
+ }
+ return true;
+}
+
+// Returns true if any op in the batch was not yet started.
+static bool pending_batch_is_unstarted(
+ pending_batch* pending, call_data* calld,
+ subchannel_call_retry_state* retry_state) {
+ if (pending->batch == nullptr || pending->batch->on_complete == nullptr) {
+ return false;
+ }
+ if (pending->batch->send_initial_metadata &&
+ !retry_state->started_send_initial_metadata) {
+ return true;
+ }
+ if (pending->batch->send_message &&
+ retry_state->started_send_message_count < calld->send_messages.size()) {
+ return true;
+ }
+ if (pending->batch->send_trailing_metadata &&
+ !retry_state->started_send_trailing_metadata) {
+ return true;
+ }
+ if (pending->batch->recv_initial_metadata &&
+ !retry_state->started_recv_initial_metadata) {
+ return true;
+ }
+ if (pending->batch->recv_message &&
+ retry_state->completed_recv_message_count ==
+ retry_state->started_recv_message_count) {
+ return true;
+ }
+ if (pending->batch->recv_trailing_metadata &&
+ !retry_state->started_recv_trailing_metadata) {
+ return true;
+ }
+ return false;
+}
+
+//
+// retry code
+//
+
+// Commits the call so that no further retry attempts will be performed.
+static void retry_commit(grpc_call_element* elem,
+ subchannel_call_retry_state* retry_state) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (calld->retry_committed) return;
+ calld->retry_committed = true;
if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG, "chand=%p calld=%p: applying service config to call",
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: committing retries", chand, calld);
+ }
+ if (retry_state != nullptr) {
+ free_cached_send_op_data_after_commit(elem, retry_state);
+ }
+}
+
+// Starts a retry after appropriate back-off.
+static void do_retry(grpc_call_element* elem,
+ subchannel_call_retry_state* retry_state,
+ grpc_millis server_pushback_ms) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ GPR_ASSERT(calld->method_params != nullptr);
+ const ClientChannelMethodParams::RetryPolicy* retry_policy =
+ calld->method_params->retry_policy();
+ GPR_ASSERT(retry_policy != nullptr);
+ // Reset subchannel call and connected subchannel.
+ if (calld->subchannel_call != nullptr) {
+ GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call,
+ "client_channel_call_retry");
+ calld->subchannel_call = nullptr;
+ }
+ if (calld->pick.connected_subchannel != nullptr) {
+ calld->pick.connected_subchannel.reset();
+ }
+ // Compute backoff delay.
+ grpc_millis next_attempt_time;
+ if (server_pushback_ms >= 0) {
+ next_attempt_time = grpc_core::ExecCtx::Get()->Now() + server_pushback_ms;
+ calld->last_attempt_got_server_pushback = true;
+ } else {
+ if (calld->num_attempts_completed == 1 ||
+ calld->last_attempt_got_server_pushback) {
+ calld->retry_backoff.Init(
+ grpc_core::BackOff::Options()
+ .set_initial_backoff(retry_policy->initial_backoff)
+ .set_multiplier(retry_policy->backoff_multiplier)
+ .set_jitter(RETRY_BACKOFF_JITTER)
+ .set_max_backoff(retry_policy->max_backoff));
+ calld->last_attempt_got_server_pushback = false;
+ }
+ next_attempt_time = calld->retry_backoff->NextAttemptTime();
+ }
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: retrying failed call in %" PRIuPTR " ms", chand,
+ calld, next_attempt_time - grpc_core::ExecCtx::Get()->Now());
+ }
+ // Schedule retry after computed delay.
+ GRPC_CLOSURE_INIT(&calld->pick_closure, start_pick_locked, elem,
+ grpc_combiner_scheduler(chand->combiner));
+ grpc_timer_init(&calld->retry_timer, next_attempt_time, &calld->pick_closure);
+ // Update bookkeeping.
+ if (retry_state != nullptr) retry_state->retry_dispatched = true;
+}
+
+// Returns true if the call is being retried.
+static bool maybe_retry(grpc_call_element* elem,
+ subchannel_batch_data* batch_data,
+ grpc_status_code status,
+ grpc_mdelem* server_pushback_md) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ // Get retry policy.
+ if (calld->method_params == nullptr) return false;
+ const ClientChannelMethodParams::RetryPolicy* retry_policy =
+ calld->method_params->retry_policy();
+ if (retry_policy == nullptr) return false;
+ // If we've already dispatched a retry from this call, return true.
+ // This catches the case where the batch has multiple callbacks
+ // (i.e., it includes either recv_message or recv_initial_metadata).
+ subchannel_call_retry_state* retry_state = nullptr;
+ if (batch_data != nullptr) {
+ retry_state = static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ batch_data->subchannel_call));
+ if (retry_state->retry_dispatched) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: retry already dispatched", chand,
+ calld);
+ }
+ return true;
+ }
+ }
+ // Check status.
+ if (status == GRPC_STATUS_OK) {
+ grpc_server_retry_throttle_data_record_success(calld->retry_throttle_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: call succeeded", chand, calld);
+ }
+ return false;
+ }
+ // Status is not OK. Check whether the status is retryable.
+ if (!retry_policy->retryable_status_codes.Contains(status)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: status %s not configured as retryable", chand,
+ calld, grpc_status_code_to_string(status));
+ }
+ return false;
+ }
+ // Record the failure and check whether retries are throttled.
+ // Note that it's important for this check to come after the status
+ // code check above, since we should only record failures whose statuses
+ // match the configured retryable status codes, so that we don't count
+ // things like failures due to malformed requests (INVALID_ARGUMENT).
+ // Conversely, it's important for this to come before the remaining
+ // checks, so that we don't fail to record failures due to other factors.
+ if (!grpc_server_retry_throttle_data_record_failure(
+ calld->retry_throttle_data)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: retries throttled", chand, calld);
+ }
+ return false;
+ }
+ // Check whether the call is committed.
+ if (calld->retry_committed) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: retries already committed", chand,
+ calld);
+ }
+ return false;
+ }
+ // Check whether we have retries remaining.
+ ++calld->num_attempts_completed;
+ if (calld->num_attempts_completed >= retry_policy->max_attempts) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: exceeded %d retry attempts", chand,
+ calld, retry_policy->max_attempts);
+ }
+ return false;
+ }
+ // If the call was cancelled from the surface, don't retry.
+ if (calld->cancel_error != GRPC_ERROR_NONE) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: call cancelled from surface, not retrying",
+ chand, calld);
+ }
+ return false;
+ }
+ // Check server push-back.
+ grpc_millis server_pushback_ms = -1;
+ if (server_pushback_md != nullptr) {
+ // If the value is "-1" or any other unparseable string, we do not retry.
+ uint32_t ms;
+ if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(*server_pushback_md), &ms)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: not retrying due to server push-back",
+ chand, calld);
+ }
+ return false;
+ } else {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: server push-back: retry in %u ms", chand,
+ calld, ms);
+ }
+ server_pushback_ms = (grpc_millis)ms;
+ }
+ }
+ do_retry(elem, retry_state, server_pushback_ms);
+ return true;
+}
+
+//
+// subchannel_batch_data
+//
+
+static subchannel_batch_data* batch_data_create(grpc_call_element* elem,
+ int refcount) {
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ calld->subchannel_call));
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(
+ gpr_arena_alloc(calld->arena, sizeof(*batch_data)));
+ batch_data->elem = elem;
+ batch_data->subchannel_call =
+ GRPC_SUBCHANNEL_CALL_REF(calld->subchannel_call, "batch_data_create");
+ batch_data->batch.payload = &retry_state->batch_payload;
+ gpr_ref_init(&batch_data->refs, refcount);
+ GRPC_CLOSURE_INIT(&batch_data->on_complete, on_complete, batch_data,
+ grpc_schedule_on_exec_ctx);
+ batch_data->batch.on_complete = &batch_data->on_complete;
+ GRPC_CALL_STACK_REF(calld->owning_call, "batch_data");
+ return batch_data;
+}
+
+static void batch_data_unref(subchannel_batch_data* batch_data) {
+ if (gpr_unref(&batch_data->refs)) {
+ if (batch_data->send_initial_metadata_storage != nullptr) {
+ grpc_metadata_batch_destroy(&batch_data->send_initial_metadata);
+ }
+ if (batch_data->send_trailing_metadata_storage != nullptr) {
+ grpc_metadata_batch_destroy(&batch_data->send_trailing_metadata);
+ }
+ if (batch_data->batch.recv_initial_metadata) {
+ grpc_metadata_batch_destroy(&batch_data->recv_initial_metadata);
+ }
+ if (batch_data->batch.recv_trailing_metadata) {
+ grpc_metadata_batch_destroy(&batch_data->recv_trailing_metadata);
+ }
+ GRPC_SUBCHANNEL_CALL_UNREF(batch_data->subchannel_call, "batch_data_unref");
+ call_data* calld = static_cast<call_data*>(batch_data->elem->call_data);
+ GRPC_CALL_STACK_UNREF(calld->owning_call, "batch_data");
+ }
+}
+
+//
+// recv_initial_metadata callback handling
+//
+
+// Invokes recv_initial_metadata_ready for a subchannel batch.
+static void invoke_recv_initial_metadata_callback(void* arg,
+ grpc_error* error) {
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
+ channel_data* chand =
+ static_cast<channel_data*>(batch_data->elem->channel_data);
+ call_data* calld = static_cast<call_data*>(batch_data->elem->call_data);
+ // Find pending batch.
+ pending_batch* pending = nullptr;
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ grpc_transport_stream_op_batch* batch = calld->pending_batches[i].batch;
+ if (batch != nullptr && batch->recv_initial_metadata &&
+ batch->payload->recv_initial_metadata.recv_initial_metadata_ready !=
+ nullptr) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: invoking recv_initial_metadata_ready for "
+ "pending batch at index %" PRIuPTR,
+ chand, calld, i);
+ }
+ pending = &calld->pending_batches[i];
+ break;
+ }
+ }
+ GPR_ASSERT(pending != nullptr);
+ // Return metadata.
+ grpc_metadata_batch_move(
+ &batch_data->recv_initial_metadata,
+ pending->batch->payload->recv_initial_metadata.recv_initial_metadata);
+ // Update bookkeeping.
+ // Note: Need to do this before invoking the callback, since invoking
+ // the callback will result in yielding the call combiner.
+ grpc_closure* recv_initial_metadata_ready =
+ pending->batch->payload->recv_initial_metadata
+ .recv_initial_metadata_ready;
+ pending->batch->payload->recv_initial_metadata.recv_initial_metadata_ready =
+ nullptr;
+ maybe_clear_pending_batch(batch_data->elem, pending);
+ batch_data_unref(batch_data);
+ // Invoke callback.
+ GRPC_CLOSURE_RUN(recv_initial_metadata_ready, GRPC_ERROR_REF(error));
+}
+
+// Intercepts recv_initial_metadata_ready callback for retries.
+// Commits the call and returns the initial metadata up the stack.
+static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
+ grpc_call_element* elem = batch_data->elem;
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: got recv_initial_metadata_ready, error=%s",
+ chand, calld, grpc_error_string(error));
+ }
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ batch_data->subchannel_call));
+ // If we got an error or a Trailers-Only response and have not yet gotten
+ // the recv_trailing_metadata on_complete callback, then defer
+ // propagating this callback back to the surface. We can evaluate whether
+ // to retry when recv_trailing_metadata comes back.
+ if ((batch_data->trailing_metadata_available || error != GRPC_ERROR_NONE) &&
+ !retry_state->completed_recv_trailing_metadata) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: deferring recv_initial_metadata_ready "
+ "(Trailers-Only)",
+ chand, calld);
+ }
+ retry_state->recv_initial_metadata_ready_deferred = true;
+ retry_state->recv_initial_metadata_error = GRPC_ERROR_REF(error);
+ if (!retry_state->started_recv_trailing_metadata) {
+ // recv_trailing_metadata not yet started by application; start it
+ // ourselves to get status.
+ start_internal_recv_trailing_metadata(elem);
+ } else {
+ GRPC_CALL_COMBINER_STOP(
+ calld->call_combiner,
+ "recv_initial_metadata_ready trailers-only or error");
+ }
+ return;
+ }
+ // Received valid initial metadata, so commit the call.
+ retry_commit(elem, retry_state);
+ // Manually invoking a callback function; it does not take ownership of error.
+ invoke_recv_initial_metadata_callback(batch_data, error);
+ GRPC_ERROR_UNREF(error);
+}
+
+//
+// recv_message callback handling
+//
+
+// Invokes recv_message_ready for a subchannel batch.
+static void invoke_recv_message_callback(void* arg, grpc_error* error) {
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
+ channel_data* chand =
+ static_cast<channel_data*>(batch_data->elem->channel_data);
+ call_data* calld = static_cast<call_data*>(batch_data->elem->call_data);
+ // Find pending op.
+ pending_batch* pending = nullptr;
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ grpc_transport_stream_op_batch* batch = calld->pending_batches[i].batch;
+ if (batch != nullptr && batch->recv_message &&
+ batch->payload->recv_message.recv_message_ready != nullptr) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: invoking recv_message_ready for "
+ "pending batch at index %" PRIuPTR,
+ chand, calld, i);
+ }
+ pending = &calld->pending_batches[i];
+ break;
+ }
+ }
+ GPR_ASSERT(pending != nullptr);
+ // Return payload.
+ *pending->batch->payload->recv_message.recv_message =
+ batch_data->recv_message;
+ // Update bookkeeping.
+ // Note: Need to do this before invoking the callback, since invoking
+ // the callback will result in yielding the call combiner.
+ grpc_closure* recv_message_ready =
+ pending->batch->payload->recv_message.recv_message_ready;
+ pending->batch->payload->recv_message.recv_message_ready = nullptr;
+ maybe_clear_pending_batch(batch_data->elem, pending);
+ batch_data_unref(batch_data);
+ // Invoke callback.
+ GRPC_CLOSURE_RUN(recv_message_ready, GRPC_ERROR_REF(error));
+}
+
+// Intercepts recv_message_ready callback for retries.
+// Commits the call and returns the message up the stack.
+static void recv_message_ready(void* arg, grpc_error* error) {
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
+ grpc_call_element* elem = batch_data->elem;
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: got recv_message_ready, error=%s",
+ chand, calld, grpc_error_string(error));
+ }
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ batch_data->subchannel_call));
+ // If we got an error or the payload was nullptr and we have not yet gotten
+ // the recv_trailing_metadata on_complete callback, then defer
+ // propagating this callback back to the surface. We can evaluate whether
+ // to retry when recv_trailing_metadata comes back.
+ if ((batch_data->recv_message == nullptr || error != GRPC_ERROR_NONE) &&
+ !retry_state->completed_recv_trailing_metadata) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: deferring recv_message_ready (nullptr "
+ "message and recv_trailing_metadata pending)",
+ chand, calld);
+ }
+ retry_state->recv_message_ready_deferred = true;
+ retry_state->recv_message_error = GRPC_ERROR_REF(error);
+ if (!retry_state->started_recv_trailing_metadata) {
+ // recv_trailing_metadata not yet started by application; start it
+ // ourselves to get status.
+ start_internal_recv_trailing_metadata(elem);
+ } else {
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner, "recv_message_ready null");
+ }
+ return;
+ }
+ // Received a valid message, so commit the call.
+ retry_commit(elem, retry_state);
+ // Manually invoking a callback function; it does not take ownership of error.
+ invoke_recv_message_callback(batch_data, error);
+ GRPC_ERROR_UNREF(error);
+}
+
+//
+// on_complete callback handling
+//
+
+// Updates retry_state to reflect the ops completed in batch_data.
+static void update_retry_state_for_completed_batch(
+ subchannel_batch_data* batch_data,
+ subchannel_call_retry_state* retry_state) {
+ if (batch_data->batch.send_initial_metadata) {
+ retry_state->completed_send_initial_metadata = true;
+ }
+ if (batch_data->batch.send_message) {
+ ++retry_state->completed_send_message_count;
+ }
+ if (batch_data->batch.send_trailing_metadata) {
+ retry_state->completed_send_trailing_metadata = true;
+ }
+ if (batch_data->batch.recv_initial_metadata) {
+ retry_state->completed_recv_initial_metadata = true;
+ }
+ if (batch_data->batch.recv_message) {
+ ++retry_state->completed_recv_message_count;
+ }
+ if (batch_data->batch.recv_trailing_metadata) {
+ retry_state->completed_recv_trailing_metadata = true;
+ }
+}
+
+// Represents a closure that needs to run as a result of a completed batch.
+typedef struct {
+ grpc_closure* closure;
+ grpc_error* error;
+ const char* reason;
+} closure_to_execute;
+
+// Adds any necessary closures for deferred recv_initial_metadata and
+// recv_message callbacks to closures, updating *num_closures as needed.
+static void add_closures_for_deferred_recv_callbacks(
+ subchannel_batch_data* batch_data, subchannel_call_retry_state* retry_state,
+ closure_to_execute* closures, size_t* num_closures) {
+ if (batch_data->batch.recv_trailing_metadata &&
+ retry_state->recv_initial_metadata_ready_deferred) {
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure =
+ GRPC_CLOSURE_INIT(&batch_data->recv_initial_metadata_ready,
+ invoke_recv_initial_metadata_callback, batch_data,
+ grpc_schedule_on_exec_ctx);
+ closure->error = retry_state->recv_initial_metadata_error;
+ closure->reason = "resuming recv_initial_metadata_ready";
+ }
+ if (batch_data->batch.recv_trailing_metadata &&
+ retry_state->recv_message_ready_deferred) {
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = GRPC_CLOSURE_INIT(&batch_data->recv_message_ready,
+ invoke_recv_message_callback,
+ batch_data, grpc_schedule_on_exec_ctx);
+ closure->error = retry_state->recv_message_error;
+ closure->reason = "resuming recv_message_ready";
+ }
+}
+
+// If there are any cached ops to replay or pending ops to start on the
+// subchannel call, adds a closure to closures to invoke
+// start_retriable_subchannel_batches(), updating *num_closures as needed.
+static void add_closures_for_replay_or_pending_send_ops(
+ grpc_call_element* elem, subchannel_batch_data* batch_data,
+ subchannel_call_retry_state* retry_state, closure_to_execute* closures,
+ size_t* num_closures) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ bool have_pending_send_message_ops =
+ retry_state->started_send_message_count < calld->send_messages.size();
+ bool have_pending_send_trailing_metadata_op =
+ calld->seen_send_trailing_metadata &&
+ !retry_state->started_send_trailing_metadata;
+ if (!have_pending_send_message_ops &&
+ !have_pending_send_trailing_metadata_op) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ pending_batch* pending = &calld->pending_batches[i];
+ grpc_transport_stream_op_batch* batch = pending->batch;
+ if (batch == nullptr || pending->send_ops_cached) continue;
+ if (batch->send_message) have_pending_send_message_ops = true;
+ if (batch->send_trailing_metadata) {
+ have_pending_send_trailing_metadata_op = true;
+ }
+ }
+ }
+ if (have_pending_send_message_ops || have_pending_send_trailing_metadata_op) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: starting next batch for pending send op(s)",
+ chand, calld);
+ }
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = GRPC_CLOSURE_INIT(
+ &batch_data->batch.handler_private.closure,
+ start_retriable_subchannel_batches, elem, grpc_schedule_on_exec_ctx);
+ closure->error = GRPC_ERROR_NONE;
+ closure->reason = "starting next batch for send_* op(s)";
+ }
+}
+
+// For any pending batch completed in batch_data, adds the necessary
+// completion closures to closures, updating *num_closures as needed.
+static void add_closures_for_completed_pending_batches(
+ grpc_call_element* elem, subchannel_batch_data* batch_data,
+ subchannel_call_retry_state* retry_state, grpc_error* error,
+ closure_to_execute* closures, size_t* num_closures) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ pending_batch* pending = &calld->pending_batches[i];
+ if (pending_batch_is_completed(pending, calld, retry_state)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: pending batch completed at index %" PRIuPTR,
+ chand, calld, i);
+ }
+ // Copy the trailing metadata to return it to the surface.
+ if (batch_data->batch.recv_trailing_metadata) {
+ grpc_metadata_batch_move(&batch_data->recv_trailing_metadata,
+ pending->batch->payload->recv_trailing_metadata
+ .recv_trailing_metadata);
+ }
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = pending->batch->on_complete;
+ closure->error = GRPC_ERROR_REF(error);
+ closure->reason = "on_complete for pending batch";
+ pending->batch->on_complete = nullptr;
+ maybe_clear_pending_batch(elem, pending);
+ }
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+// For any pending batch containing an op that has not yet been started,
+// adds the pending batch's completion closures to closures, updating
+// *num_closures as needed.
+static void add_closures_to_fail_unstarted_pending_batches(
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state,
+ grpc_error* error, closure_to_execute* closures, size_t* num_closures) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ pending_batch* pending = &calld->pending_batches[i];
+ if (pending_batch_is_unstarted(pending, calld, retry_state)) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: failing unstarted pending batch at index "
+ "%" PRIuPTR,
+ chand, calld, i);
+ }
+ if (pending->batch->recv_initial_metadata) {
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = pending->batch->payload->recv_initial_metadata
+ .recv_initial_metadata_ready;
+ closure->error = GRPC_ERROR_REF(error);
+ closure->reason =
+ "failing recv_initial_metadata_ready for pending batch";
+ pending->batch->payload->recv_initial_metadata
+ .recv_initial_metadata_ready = nullptr;
+ }
+ if (pending->batch->recv_message) {
+ *pending->batch->payload->recv_message.recv_message = nullptr;
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure =
+ pending->batch->payload->recv_message.recv_message_ready;
+ closure->error = GRPC_ERROR_REF(error);
+ closure->reason = "failing recv_message_ready for pending batch";
+ pending->batch->payload->recv_message.recv_message_ready = nullptr;
+ }
+ closure_to_execute* closure = &closures[(*num_closures)++];
+ closure->closure = pending->batch->on_complete;
+ closure->error = GRPC_ERROR_REF(error);
+ closure->reason = "failing on_complete for pending batch";
+ pending->batch->on_complete = nullptr;
+ maybe_clear_pending_batch(elem, pending);
+ }
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+// Callback used to intercept on_complete from subchannel calls.
+// Called only when retries are enabled.
+static void on_complete(void* arg, grpc_error* error) {
+ subchannel_batch_data* batch_data = static_cast<subchannel_batch_data*>(arg);
+ grpc_call_element* elem = batch_data->elem;
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ char* batch_str = grpc_transport_stream_op_batch_string(&batch_data->batch);
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: got on_complete, error=%s, batch=%s",
+ chand, calld, grpc_error_string(error), batch_str);
+ gpr_free(batch_str);
+ }
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ batch_data->subchannel_call));
+ // If we have previously completed recv_trailing_metadata, then the
+ // call is finished.
+ bool call_finished = retry_state->completed_recv_trailing_metadata;
+ // Update bookkeeping in retry_state.
+ update_retry_state_for_completed_batch(batch_data, retry_state);
+ if (call_finished) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: call already finished", chand,
+ calld);
+ }
+ } else {
+ // Check if this batch finished the call, and if so, get its status.
+ // The call is finished if either (a) this callback was invoked with
+ // an error or (b) we receive status.
+ grpc_status_code status = GRPC_STATUS_OK;
+ grpc_mdelem* server_pushback_md = nullptr;
+ if (error != GRPC_ERROR_NONE) { // Case (a).
+ call_finished = true;
+ grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr,
+ nullptr);
+ } else if (batch_data->batch.recv_trailing_metadata) { // Case (b).
+ call_finished = true;
+ grpc_metadata_batch* md_batch =
+ batch_data->batch.payload->recv_trailing_metadata
+ .recv_trailing_metadata;
+ GPR_ASSERT(md_batch->idx.named.grpc_status != nullptr);
+ status = grpc_get_status_code_from_metadata(
+ md_batch->idx.named.grpc_status->md);
+ if (md_batch->idx.named.grpc_retry_pushback_ms != nullptr) {
+ server_pushback_md = &md_batch->idx.named.grpc_retry_pushback_ms->md;
+ }
+ } else if (retry_state->completed_recv_trailing_metadata) {
+ call_finished = true;
+ }
+ if (call_finished && grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: call finished, status=%s", chand,
+ calld, grpc_status_code_to_string(status));
+ }
+ // If the call is finished, check if we should retry.
+ if (call_finished &&
+ maybe_retry(elem, batch_data, status, server_pushback_md)) {
+ // Unref batch_data for deferred recv_initial_metadata_ready or
+ // recv_message_ready callbacks, if any.
+ if (batch_data->batch.recv_trailing_metadata &&
+ retry_state->recv_initial_metadata_ready_deferred) {
+ batch_data_unref(batch_data);
+ GRPC_ERROR_UNREF(retry_state->recv_initial_metadata_error);
+ }
+ if (batch_data->batch.recv_trailing_metadata &&
+ retry_state->recv_message_ready_deferred) {
+ batch_data_unref(batch_data);
+ GRPC_ERROR_UNREF(retry_state->recv_message_error);
+ }
+ batch_data_unref(batch_data);
+ return;
+ }
+ }
+ // If the call is finished or retries are committed, free cached data for
+ // send ops that we've just completed.
+ if (call_finished || calld->retry_committed) {
+ free_cached_send_op_data_for_completed_batch(elem, batch_data, retry_state);
+ }
+ // Call not being retried.
+ // Construct list of closures to execute.
+ // Max number of closures is number of pending batches plus one for
+ // each of:
+ // - recv_initial_metadata_ready (either deferred or unstarted)
+ // - recv_message_ready (either deferred or unstarted)
+ // - starting a new batch for pending send ops
+ closure_to_execute closures[GPR_ARRAY_SIZE(calld->pending_batches) + 3];
+ size_t num_closures = 0;
+ // If there are deferred recv_initial_metadata_ready or recv_message_ready
+ // callbacks, add them to closures.
+ add_closures_for_deferred_recv_callbacks(batch_data, retry_state, closures,
+ &num_closures);
+ // Find pending batches whose ops are now complete and add their
+ // on_complete callbacks to closures.
+ add_closures_for_completed_pending_batches(elem, batch_data, retry_state,
+ GRPC_ERROR_REF(error), closures,
+ &num_closures);
+ // Add closures to handle any pending batches that have not yet been started.
+ // If the call is finished, we fail these batches; otherwise, we add a
+ // callback to start_retriable_subchannel_batches() to start them on
+ // the subchannel call.
+ if (call_finished) {
+ add_closures_to_fail_unstarted_pending_batches(
+ elem, retry_state, GRPC_ERROR_REF(error), closures, &num_closures);
+ } else {
+ add_closures_for_replay_or_pending_send_ops(elem, batch_data, retry_state,
+ closures, &num_closures);
+ }
+ // Don't need batch_data anymore.
+ batch_data_unref(batch_data);
+ // Schedule all of the closures identified above.
+ // Note that the call combiner will be yielded for each closure that
+ // we schedule. We're already running in the call combiner, so one of
+ // the closures can be scheduled directly, but the others will
+ // have to re-enter the call combiner.
+ if (num_closures > 0) {
+ GRPC_CLOSURE_SCHED(closures[0].closure, closures[0].error);
+ for (size_t i = 1; i < num_closures; ++i) {
+ GRPC_CALL_COMBINER_START(calld->call_combiner, closures[i].closure,
+ closures[i].error, closures[i].reason);
+ }
+ } else {
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
+ "no closures to run for on_complete");
+ }
+}
+
+//
+// subchannel batch construction
+//
+
+// Helper function used to start a subchannel batch in the call combiner.
+static void start_batch_in_call_combiner(void* arg, grpc_error* ignored) {
+ grpc_transport_stream_op_batch* batch =
+ static_cast<grpc_transport_stream_op_batch*>(arg);
+ grpc_subchannel_call* subchannel_call =
+ static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg);
+ // Note: This will release the call combiner.
+ grpc_subchannel_call_process_op(subchannel_call, batch);
+}
+
+// Adds retriable send_initial_metadata op to batch_data.
+static void add_retriable_send_initial_metadata_op(
+ call_data* calld, subchannel_call_retry_state* retry_state,
+ subchannel_batch_data* batch_data) {
+ // Maps the number of retries to the corresponding metadata value slice.
+ static const grpc_slice* retry_count_strings[] = {
+ &GRPC_MDSTR_1, &GRPC_MDSTR_2, &GRPC_MDSTR_3, &GRPC_MDSTR_4};
+ // We need to make a copy of the metadata batch for each attempt, since
+ // the filters in the subchannel stack may modify this batch, and we don't
+ // want those modifications to be passed forward to subsequent attempts.
+ //
+ // If we've already completed one or more attempts, add the
+ // grpc-retry-attempts header.
+ batch_data->send_initial_metadata_storage =
+ static_cast<grpc_linked_mdelem*>(gpr_arena_alloc(
+ calld->arena, sizeof(grpc_linked_mdelem) *
+ (calld->send_initial_metadata.list.count +
+ (calld->num_attempts_completed > 0))));
+ grpc_metadata_batch_copy(&calld->send_initial_metadata,
+ &batch_data->send_initial_metadata,
+ batch_data->send_initial_metadata_storage);
+ if (batch_data->send_initial_metadata.idx.named.grpc_previous_rpc_attempts !=
+ nullptr) {
+ grpc_metadata_batch_remove(
+ &batch_data->send_initial_metadata,
+ batch_data->send_initial_metadata.idx.named.grpc_previous_rpc_attempts);
+ }
+ if (calld->num_attempts_completed > 0) {
+ grpc_mdelem retry_md = grpc_mdelem_from_slices(
+ GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS,
+ *retry_count_strings[calld->num_attempts_completed - 1]);
+ grpc_error* error = grpc_metadata_batch_add_tail(
+ &batch_data->send_initial_metadata,
+ &batch_data->send_initial_metadata_storage[calld->send_initial_metadata
+ .list.count],
+ retry_md);
+ if (error != GRPC_ERROR_NONE) {
+ gpr_log(GPR_ERROR, "error adding retry metadata: %s",
+ grpc_error_string(error));
+ GPR_ASSERT(false);
+ }
+ }
+ retry_state->started_send_initial_metadata = true;
+ batch_data->batch.send_initial_metadata = true;
+ batch_data->batch.payload->send_initial_metadata.send_initial_metadata =
+ &batch_data->send_initial_metadata;
+ batch_data->batch.payload->send_initial_metadata.send_initial_metadata_flags =
+ calld->send_initial_metadata_flags;
+ batch_data->batch.payload->send_initial_metadata.peer_string =
+ calld->peer_string;
+}
+
+// Adds retriable send_message op to batch_data.
+static void add_retriable_send_message_op(
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state,
+ subchannel_batch_data* batch_data) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: starting calld->send_messages[%" PRIuPTR "]",
+ chand, calld, retry_state->started_send_message_count);
+ }
+ grpc_byte_stream_cache* cache =
+ calld->send_messages[retry_state->started_send_message_count];
+ ++retry_state->started_send_message_count;
+ grpc_caching_byte_stream_init(&batch_data->send_message, cache);
+ batch_data->batch.send_message = true;
+ batch_data->batch.payload->send_message.send_message =
+ &batch_data->send_message.base;
+}
+
+// Adds retriable send_trailing_metadata op to batch_data.
+static void add_retriable_send_trailing_metadata_op(
+ call_data* calld, subchannel_call_retry_state* retry_state,
+ subchannel_batch_data* batch_data) {
+ // We need to make a copy of the metadata batch for each attempt, since
+ // the filters in the subchannel stack may modify this batch, and we don't
+ // want those modifications to be passed forward to subsequent attempts.
+ batch_data->send_trailing_metadata_storage =
+ static_cast<grpc_linked_mdelem*>(gpr_arena_alloc(
+ calld->arena, sizeof(grpc_linked_mdelem) *
+ calld->send_trailing_metadata.list.count));
+ grpc_metadata_batch_copy(&calld->send_trailing_metadata,
+ &batch_data->send_trailing_metadata,
+ batch_data->send_trailing_metadata_storage);
+ retry_state->started_send_trailing_metadata = true;
+ batch_data->batch.send_trailing_metadata = true;
+ batch_data->batch.payload->send_trailing_metadata.send_trailing_metadata =
+ &batch_data->send_trailing_metadata;
+}
+
+// Adds retriable recv_initial_metadata op to batch_data.
+static void add_retriable_recv_initial_metadata_op(
+ call_data* calld, subchannel_call_retry_state* retry_state,
+ subchannel_batch_data* batch_data) {
+ retry_state->started_recv_initial_metadata = true;
+ batch_data->batch.recv_initial_metadata = true;
+ grpc_metadata_batch_init(&batch_data->recv_initial_metadata);
+ batch_data->batch.payload->recv_initial_metadata.recv_initial_metadata =
+ &batch_data->recv_initial_metadata;
+ batch_data->batch.payload->recv_initial_metadata.trailing_metadata_available =
+ &batch_data->trailing_metadata_available;
+ GRPC_CLOSURE_INIT(&batch_data->recv_initial_metadata_ready,
+ recv_initial_metadata_ready, batch_data,
+ grpc_schedule_on_exec_ctx);
+ batch_data->batch.payload->recv_initial_metadata.recv_initial_metadata_ready =
+ &batch_data->recv_initial_metadata_ready;
+}
+
+// Adds retriable recv_message op to batch_data.
+static void add_retriable_recv_message_op(
+ call_data* calld, subchannel_call_retry_state* retry_state,
+ subchannel_batch_data* batch_data) {
+ ++retry_state->started_recv_message_count;
+ batch_data->batch.recv_message = true;
+ batch_data->batch.payload->recv_message.recv_message =
+ &batch_data->recv_message;
+ GRPC_CLOSURE_INIT(&batch_data->recv_message_ready, recv_message_ready,
+ batch_data, grpc_schedule_on_exec_ctx);
+ batch_data->batch.payload->recv_message.recv_message_ready =
+ &batch_data->recv_message_ready;
+}
+
+// Adds retriable recv_trailing_metadata op to batch_data.
+static void add_retriable_recv_trailing_metadata_op(
+ call_data* calld, subchannel_call_retry_state* retry_state,
+ subchannel_batch_data* batch_data) {
+ retry_state->started_recv_trailing_metadata = true;
+ batch_data->batch.recv_trailing_metadata = true;
+ grpc_metadata_batch_init(&batch_data->recv_trailing_metadata);
+ batch_data->batch.payload->recv_trailing_metadata.recv_trailing_metadata =
+ &batch_data->recv_trailing_metadata;
+ batch_data->batch.collect_stats = true;
+ batch_data->batch.payload->collect_stats.collect_stats =
+ &batch_data->collect_stats;
+}
+
+// Helper function used to start a recv_trailing_metadata batch. This
+// is used in the case where a recv_initial_metadata or recv_message
+// op fails in a way that we know the call is over but when the application
+// has not yet started its own recv_trailing_metadata op.
+static void start_internal_recv_trailing_metadata(grpc_call_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: call failed but recv_trailing_metadata not "
+ "started; starting it internally",
chand, calld);
}
- if (chand->retry_throttle_data != nullptr) {
- calld->retry_throttle_data =
- grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ calld->subchannel_call));
+ subchannel_batch_data* batch_data = batch_data_create(elem, 1);
+ add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data);
+ // Note: This will release the call combiner.
+ grpc_subchannel_call_process_op(calld->subchannel_call, &batch_data->batch);
+}
+
+// If there are any cached send ops that need to be replayed on the
+// current subchannel call, creates and returns a new subchannel batch
+// to replay those ops. Otherwise, returns nullptr.
+static subchannel_batch_data* maybe_create_subchannel_batch_for_replay(
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ subchannel_batch_data* replay_batch_data = nullptr;
+ // send_initial_metadata.
+ if (calld->seen_send_initial_metadata &&
+ !retry_state->started_send_initial_metadata &&
+ !calld->pending_send_initial_metadata) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: replaying previously completed "
+ "send_initial_metadata op",
+ chand, calld);
+ }
+ replay_batch_data = batch_data_create(elem, 1);
+ add_retriable_send_initial_metadata_op(calld, retry_state,
+ replay_batch_data);
+ }
+ // send_message.
+ // Note that we can only have one send_message op in flight at a time.
+ if (retry_state->started_send_message_count < calld->send_messages.size() &&
+ retry_state->started_send_message_count ==
+ retry_state->completed_send_message_count &&
+ !calld->pending_send_message) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: replaying previously completed "
+ "send_message op",
+ chand, calld);
+ }
+ if (replay_batch_data == nullptr) {
+ replay_batch_data = batch_data_create(elem, 1);
+ }
+ add_retriable_send_message_op(elem, retry_state, replay_batch_data);
+ }
+ // send_trailing_metadata.
+ // Note that we only add this op if we have no more send_message ops
+ // to start, since we can't send down any more send_message ops after
+ // send_trailing_metadata.
+ if (calld->seen_send_trailing_metadata &&
+ retry_state->started_send_message_count == calld->send_messages.size() &&
+ !retry_state->started_send_trailing_metadata &&
+ !calld->pending_send_trailing_metadata) {
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: replaying previously completed "
+ "send_trailing_metadata op",
+ chand, calld);
+ }
+ if (replay_batch_data == nullptr) {
+ replay_batch_data = batch_data_create(elem, 1);
+ }
+ add_retriable_send_trailing_metadata_op(calld, retry_state,
+ replay_batch_data);
}
- if (chand->method_params_table != nullptr) {
- calld->method_params = static_cast<method_parameters*>(
- grpc_method_config_table_get(chand->method_params_table, calld->path));
- if (calld->method_params != nullptr) {
- method_parameters_ref(calld->method_params);
- // If the deadline from the service config is shorter than the one
- // from the client API, reset the deadline timer.
- if (chand->deadline_checking_enabled &&
- calld->method_params->timeout != 0) {
- const grpc_millis per_method_deadline =
- grpc_timespec_to_millis_round_up(calld->call_start_time) +
- calld->method_params->timeout;
- if (per_method_deadline < calld->deadline) {
- calld->deadline = per_method_deadline;
- grpc_deadline_state_reset(elem, calld->deadline);
- }
+ return replay_batch_data;
+}
+
+// Adds subchannel batches for pending batches to batches, updating
+// *num_batches as needed.
+static void add_subchannel_batches_for_pending_batches(
+ grpc_call_element* elem, subchannel_call_retry_state* retry_state,
+ grpc_transport_stream_op_batch** batches, size_t* num_batches) {
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ pending_batch* pending = &calld->pending_batches[i];
+ grpc_transport_stream_op_batch* batch = pending->batch;
+ if (batch == nullptr) continue;
+ // Skip any batch that either (a) has already been started on this
+ // subchannel call or (b) we can't start yet because we're still
+ // replaying send ops that need to be completed first.
+ // TODO(roth): Note that if any one op in the batch can't be sent
+ // yet due to ops that we're replaying, we don't start any of the ops
+ // in the batch. This is probably okay, but it could conceivably
+ // lead to increased latency in some cases -- e.g., we could delay
+ // starting a recv op due to it being in the same batch with a send
+ // op. If/when we revamp the callback protocol in
+ // transport_stream_op_batch, we may be able to fix this.
+ if (batch->send_initial_metadata &&
+ retry_state->started_send_initial_metadata) {
+ continue;
+ }
+ if (batch->send_message && retry_state->completed_send_message_count <
+ retry_state->started_send_message_count) {
+ continue;
+ }
+ // Note that we only start send_trailing_metadata if we have no more
+ // send_message ops to start, since we can't send down any more
+ // send_message ops after send_trailing_metadata.
+ if (batch->send_trailing_metadata &&
+ (retry_state->started_send_message_count + batch->send_message <
+ calld->send_messages.size() ||
+ retry_state->started_send_trailing_metadata)) {
+ continue;
+ }
+ if (batch->recv_initial_metadata &&
+ retry_state->started_recv_initial_metadata) {
+ continue;
+ }
+ if (batch->recv_message && retry_state->completed_recv_message_count <
+ retry_state->started_recv_message_count) {
+ continue;
+ }
+ if (batch->recv_trailing_metadata &&
+ retry_state->started_recv_trailing_metadata) {
+ continue;
+ }
+ // If we're not retrying, just send the batch as-is.
+ if (calld->method_params == nullptr ||
+ calld->method_params->retry_policy() == nullptr ||
+ calld->retry_committed) {
+ batches[(*num_batches)++] = batch;
+ pending_batch_clear(calld, pending);
+ continue;
+ }
+ // Create batch with the right number of callbacks.
+ const int num_callbacks =
+ 1 + batch->recv_initial_metadata + batch->recv_message;
+ subchannel_batch_data* batch_data = batch_data_create(elem, num_callbacks);
+ // Cache send ops if needed.
+ maybe_cache_send_ops_for_batch(calld, pending);
+ // send_initial_metadata.
+ if (batch->send_initial_metadata) {
+ add_retriable_send_initial_metadata_op(calld, retry_state, batch_data);
+ }
+ // send_message.
+ if (batch->send_message) {
+ add_retriable_send_message_op(elem, retry_state, batch_data);
+ }
+ // send_trailing_metadata.
+ if (batch->send_trailing_metadata) {
+ add_retriable_send_trailing_metadata_op(calld, retry_state, batch_data);
+ }
+ // recv_initial_metadata.
+ if (batch->recv_initial_metadata) {
+ // recv_flags is only used on the server side.
+ GPR_ASSERT(batch->payload->recv_initial_metadata.recv_flags == nullptr);
+ add_retriable_recv_initial_metadata_op(calld, retry_state, batch_data);
+ }
+ // recv_message.
+ if (batch->recv_message) {
+ add_retriable_recv_message_op(calld, retry_state, batch_data);
+ }
+ // recv_trailing_metadata.
+ if (batch->recv_trailing_metadata) {
+ GPR_ASSERT(batch->collect_stats);
+ add_retriable_recv_trailing_metadata_op(calld, retry_state, batch_data);
+ }
+ batches[(*num_batches)++] = &batch_data->batch;
+ }
+}
+
+// Constructs and starts whatever subchannel batches are needed on the
+// subchannel call.
+static void start_retriable_subchannel_batches(void* arg, grpc_error* ignored) {
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: constructing retriable batches",
+ chand, calld);
+ }
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ calld->subchannel_call));
+ // We can start up to 6 batches.
+ grpc_transport_stream_op_batch*
+ batches[GPR_ARRAY_SIZE(calld->pending_batches)];
+ size_t num_batches = 0;
+ // Replay previously-returned send_* ops if needed.
+ subchannel_batch_data* replay_batch_data =
+ maybe_create_subchannel_batch_for_replay(elem, retry_state);
+ if (replay_batch_data != nullptr) {
+ batches[num_batches++] = &replay_batch_data->batch;
+ }
+ // Now add pending batches.
+ add_subchannel_batches_for_pending_batches(elem, retry_state, batches,
+ &num_batches);
+ // Start batches on subchannel call.
+ // Note that the call combiner will be yielded for each batch that we
+ // send down. We're already running in the call combiner, so one of
+ // the batches can be started directly, but the others will have to
+ // re-enter the call combiner.
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: starting %" PRIuPTR
+ " retriable batches on subchannel_call=%p",
+ chand, calld, num_batches, calld->subchannel_call);
+ }
+ if (num_batches == 0) {
+ // This should be fairly rare, but it can happen when (e.g.) an
+ // attempt completes before it has finished replaying all
+ // previously sent messages.
+ GRPC_CALL_COMBINER_STOP(calld->call_combiner,
+ "no retriable subchannel batches to start");
+ } else {
+ for (size_t i = 1; i < num_batches; ++i) {
+ if (grpc_client_channel_trace.enabled()) {
+ char* batch_str = grpc_transport_stream_op_batch_string(batches[i]);
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: starting batch in call combiner: %s", chand,
+ calld, batch_str);
+ gpr_free(batch_str);
}
+ batches[i]->handler_private.extra_arg = calld->subchannel_call;
+ GRPC_CLOSURE_INIT(&batches[i]->handler_private.closure,
+ start_batch_in_call_combiner, batches[i],
+ grpc_schedule_on_exec_ctx);
+ GRPC_CALL_COMBINER_START(calld->call_combiner,
+ &batches[i]->handler_private.closure,
+ GRPC_ERROR_NONE, "start_subchannel_batch");
}
+ if (grpc_client_channel_trace.enabled()) {
+ char* batch_str = grpc_transport_stream_op_batch_string(batches[0]);
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting batch: %s", chand, calld,
+ batch_str);
+ gpr_free(batch_str);
+ }
+ // Note: This will release the call combiner.
+ grpc_subchannel_call_process_op(calld->subchannel_call, batches[0]);
}
}
-static void create_subchannel_call_locked(grpc_call_element* elem,
- grpc_error* error) {
+//
+// LB pick
+//
+
+static void create_subchannel_call(grpc_call_element* elem, grpc_error* error) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
+ const size_t parent_data_size =
+ calld->enable_retries ? sizeof(subchannel_call_retry_state) : 0;
const grpc_core::ConnectedSubchannel::CallArgs call_args = {
calld->pollent, // pollent
calld->path, // path
@@ -1008,7 +2466,8 @@ static void create_subchannel_call_locked(grpc_call_element* elem,
calld->deadline, // deadline
calld->arena, // arena
calld->pick.subchannel_call_context, // context
- calld->call_combiner // call_combiner
+ calld->call_combiner, // call_combiner
+ parent_data_size // parent_data_size
};
grpc_error* new_error = calld->pick.connected_subchannel->CreateCall(
call_args, &calld->subchannel_call);
@@ -1018,36 +2477,61 @@ static void create_subchannel_call_locked(grpc_call_element* elem,
}
if (new_error != GRPC_ERROR_NONE) {
new_error = grpc_error_add_child(new_error, error);
- waiting_for_pick_batches_fail(elem, new_error);
+ pending_batches_fail(elem, new_error, true /* yield_call_combiner */);
} else {
- waiting_for_pick_batches_resume(elem);
+ if (parent_data_size > 0) {
+ subchannel_call_retry_state* retry_state =
+ static_cast<subchannel_call_retry_state*>(
+ grpc_connected_subchannel_call_get_parent_data(
+ calld->subchannel_call));
+ retry_state->batch_payload.context = calld->pick.subchannel_call_context;
+ }
+ pending_batches_resume(elem);
}
GRPC_ERROR_UNREF(error);
}
// Invoked when a pick is completed, on both success or failure.
-static void pick_done_locked(grpc_call_element* elem, grpc_error* error) {
- call_data* calld = static_cast<call_data*>(elem->call_data);
+static void pick_done(void* arg, grpc_error* error) {
+ grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
if (calld->pick.connected_subchannel == nullptr) {
// Failed to create subchannel.
- GRPC_ERROR_UNREF(calld->error);
- calld->error = error == GRPC_ERROR_NONE
- ? GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Call dropped by load balancing policy")
- : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Failed to create subchannel", &error, 1);
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: failed to create subchannel: error=%s", chand,
- calld, grpc_error_string(calld->error));
+ // If there was no error, this is an LB policy drop, in which case
+ // we return an error; otherwise, we may retry.
+ grpc_status_code status = GRPC_STATUS_OK;
+ grpc_error_get_status(error, calld->deadline, &status, nullptr, nullptr,
+ nullptr);
+ if (error == GRPC_ERROR_NONE || !calld->enable_retries ||
+ !maybe_retry(elem, nullptr /* batch_data */, status,
+ nullptr /* server_pushback_md */)) {
+ grpc_error* new_error =
+ error == GRPC_ERROR_NONE
+ ? GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Call dropped by load balancing policy")
+ : GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+ "Failed to create subchannel", &error, 1);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "chand=%p calld=%p: failed to create subchannel: error=%s",
+ chand, calld, grpc_error_string(new_error));
+ }
+ pending_batches_fail(elem, new_error, true /* yield_call_combiner */);
}
- waiting_for_pick_batches_fail(elem, GRPC_ERROR_REF(calld->error));
} else {
/* Create call on subchannel. */
- create_subchannel_call_locked(elem, GRPC_ERROR_REF(error));
+ create_subchannel_call(elem, GRPC_ERROR_REF(error));
}
- GRPC_ERROR_UNREF(error);
+}
+
+// Invoked when a pick is completed to leave the client_channel combiner
+// and continue processing in the call combiner.
+static void pick_done_locked(grpc_call_element* elem, grpc_error* error) {
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ GRPC_CLOSURE_INIT(&calld->pick_closure, pick_done, elem,
+ grpc_schedule_on_exec_ctx);
+ GRPC_CLOSURE_SCHED(&calld->pick_closure, error);
}
// A wrapper around pick_done_locked() that is used in cases where
@@ -1074,15 +2558,14 @@ static void pick_callback_cancel_locked(void* arg, grpc_error* error) {
if (error != GRPC_ERROR_NONE && chand->lb_policy != nullptr) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: cancelling pick from LB policy %p",
- chand, calld, chand->lb_policy);
+ chand, calld, chand->lb_policy.get());
}
- grpc_lb_policy_cancel_pick_locked(chand->lb_policy, &calld->pick,
- GRPC_ERROR_REF(error));
+ chand->lb_policy->CancelPickLocked(&calld->pick, GRPC_ERROR_REF(error));
}
GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback_cancel");
}
-// Callback invoked by grpc_lb_policy_pick_locked() for async picks.
+// Callback invoked by LoadBalancingPolicy::PickLocked() for async picks.
// Unrefs the LB policy and invokes async_pick_done_locked().
static void pick_callback_done_locked(void* arg, grpc_error* error) {
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
@@ -1096,48 +2579,98 @@ static void pick_callback_done_locked(void* arg, grpc_error* error) {
GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
}
-// Takes a ref to chand->lb_policy and calls grpc_lb_policy_pick_locked().
-// If the pick was completed synchronously, unrefs the LB policy and
-// returns true.
+// Applies service config to the call. Must be invoked once we know
+// that the resolver has returned results to the channel.
+static void apply_service_config_to_call_locked(grpc_call_element* elem) {
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ if (grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "chand=%p calld=%p: applying service config to call",
+ chand, calld);
+ }
+ if (chand->retry_throttle_data != nullptr) {
+ calld->retry_throttle_data =
+ grpc_server_retry_throttle_data_ref(chand->retry_throttle_data);
+ }
+ if (chand->method_params_table != nullptr) {
+ calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup(
+ *chand->method_params_table, calld->path);
+ if (calld->method_params != nullptr) {
+ // If the deadline from the service config is shorter than the one
+ // from the client API, reset the deadline timer.
+ if (chand->deadline_checking_enabled &&
+ calld->method_params->timeout() != 0) {
+ const grpc_millis per_method_deadline =
+ grpc_timespec_to_millis_round_up(calld->call_start_time) +
+ calld->method_params->timeout();
+ if (per_method_deadline < calld->deadline) {
+ calld->deadline = per_method_deadline;
+ grpc_deadline_state_reset(elem, calld->deadline);
+ }
+ }
+ }
+ }
+ // If no retry policy, disable retries.
+ // TODO(roth): Remove this when adding support for transparent retries.
+ if (calld->method_params == nullptr ||
+ calld->method_params->retry_policy() == nullptr) {
+ calld->enable_retries = false;
+ }
+}
+
+// Starts a pick on chand->lb_policy.
+// Returns true if pick is completed synchronously.
static bool pick_callback_start_locked(grpc_call_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: starting pick on lb_policy=%p",
- chand, calld, chand->lb_policy);
+ chand, calld, chand->lb_policy.get());
+ }
+ // Only get service config data on the first attempt.
+ if (calld->num_attempts_completed == 0) {
+ apply_service_config_to_call_locked(elem);
}
- apply_service_config_to_call_locked(elem);
// If the application explicitly set wait_for_ready, use that.
// Otherwise, if the service config specified a value for this
// method, use that.
- uint32_t initial_metadata_flags =
- calld->initial_metadata_batch->payload->send_initial_metadata
- .send_initial_metadata_flags;
+ //
+ // The send_initial_metadata batch will be the first one in the list,
+ // as set by get_batch_index() above.
+ calld->pick.initial_metadata =
+ calld->seen_send_initial_metadata
+ ? &calld->send_initial_metadata
+ : calld->pending_batches[0]
+ .batch->payload->send_initial_metadata.send_initial_metadata;
+ uint32_t send_initial_metadata_flags =
+ calld->seen_send_initial_metadata
+ ? calld->send_initial_metadata_flags
+ : calld->pending_batches[0]
+ .batch->payload->send_initial_metadata
+ .send_initial_metadata_flags;
const bool wait_for_ready_set_from_api =
- initial_metadata_flags &
+ send_initial_metadata_flags &
GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
const bool wait_for_ready_set_from_service_config =
calld->method_params != nullptr &&
- calld->method_params->wait_for_ready != WAIT_FOR_READY_UNSET;
+ calld->method_params->wait_for_ready() !=
+ ClientChannelMethodParams::WAIT_FOR_READY_UNSET;
if (!wait_for_ready_set_from_api && wait_for_ready_set_from_service_config) {
- if (calld->method_params->wait_for_ready == WAIT_FOR_READY_TRUE) {
- initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
+ if (calld->method_params->wait_for_ready() ==
+ ClientChannelMethodParams::WAIT_FOR_READY_TRUE) {
+ send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY;
} else {
- initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
+ send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY;
}
}
- calld->pick.initial_metadata =
- calld->initial_metadata_batch->payload->send_initial_metadata
- .send_initial_metadata;
- calld->pick.initial_metadata_flags = initial_metadata_flags;
- GRPC_CLOSURE_INIT(&calld->lb_pick_closure, pick_callback_done_locked, elem,
+ calld->pick.initial_metadata_flags = send_initial_metadata_flags;
+ GRPC_CLOSURE_INIT(&calld->pick_closure, pick_callback_done_locked, elem,
grpc_combiner_scheduler(chand->combiner));
- calld->pick.on_complete = &calld->lb_pick_closure;
+ calld->pick.on_complete = &calld->pick_closure;
GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback");
- const bool pick_done =
- grpc_lb_policy_pick_locked(chand->lb_policy, &calld->pick);
+ const bool pick_done = chand->lb_policy->PickLocked(&calld->pick);
if (pick_done) {
- /* synchronous grpc_lb_policy_pick call. Unref the LB policy. */
+ // Pick completed synchronously.
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: pick completed synchronously",
chand, calld);
@@ -1147,7 +2680,7 @@ static bool pick_callback_start_locked(grpc_call_element* elem) {
GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback_cancel");
grpc_call_combiner_set_notify_on_cancel(
calld->call_combiner,
- GRPC_CLOSURE_INIT(&calld->lb_pick_cancel_closure,
+ GRPC_CLOSURE_INIT(&calld->pick_cancel_closure,
pick_callback_cancel_locked, elem,
grpc_combiner_scheduler(chand->combiner)));
}
@@ -1196,8 +2729,6 @@ static void pick_after_resolver_result_cancel_locked(void* arg,
"Pick cancelled", &error, 1));
}
-static void pick_after_resolver_result_start_locked(grpc_call_element* elem);
-
static void pick_after_resolver_result_done_locked(void* arg,
grpc_error* error) {
pick_after_resolver_result_args* args =
@@ -1234,7 +2765,7 @@ static void pick_after_resolver_result_done_locked(void* arg,
async_pick_done_locked(elem, GRPC_ERROR_NONE);
}
}
- // TODO(roth): It should be impossible for chand->lb_policy to be NULL
+ // TODO(roth): It should be impossible for chand->lb_policy to be nullptr
// here, so the rest of this code should never actually be executed.
// However, we have reports of a crash on iOS that triggers this case,
// so we are temporarily adding this to restore branches that were
@@ -1287,6 +2818,7 @@ static void start_pick_locked(void* arg, grpc_error* ignored) {
call_data* calld = static_cast<call_data*>(elem->call_data);
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
GPR_ASSERT(calld->pick.connected_subchannel == nullptr);
+ GPR_ASSERT(calld->subchannel_call == nullptr);
if (chand->lb_policy != nullptr) {
// We already have an LB policy, so ask it for a pick.
if (pick_callback_start_locked(elem)) {
@@ -1315,24 +2847,9 @@ static void start_pick_locked(void* arg, grpc_error* ignored) {
chand->interested_parties);
}
-static void on_complete(void* arg, grpc_error* error) {
- grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
- call_data* calld = static_cast<call_data*>(elem->call_data);
- if (calld->retry_throttle_data != nullptr) {
- if (error == GRPC_ERROR_NONE) {
- grpc_server_retry_throttle_data_record_success(
- calld->retry_throttle_data);
- } else {
- // TODO(roth): In a subsequent PR, check the return value here and
- // decide whether or not to retry. Note that we should only
- // record failures whose statuses match the configured retryable
- // or non-fatal status codes.
- grpc_server_retry_throttle_data_record_failure(
- calld->retry_throttle_data);
- }
- }
- GRPC_CLOSURE_RUN(calld->original_on_complete, GRPC_ERROR_REF(error));
-}
+//
+// filter call vtable functions
+//
static void cc_start_transport_stream_op_batch(
grpc_call_element* elem, grpc_transport_stream_op_batch* batch) {
@@ -1343,46 +2860,47 @@ static void cc_start_transport_stream_op_batch(
grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch);
}
// If we've previously been cancelled, immediately fail any new batches.
- if (calld->error != GRPC_ERROR_NONE) {
+ if (calld->cancel_error != GRPC_ERROR_NONE) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: failing batch with error: %s",
- chand, calld, grpc_error_string(calld->error));
+ chand, calld, grpc_error_string(calld->cancel_error));
}
+ // Note: This will release the call combiner.
grpc_transport_stream_op_batch_finish_with_failure(
- batch, GRPC_ERROR_REF(calld->error), calld->call_combiner);
+ batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner);
return;
}
+ // Handle cancellation.
if (batch->cancel_stream) {
// Stash a copy of cancel_error in our call data, so that we can use
// it for subsequent operations. This ensures that if the call is
// cancelled before any batches are passed down (e.g., if the deadline
// is in the past when the call starts), we can return the right
// error to the caller when the first batch does get passed down.
- GRPC_ERROR_UNREF(calld->error);
- calld->error = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
+ GRPC_ERROR_UNREF(calld->cancel_error);
+ calld->cancel_error =
+ GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG, "chand=%p calld=%p: recording cancel_error=%s", chand,
- calld, grpc_error_string(calld->error));
+ calld, grpc_error_string(calld->cancel_error));
}
- // If we have a subchannel call, send the cancellation batch down.
- // Otherwise, fail all pending batches.
- if (calld->subchannel_call != nullptr) {
- grpc_subchannel_call_process_op(calld->subchannel_call, batch);
+ // If we do not have a subchannel call (i.e., a pick has not yet
+ // been started), fail all pending batches. Otherwise, send the
+ // cancellation down to the subchannel call.
+ if (calld->subchannel_call == nullptr) {
+ pending_batches_fail(elem, GRPC_ERROR_REF(calld->cancel_error),
+ false /* yield_call_combiner */);
+ // Note: This will release the call combiner.
+ grpc_transport_stream_op_batch_finish_with_failure(
+ batch, GRPC_ERROR_REF(calld->cancel_error), calld->call_combiner);
} else {
- waiting_for_pick_batches_add(calld, batch);
- waiting_for_pick_batches_fail(elem, GRPC_ERROR_REF(calld->error));
+ // Note: This will release the call combiner.
+ grpc_subchannel_call_process_op(calld->subchannel_call, batch);
}
return;
}
- // Intercept on_complete for recv_trailing_metadata so that we can
- // check retry throttle status.
- if (batch->recv_trailing_metadata) {
- GPR_ASSERT(batch->on_complete != nullptr);
- calld->original_on_complete = batch->on_complete;
- GRPC_CLOSURE_INIT(&calld->on_complete, on_complete, elem,
- grpc_schedule_on_exec_ctx);
- batch->on_complete = &calld->on_complete;
- }
+ // Add the batch to the pending list.
+ pending_batches_add(elem, batch);
// Check if we've already gotten a subchannel call.
// Note that once we have completed the pick, we do not need to enter
// the channel combiner, which is more efficient (especially for
@@ -1390,15 +2908,13 @@ static void cc_start_transport_stream_op_batch(
if (calld->subchannel_call != nullptr) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_DEBUG,
- "chand=%p calld=%p: sending batch to subchannel_call=%p", chand,
+ "chand=%p calld=%p: starting batch on subchannel_call=%p", chand,
calld, calld->subchannel_call);
}
- grpc_subchannel_call_process_op(calld->subchannel_call, batch);
+ pending_batches_resume(elem);
return;
}
// We do not yet have a subchannel call.
- // Add the batch to the waiting-for-pick list.
- waiting_for_pick_batches_add(calld, batch);
// For batches containing a send_initial_metadata op, enter the channel
// combiner to start a pick.
if (batch->send_initial_metadata) {
@@ -1438,6 +2954,7 @@ static grpc_error* cc_init_call_elem(grpc_call_element* elem,
grpc_deadline_state_init(elem, args->call_stack, args->call_combiner,
calld->deadline);
}
+ calld->enable_retries = chand->enable_retries;
return GRPC_ERROR_NONE;
}
@@ -1451,10 +2968,8 @@ static void cc_destroy_call_elem(grpc_call_element* elem,
grpc_deadline_state_destroy(elem);
}
grpc_slice_unref_internal(calld->path);
- if (calld->method_params != nullptr) {
- method_parameters_unref(calld->method_params);
- }
- GRPC_ERROR_UNREF(calld->error);
+ calld->method_params.reset();
+ GRPC_ERROR_UNREF(calld->cancel_error);
if (calld->subchannel_call != nullptr) {
grpc_subchannel_call_set_cleanup_closure(calld->subchannel_call,
then_schedule_closure);
@@ -1462,7 +2977,9 @@ static void cc_destroy_call_elem(grpc_call_element* elem,
GRPC_SUBCHANNEL_CALL_UNREF(calld->subchannel_call,
"client_channel_destroy_call");
}
- GPR_ASSERT(calld->waiting_for_pick_batches_count == 0);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(calld->pending_batches); ++i) {
+ GPR_ASSERT(calld->pending_batches[i].batch == nullptr);
+ }
if (calld->pick.connected_subchannel != nullptr) {
calld->pick.connected_subchannel.reset();
}
@@ -1502,7 +3019,7 @@ const grpc_channel_filter grpc_client_channel_filter = {
static void try_to_connect_locked(void* arg, grpc_error* error_ignored) {
channel_data* chand = static_cast<channel_data*>(arg);
if (chand->lb_policy != nullptr) {
- grpc_lb_policy_exit_idle_locked(chand->lb_policy);
+ chand->lb_policy->ExitIdleLocked();
} else {
chand->exit_idle_when_lb_policy_arrives = true;
if (!chand->started_resolving && chand->resolver != nullptr) {
@@ -1662,3 +3179,9 @@ void grpc_client_channel_watch_connectivity_state(
grpc_combiner_scheduler(chand->combiner)),
GRPC_ERROR_NONE);
}
+
+grpc_subchannel_call* grpc_client_channel_get_subchannel_call(
+ grpc_call_element* elem) {
+ call_data* calld = static_cast<call_data*>(elem->call_data);
+ return calld->subchannel_call;
+}
diff --git a/src/core/ext/filters/client_channel/client_channel.h b/src/core/ext/filters/client_channel/client_channel.h
index 9670405cbe..a21e5623a7 100644
--- a/src/core/ext/filters/client_channel/client_channel.h
+++ b/src/core/ext/filters/client_channel/client_channel.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/channel/channel_stack.h"
diff --git a/src/core/ext/filters/client_channel/client_channel_factory.cc b/src/core/ext/filters/client_channel/client_channel_factory.cc
index 3baf5b31ab..172e9f03c7 100644
--- a/src/core/ext/filters/client_channel/client_channel_factory.cc
+++ b/src/core/ext/filters/client_channel/client_channel_factory.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/lib/channel/channel_args.h"
diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h
index 766ebb9389..601ec46b2a 100644
--- a/src/core/ext/filters/client_channel/client_channel_factory.h
+++ b/src/core/ext/filters/client_channel/client_channel_factory.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CLIENT_CHANNEL_FACTORY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/ext/filters/client_channel/subchannel.h"
diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc
index 9172fa781c..3c3a97532f 100644
--- a/src/core/ext/filters/client_channel/client_channel_plugin.cc
+++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc
@@ -63,7 +63,7 @@ static bool set_default_host_if_unset(grpc_channel_stack_builder* builder,
}
void grpc_client_channel_init(void) {
- grpc_lb_policy_registry_init();
+ grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry();
grpc_core::ResolverRegistry::Builder::InitRegistry();
grpc_retry_throttle_map_init();
grpc_proxy_mapper_registry_init();
@@ -83,5 +83,5 @@ void grpc_client_channel_shutdown(void) {
grpc_proxy_mapper_registry_shutdown();
grpc_retry_throttle_map_shutdown();
grpc_core::ResolverRegistry::Builder::ShutdownRegistry();
- grpc_lb_policy_registry_shutdown();
+ grpc_core::LoadBalancingPolicyRegistry::Builder::ShutdownRegistry();
}
diff --git a/src/core/ext/filters/client_channel/connector.cc b/src/core/ext/filters/client_channel/connector.cc
index c8bf2f3e1c..5e04b3b453 100644
--- a/src/core/ext/filters/client_channel/connector.cc
+++ b/src/core/ext/filters/client_channel/connector.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/connector.h"
grpc_connector* grpc_connector_ref(grpc_connector* connector) {
diff --git a/src/core/ext/filters/client_channel/connector.h b/src/core/ext/filters/client_channel/connector.h
index d657658d67..556594929c 100644
--- a/src/core/ext/filters/client_channel/connector.h
+++ b/src/core/ext/filters/client_channel/connector.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONNECTOR_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_CONNECTOR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/transport/transport.h"
diff --git a/src/core/ext/filters/client_channel/http_connect_handshaker.cc b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
index 6bb4cefe73..fb29fa788d 100644
--- a/src/core/ext/filters/client_channel/http_connect_handshaker.cc
+++ b/src/core/ext/filters/client_channel/http_connect_handshaker.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include <string.h>
@@ -254,7 +256,8 @@ static void http_connect_handshaker_do_handshake(
// If not found, invoke on_handshake_done without doing anything.
const grpc_arg* arg =
grpc_channel_args_find(args->args, GRPC_ARG_HTTP_CONNECT_SERVER);
- if (arg == nullptr) {
+ char* server_name = grpc_channel_arg_get_string(arg);
+ if (server_name == nullptr) {
// Set shutdown to true so that subsequent calls to
// http_connect_handshaker_shutdown() do nothing.
gpr_mu_lock(&handshaker->mu);
@@ -263,17 +266,15 @@ static void http_connect_handshaker_do_handshake(
GRPC_CLOSURE_SCHED(on_handshake_done, GRPC_ERROR_NONE);
return;
}
- GPR_ASSERT(arg->type == GRPC_ARG_STRING);
- char* server_name = arg->value.string;
// Get headers from channel args.
arg = grpc_channel_args_find(args->args, GRPC_ARG_HTTP_CONNECT_HEADERS);
+ char* arg_header_string = grpc_channel_arg_get_string(arg);
grpc_http_header* headers = nullptr;
size_t num_headers = 0;
char** header_strings = nullptr;
size_t num_header_strings = 0;
- if (arg != nullptr) {
- GPR_ASSERT(arg->type == GRPC_ARG_STRING);
- gpr_string_split(arg->value.string, "\n", &header_strings,
+ if (arg_header_string != nullptr) {
+ gpr_string_split(arg_header_string, "\n", &header_strings,
&num_header_strings);
headers = static_cast<grpc_http_header*>(
gpr_malloc(sizeof(grpc_http_header) * num_header_strings));
diff --git a/src/core/ext/filters/client_channel/http_proxy.cc b/src/core/ext/filters/client_channel/http_proxy.cc
index d42376413d..29a6c0e367 100644
--- a/src/core/ext/filters/client_channel/http_proxy.cc
+++ b/src/core/ext/filters/client_channel/http_proxy.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/http_proxy.h"
#include <stdbool.h>
diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc
index 27fb2ad1f4..fa63dd75b5 100644
--- a/src/core/ext/filters/client_channel/lb_policy.cc
+++ b/src/core/ext/filters/client_channel/lb_policy.cc
@@ -16,127 +16,44 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/lib/iomgr/combiner.h"
grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(
false, "lb_policy_refcount");
-void grpc_lb_policy_init(grpc_lb_policy* policy,
- const grpc_lb_policy_vtable* vtable,
- grpc_combiner* combiner) {
- policy->vtable = vtable;
- gpr_ref_init(&policy->refs, 1);
- policy->interested_parties = grpc_pollset_set_create();
- policy->combiner = GRPC_COMBINER_REF(combiner, "lb_policy");
-}
-
-#ifndef NDEBUG
-void grpc_lb_policy_ref(grpc_lb_policy* lb_policy, const char* file, int line,
- const char* reason) {
- if (grpc_trace_lb_policy_refcount.enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&lb_policy->refs.count);
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "LB_POLICY:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", lb_policy,
- old_refs, old_refs + 1, reason);
- }
-#else
-void grpc_lb_policy_ref(grpc_lb_policy* lb_policy) {
-#endif
- gpr_ref(&lb_policy->refs);
-}
-
-#ifndef NDEBUG
-void grpc_lb_policy_unref(grpc_lb_policy* lb_policy, const char* file, int line,
- const char* reason) {
- if (grpc_trace_lb_policy_refcount.enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&lb_policy->refs.count);
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "LB_POLICY:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", lb_policy,
- old_refs, old_refs - 1, reason);
- }
-#else
-void grpc_lb_policy_unref(grpc_lb_policy* lb_policy) {
-#endif
- if (gpr_unref(&lb_policy->refs)) {
- grpc_pollset_set_destroy(lb_policy->interested_parties);
- grpc_combiner* combiner = lb_policy->combiner;
- lb_policy->vtable->destroy(lb_policy);
- GRPC_COMBINER_UNREF(combiner, "lb_policy");
- }
-}
-
-void grpc_lb_policy_shutdown_locked(grpc_lb_policy* policy,
- grpc_lb_policy* new_policy) {
- policy->vtable->shutdown_locked(policy, new_policy);
-}
+namespace grpc_core {
-int grpc_lb_policy_pick_locked(grpc_lb_policy* policy,
- grpc_lb_policy_pick_state* pick) {
- return policy->vtable->pick_locked(policy, pick);
-}
-
-void grpc_lb_policy_cancel_pick_locked(grpc_lb_policy* policy,
- grpc_lb_policy_pick_state* pick,
- grpc_error* error) {
- policy->vtable->cancel_pick_locked(policy, pick, error);
-}
+LoadBalancingPolicy::LoadBalancingPolicy(const Args& args)
+ : InternallyRefCountedWithTracing(&grpc_trace_lb_policy_refcount),
+ combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")),
+ client_channel_factory_(args.client_channel_factory),
+ interested_parties_(grpc_pollset_set_create()),
+ request_reresolution_(nullptr) {}
-void grpc_lb_policy_cancel_picks_locked(grpc_lb_policy* policy,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error* error) {
- policy->vtable->cancel_picks_locked(policy, initial_metadata_flags_mask,
- initial_metadata_flags_eq, error);
+LoadBalancingPolicy::~LoadBalancingPolicy() {
+ grpc_pollset_set_destroy(interested_parties_);
+ GRPC_COMBINER_UNREF(combiner_, "lb_policy");
}
-void grpc_lb_policy_exit_idle_locked(grpc_lb_policy* policy) {
- policy->vtable->exit_idle_locked(policy);
-}
-
-void grpc_lb_policy_ping_one_locked(grpc_lb_policy* policy,
- grpc_closure* on_initiate,
- grpc_closure* on_ack) {
- policy->vtable->ping_one_locked(policy, on_initiate, on_ack);
-}
-
-void grpc_lb_policy_notify_on_state_change_locked(
- grpc_lb_policy* policy, grpc_connectivity_state* state,
- grpc_closure* closure) {
- policy->vtable->notify_on_state_change_locked(policy, state, closure);
-}
-
-grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
- grpc_lb_policy* policy, grpc_error** connectivity_error) {
- return policy->vtable->check_connectivity_locked(policy, connectivity_error);
-}
-
-void grpc_lb_policy_update_locked(grpc_lb_policy* policy,
- const grpc_lb_policy_args* lb_policy_args) {
- policy->vtable->update_locked(policy, lb_policy_args);
-}
-
-void grpc_lb_policy_set_reresolve_closure_locked(
- grpc_lb_policy* policy, grpc_closure* request_reresolution) {
- GPR_ASSERT(policy->request_reresolution == nullptr);
- policy->request_reresolution = request_reresolution;
-}
-
-void grpc_lb_policy_try_reresolve(grpc_lb_policy* policy,
- grpc_core::TraceFlag* grpc_lb_trace,
- grpc_error* error) {
- if (policy->request_reresolution != nullptr) {
- GRPC_CLOSURE_SCHED(policy->request_reresolution, error);
- policy->request_reresolution = nullptr;
+void LoadBalancingPolicy::TryReresolutionLocked(
+ grpc_core::TraceFlag* grpc_lb_trace, grpc_error* error) {
+ if (request_reresolution_ != nullptr) {
+ GRPC_CLOSURE_SCHED(request_reresolution_, error);
+ request_reresolution_ = nullptr;
if (grpc_lb_trace->enabled()) {
gpr_log(GPR_DEBUG,
"%s %p: scheduling re-resolution closure with error=%s.",
- grpc_lb_trace->name(), policy, grpc_error_string(error));
+ grpc_lb_trace->name(), this, grpc_error_string(error));
}
} else {
if (grpc_lb_trace->enabled()) {
gpr_log(GPR_DEBUG, "%s %p: no available re-resolution closure.",
- grpc_lb_trace->name(), policy);
+ grpc_lb_trace->name(), this);
}
}
}
+
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 6edd314d5e..c3e43e5ef6 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -19,182 +19,183 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/transport/connectivity_state.h"
-/** A load balancing policy: specified by a vtable and a struct (which
- is expected to be extended to contain some parameters) */
-typedef struct grpc_lb_policy grpc_lb_policy;
-typedef struct grpc_lb_policy_vtable grpc_lb_policy_vtable;
-typedef struct grpc_lb_policy_args grpc_lb_policy_args;
-
extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount;
-struct grpc_lb_policy {
- const grpc_lb_policy_vtable* vtable;
- gpr_refcount refs;
- /* owned pointer to interested parties in load balancing decisions */
- grpc_pollset_set* interested_parties;
- /* combiner under which lb_policy actions take place */
- grpc_combiner* combiner;
- /* callback to force a re-resolution */
- grpc_closure* request_reresolution;
-};
-
-/// State used for an LB pick.
-typedef struct grpc_lb_policy_pick_state {
- /// Initial metadata associated with the picking call.
- grpc_metadata_batch* initial_metadata;
- /// Bitmask used for selective cancelling. See \a
- /// grpc_lb_policy_cancel_picks() and \a GRPC_INITIAL_METADATA_* in
- /// grpc_types.h.
- uint32_t initial_metadata_flags;
- /// Storage for LB token in \a initial_metadata, or NULL if not used.
- grpc_linked_mdelem lb_token_mdelem_storage;
- /// Closure to run when pick is complete, if not completed synchronously.
- grpc_closure* on_complete;
- /// Will be set to the selected subchannel, or nullptr on failure or when
- /// the LB policy decides to drop the call.
- grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel;
- /// Will be populated with context to pass to the subchannel call, if needed.
- grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
- /// Upon success, \a *user_data will be set to whatever opaque information
- /// may need to be propagated from the LB policy, or NULL if not needed.
- void** user_data;
- /// Next pointer. For internal use by LB policy.
- struct grpc_lb_policy_pick_state* next;
-} grpc_lb_policy_pick_state;
-
-struct grpc_lb_policy_vtable {
- void (*destroy)(grpc_lb_policy* policy);
-
- /// \see grpc_lb_policy_shutdown_locked().
- void (*shutdown_locked)(grpc_lb_policy* policy, grpc_lb_policy* new_policy);
-
- /** \see grpc_lb_policy_pick */
- int (*pick_locked)(grpc_lb_policy* policy, grpc_lb_policy_pick_state* pick);
-
- /** \see grpc_lb_policy_cancel_pick */
- void (*cancel_pick_locked)(grpc_lb_policy* policy,
- grpc_lb_policy_pick_state* pick,
+namespace grpc_core {
+
+/// Interface for load balancing policies.
+///
+/// Note: All methods with a "Locked" suffix must be called from the
+/// combiner passed to the constructor.
+///
+/// Any I/O done by the LB policy should be done under the pollset_set
+/// returned by \a interested_parties().
+class LoadBalancingPolicy
+ : public InternallyRefCountedWithTracing<LoadBalancingPolicy> {
+ public:
+ struct Args {
+ /// The combiner under which all LB policy calls will be run.
+ /// Policy does NOT take ownership of the reference to the combiner.
+ // TODO(roth): Once we have a C++-like interface for combiners, this
+ // API should change to take a smart pointer that does pass ownership
+ // of a reference.
+ grpc_combiner* combiner = nullptr;
+ /// Used to create channels and subchannels.
+ grpc_client_channel_factory* client_channel_factory = nullptr;
+ /// Channel args from the resolver.
+ /// Note that the LB policy gets the set of addresses from the
+ /// GRPC_ARG_LB_ADDRESSES channel arg.
+ grpc_channel_args* args = nullptr;
+ };
+
+ /// State used for an LB pick.
+ struct PickState {
+ /// Initial metadata associated with the picking call.
+ grpc_metadata_batch* initial_metadata;
+ /// Bitmask used for selective cancelling. See
+ /// \a CancelMatchingPicksLocked() and \a GRPC_INITIAL_METADATA_* in
+ /// grpc_types.h.
+ uint32_t initial_metadata_flags;
+ /// Storage for LB token in \a initial_metadata, or nullptr if not used.
+ grpc_linked_mdelem lb_token_mdelem_storage;
+ /// Closure to run when pick is complete, if not completed synchronously.
+ grpc_closure* on_complete;
+ /// Will be set to the selected subchannel, or nullptr on failure or when
+ /// the LB policy decides to drop the call.
+ RefCountedPtr<ConnectedSubchannel> connected_subchannel;
+ /// Will be populated with context to pass to the subchannel call, if
+ /// needed.
+ grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT];
+ /// Upon success, \a *user_data will be set to whatever opaque information
+ /// may need to be propagated from the LB policy, or nullptr if not needed.
+ // TODO(roth): As part of revamping our metadata APIs, try to find a
+ // way to clean this up and C++-ify it.
+ void** user_data;
+ /// Next pointer. For internal use by LB policy.
+ PickState* next;
+ };
+
+ // Not copyable nor movable.
+ LoadBalancingPolicy(const LoadBalancingPolicy&) = delete;
+ LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete;
+
+ /// Updates the policy with a new set of \a args from the resolver.
+ /// Note that the LB policy gets the set of addresses from the
+ /// GRPC_ARG_LB_ADDRESSES channel arg.
+ virtual void UpdateLocked(const grpc_channel_args& args) GRPC_ABSTRACT;
+
+ /// Finds an appropriate subchannel for a call, based on data in \a pick.
+ /// \a pick must remain alive until the pick is complete.
+ ///
+ /// If the pick succeeds and a result is known immediately, returns true.
+ /// Otherwise, \a pick->on_complete will be invoked once the pick is
+ /// complete with its error argument set to indicate success or failure.
+ virtual bool PickLocked(PickState* pick) GRPC_ABSTRACT;
+
+ /// Cancels \a pick.
+ /// The \a on_complete callback of the pending pick will be invoked with
+ /// \a pick->connected_subchannel set to null.
+ virtual void CancelPickLocked(PickState* pick,
+ grpc_error* error) GRPC_ABSTRACT;
+
+ /// Cancels all pending picks for which their \a initial_metadata_flags (as
+ /// given in the call to \a PickLocked()) matches
+ /// \a initial_metadata_flags_eq when ANDed with
+ /// \a initial_metadata_flags_mask.
+ virtual void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) GRPC_ABSTRACT;
+
+ /// Requests a notification when the connectivity state of the policy
+ /// changes from \a *state. When that happens, sets \a *state to the
+ /// new state and schedules \a closure.
+ virtual void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
+ grpc_closure* closure) GRPC_ABSTRACT;
+
+ /// Returns the policy's current connectivity state. Sets \a error to
+ /// the associated error, if any.
+ virtual grpc_connectivity_state CheckConnectivityLocked(
+ grpc_error** connectivity_error) GRPC_ABSTRACT;
+
+ /// Hands off pending picks to \a new_policy.
+ virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy)
+ GRPC_ABSTRACT;
+
+ /// Performs a connected subchannel ping via \a ConnectedSubchannel::Ping()
+ /// against one of the connected subchannels managed by the policy.
+ /// Note: This is intended only for use in tests.
+ virtual void PingOneLocked(grpc_closure* on_initiate,
+ grpc_closure* on_ack) GRPC_ABSTRACT;
+
+ /// Tries to enter a READY connectivity state.
+ /// TODO(roth): As part of restructuring how we handle IDLE state,
+ /// consider whether this method is still needed.
+ virtual void ExitIdleLocked() GRPC_ABSTRACT;
+
+ void Orphan() override {
+ // Invoke ShutdownAndUnrefLocked() inside of the combiner.
+ GRPC_CLOSURE_SCHED(
+ GRPC_CLOSURE_CREATE(&LoadBalancingPolicy::ShutdownAndUnrefLocked, this,
+ grpc_combiner_scheduler(combiner_)),
+ GRPC_ERROR_NONE);
+ }
+
+ /// Sets the re-resolution closure to \a request_reresolution.
+ void SetReresolutionClosureLocked(grpc_closure* request_reresolution) {
+ GPR_ASSERT(request_reresolution_ == nullptr);
+ request_reresolution_ = request_reresolution;
+ }
+
+ grpc_pollset_set* interested_parties() const { return interested_parties_; }
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ explicit LoadBalancingPolicy(const Args& args);
+ virtual ~LoadBalancingPolicy();
+
+ grpc_combiner* combiner() const { return combiner_; }
+ grpc_client_channel_factory* client_channel_factory() const {
+ return client_channel_factory_;
+ }
+
+ /// Shuts down the policy. Any pending picks that have not been
+ /// handed off to a new policy via HandOffPendingPicksLocked() will be
+ /// failed.
+ virtual void ShutdownLocked() GRPC_ABSTRACT;
+
+ /// Tries to request a re-resolution.
+ void TryReresolutionLocked(grpc_core::TraceFlag* grpc_lb_trace,
grpc_error* error);
- /** \see grpc_lb_policy_cancel_picks */
- void (*cancel_picks_locked)(grpc_lb_policy* policy,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error* error);
-
- /** \see grpc_lb_policy_ping_one */
- void (*ping_one_locked)(grpc_lb_policy* policy, grpc_closure* on_initiate,
- grpc_closure* on_ack);
-
- /** Try to enter a READY connectivity state */
- void (*exit_idle_locked)(grpc_lb_policy* policy);
-
- /** check the current connectivity of the lb_policy */
- grpc_connectivity_state (*check_connectivity_locked)(
- grpc_lb_policy* policy, grpc_error** connectivity_error);
-
- /** call notify when the connectivity state of a channel changes from *state.
- Updates *state with the new state of the policy. Calling with a NULL \a
- state cancels the subscription. */
- void (*notify_on_state_change_locked)(grpc_lb_policy* policy,
- grpc_connectivity_state* state,
- grpc_closure* closure);
-
- void (*update_locked)(grpc_lb_policy* policy,
- const grpc_lb_policy_args* args);
+ private:
+ static void ShutdownAndUnrefLocked(void* arg, grpc_error* ignored) {
+ LoadBalancingPolicy* policy = static_cast<LoadBalancingPolicy*>(arg);
+ policy->ShutdownLocked();
+ policy->Unref();
+ }
+
+ /// Combiner under which LB policy actions take place.
+ grpc_combiner* combiner_;
+ /// Client channel factory, used to create channels and subchannels.
+ grpc_client_channel_factory* client_channel_factory_;
+ /// Owned pointer to interested parties in load balancing decisions.
+ grpc_pollset_set* interested_parties_;
+ /// Callback to force a re-resolution.
+ grpc_closure* request_reresolution_;
};
-#ifndef NDEBUG
-#define GRPC_LB_POLICY_REF(p, r) \
- grpc_lb_policy_ref((p), __FILE__, __LINE__, (r))
-#define GRPC_LB_POLICY_UNREF(p, r) \
- grpc_lb_policy_unref((p), __FILE__, __LINE__, (r))
-void grpc_lb_policy_ref(grpc_lb_policy* policy, const char* file, int line,
- const char* reason);
-void grpc_lb_policy_unref(grpc_lb_policy* policy, const char* file, int line,
- const char* reason);
-#else // !NDEBUG
-#define GRPC_LB_POLICY_REF(p, r) grpc_lb_policy_ref((p))
-#define GRPC_LB_POLICY_UNREF(p, r) grpc_lb_policy_unref((p))
-void grpc_lb_policy_ref(grpc_lb_policy* policy);
-void grpc_lb_policy_unref(grpc_lb_policy* policy);
-#endif
-
-/** called by concrete implementations to initialize the base struct */
-void grpc_lb_policy_init(grpc_lb_policy* policy,
- const grpc_lb_policy_vtable* vtable,
- grpc_combiner* combiner);
-
-/// Shuts down \a policy.
-/// If \a new_policy is non-null, any pending picks will be restarted
-/// on that policy; otherwise, they will be failed.
-void grpc_lb_policy_shutdown_locked(grpc_lb_policy* policy,
- grpc_lb_policy* new_policy);
-
-/** Finds an appropriate subchannel for a call, based on data in \a pick.
- \a pick must remain alive until the pick is complete.
-
- If the pick succeeds and a result is known immediately, a non-zero
- value will be returned. Otherwise, \a pick->on_complete will be invoked
- once the pick is complete with its error argument set to indicate
- success or failure.
-
- Any IO should be done under the \a interested_parties \a grpc_pollset_set
- in the \a grpc_lb_policy struct. */
-int grpc_lb_policy_pick_locked(grpc_lb_policy* policy,
- grpc_lb_policy_pick_state* pick);
-
-/** Perform a connected subchannel ping (see \a
- grpc_core::ConnectedSubchannel::Ping)
- against one of the connected subchannels managed by \a policy. */
-void grpc_lb_policy_ping_one_locked(grpc_lb_policy* policy,
- grpc_closure* on_initiate,
- grpc_closure* on_ack);
-
-/** Cancel picks for \a pick.
- The \a on_complete callback of the pending picks will be invoked with \a
- *target set to NULL. */
-void grpc_lb_policy_cancel_pick_locked(grpc_lb_policy* policy,
- grpc_lb_policy_pick_state* pick,
- grpc_error* error);
-
-/** Cancel all pending picks for which their \a initial_metadata_flags (as given
- in the call to \a grpc_lb_policy_pick) matches \a initial_metadata_flags_eq
- when AND'd with \a initial_metadata_flags_mask */
-void grpc_lb_policy_cancel_picks_locked(grpc_lb_policy* policy,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error* error);
-
-/** Try to enter a READY connectivity state */
-void grpc_lb_policy_exit_idle_locked(grpc_lb_policy* policy);
-
-/* Call notify when the connectivity state of a channel changes from \a *state.
- * Updates \a *state with the new state of the policy */
-void grpc_lb_policy_notify_on_state_change_locked(
- grpc_lb_policy* policy, grpc_connectivity_state* state,
- grpc_closure* closure);
-
-grpc_connectivity_state grpc_lb_policy_check_connectivity_locked(
- grpc_lb_policy* policy, grpc_error** connectivity_error);
-
-/** Update \a policy with \a lb_policy_args. */
-void grpc_lb_policy_update_locked(grpc_lb_policy* policy,
- const grpc_lb_policy_args* lb_policy_args);
-
-/** Set the re-resolution closure to \a request_reresolution. */
-void grpc_lb_policy_set_reresolve_closure_locked(
- grpc_lb_policy* policy, grpc_closure* request_reresolution);
-
-/** Try to request a re-resolution. It's NOT a public API; it's only for use by
- the LB policy implementations. */
-void grpc_lb_policy_try_reresolve(grpc_lb_policy* policy,
- grpc_core::TraceFlag* grpc_lb_trace,
- grpc_error* error);
+} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_H */
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
index 1a3a1f029c..18ef1f6ff5 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
#include <grpc/support/atm.h>
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
index 04de7a04df..838e2ef1ca 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_CLIENT_LOAD_REPORTING_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_client_load_reporting_filter;
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index 1c8809eabc..7c0e33ff0a 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -16,68 +16,50 @@
*
*/
-/** Implementation of the gRPC LB policy.
- *
- * This policy takes as input a set of resolved addresses {a1..an} for which the
- * LB set was set (it's the resolver's responsibility to ensure this). That is
- * to say, {a1..an} represent a collection of LB servers.
- *
- * An internal channel (\a glb_lb_policy.lb_channel) is created over {a1..an}.
- * This channel behaves just like a regular channel. In particular, the
- * constructed URI over the addresses a1..an will use the default pick first
- * policy to select from this list of LB server backends.
- *
- * The first time the policy gets a request for a pick, a ping, or to exit the
- * idle state, \a query_for_backends_locked() is called. This function sets up
- * and initiates the internal communication with the LB server. In particular,
- * it's responsible for instantiating the internal *streaming* call to the LB
- * server (whichever address from {a1..an} pick-first chose). This call is
- * serviced by two callbacks, \a lb_on_server_status_received and \a
- * lb_on_response_received. The former will be called when the call to the LB
- * server completes. This can happen if the LB server closes the connection or
- * if this policy itself cancels the call (for example because it's shutting
- * down). If the internal call times out, the usual behavior of pick-first
- * applies, continuing to pick from the list {a1..an}.
- *
- * Upon sucesss, the incoming \a LoadBalancingResponse is processed by \a
- * res_recv. An invalid one results in the termination of the streaming call. A
- * new streaming call should be created if possible, failing the original call
- * otherwise. For a valid \a LoadBalancingResponse, the server list of actual
- * backends is extracted. A Round Robin policy will be created from this list.
- * There are two possible scenarios:
- *
- * 1. This is the first server list received. There was no previous instance of
- * the Round Robin policy. \a rr_handover_locked() will instantiate the RR
- * policy and perform all the pending operations over it.
- * 2. There's already a RR policy instance active. We need to introduce the new
- * one build from the new serverlist, but taking care not to disrupt the
- * operations in progress over the old RR instance. This is done by
- * decreasing the reference count on the old policy. The moment no more
- * references are held on the old RR policy, it'll be destroyed and \a
- * on_rr_connectivity_changed notified with a \a GRPC_CHANNEL_SHUTDOWN
- * state. At this point we can transition to a new RR instance safely, which
- * is done once again via \a rr_handover_locked().
- *
- *
- * Once a RR policy instance is in place (and getting updated as described),
- * calls to for a pick, a ping or a cancellation will be serviced right away by
- * forwarding them to the RR instance. Any time there's no RR policy available
- * (ie, right after the creation of the gRPCLB policy, if an empty serverlist is
- * received, etc), pick/ping requests are added to a list of pending picks/pings
- * to be flushed and serviced as part of \a rr_handover_locked() the moment the
- * RR policy instance becomes available.
- *
- * \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the
- * high level design and details. */
+/// Implementation of the gRPC LB policy.
+///
+/// This policy takes as input a list of resolved addresses, which must
+/// include at least one balancer address.
+///
+/// An internal channel (\a lb_channel_) is created for the addresses
+/// from that are balancers. This channel behaves just like a regular
+/// channel that uses pick_first to select from the list of balancer
+/// addresses.
+///
+/// The first time the policy gets a request for a pick, a ping, or to exit
+/// the idle state, \a StartPickingLocked() is called. This method is
+/// responsible for instantiating the internal *streaming* call to the LB
+/// server (whichever address pick_first chose). The call will be complete
+/// when either the balancer sends status or when we cancel the call (e.g.,
+/// because we are shutting down). In needed, we retry the call. If we
+/// received at least one valid message from the server, a new call attempt
+/// will be made immediately; otherwise, we apply back-off delays between
+/// attempts.
+///
+/// We maintain an internal round_robin policy instance for distributing
+/// requests across backends. Whenever we receive a new serverlist from
+/// the balancer, we update the round_robin policy with the new list of
+/// addresses. If we cannot communicate with the balancer on startup,
+/// however, we may enter fallback mode, in which case we will populate
+/// the RR policy's addresses from the backend addresses returned by the
+/// resolver.
+///
+/// Once an RR policy instance is in place (and getting updated as described),
+/// calls for a pick, a ping, or a cancellation will be serviced right
+/// away by forwarding them to the RR instance. Any time there's no RR
+/// policy available (i.e., right after the creation of the gRPCLB policy),
+/// pick and ping requests are added to a list of pending picks and pings
+/// to be flushed and serviced when the RR policy instance becomes available.
+///
+/// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the
+/// high level design and details.
-/* TODO(dgq):
- * - Implement LB service forwarding (point 2c. in the doc's diagram).
- */
+// With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
+// using that endpoint. Because of various transitive includes in uv.h,
+// including windows.h on Windows, uv.h must be included before other system
+// headers. Therefore, sockaddr.h must always be included first.
+#include <grpc/support/port_platform.h>
-/* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
- using that endpoint. Because of various transitive includes in uv.h,
- including windows.h on Windows, uv.h must be included before other system
- headers. Therefore, sockaddr.h must always be included first */
#include "src/core/lib/iomgr/sockaddr.h"
#include <inttypes.h>
@@ -93,7 +75,6 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
-#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
@@ -108,6 +89,8 @@
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/manual_constructor.h"
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/sockaddr.h"
@@ -127,336 +110,294 @@
#define GRPC_GRPCLB_RECONNECT_JITTER 0.2
#define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000
-grpc_core::TraceFlag grpc_lb_glb_trace(false, "glb");
+namespace grpc_core {
-struct glb_lb_policy;
+TraceFlag grpc_lb_glb_trace(false, "glb");
namespace {
-/// Linked list of pending pick requests. It stores all information needed to
-/// eventually call (Round Robin's) pick() on them. They mainly stay pending
-/// waiting for the RR policy to be created.
-///
-/// Note that when a pick is sent to the RR policy, we inject our own
-/// on_complete callback, so that we can intercept the result before
-/// invoking the original on_complete callback. This allows us to set the
-/// LB token metadata and add client_stats to the call context.
-/// See \a pending_pick_complete() for details.
-struct pending_pick {
- // Our on_complete closure and the original one.
- grpc_closure on_complete;
- grpc_closure* original_on_complete;
- // The original pick.
- grpc_lb_policy_pick_state* pick;
- // Stats for client-side load reporting. Note that this holds a
- // reference, which must be either passed on via context or unreffed.
- grpc_grpclb_client_stats* client_stats;
- // The LB token associated with the pick. This is set via user_data in
- // the pick.
- grpc_mdelem lb_token;
- // The grpclb instance that created the wrapping. This instance is not owned,
- // reference counts are untouched. It's used only for logging purposes.
- glb_lb_policy* glb_policy;
- // Next pending pick.
- struct pending_pick* next;
-};
+class GrpcLb : public LoadBalancingPolicy {
+ public:
+ GrpcLb(const grpc_lb_addresses* addresses, const Args& args);
+
+ void UpdateLocked(const grpc_channel_args& args) override;
+ bool PickLocked(PickState* pick) override;
+ void CancelPickLocked(PickState* pick, grpc_error* error) override;
+ void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) override;
+ void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
+ grpc_closure* closure) override;
+ grpc_connectivity_state CheckConnectivityLocked(
+ grpc_error** connectivity_error) override;
+ void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
+ void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
+ void ExitIdleLocked() override;
+
+ private:
+ /// Linked list of pending pick requests. It stores all information needed to
+ /// eventually call (Round Robin's) pick() on them. They mainly stay pending
+ /// waiting for the RR policy to be created.
+ ///
+ /// Note that when a pick is sent to the RR policy, we inject our own
+ /// on_complete callback, so that we can intercept the result before
+ /// invoking the original on_complete callback. This allows us to set the
+ /// LB token metadata and add client_stats to the call context.
+ /// See \a pending_pick_complete() for details.
+ struct PendingPick {
+ // The grpclb instance that created the wrapping. This instance is not
+ // owned; reference counts are untouched. It's used only for logging
+ // purposes.
+ GrpcLb* grpclb_policy;
+ // The original pick.
+ PickState* pick;
+ // Our on_complete closure and the original one.
+ grpc_closure on_complete;
+ grpc_closure* original_on_complete;
+ // The LB token associated with the pick. This is set via user_data in
+ // the pick.
+ grpc_mdelem lb_token;
+ // Stats for client-side load reporting. Note that this holds a
+ // reference, which must be either passed on via context or unreffed.
+ grpc_grpclb_client_stats* client_stats = nullptr;
+ // Next pending pick.
+ PendingPick* next = nullptr;
+ };
+
+ /// A linked list of pending pings waiting for the RR policy to be created.
+ struct PendingPing {
+ grpc_closure* on_initiate;
+ grpc_closure* on_ack;
+ PendingPing* next = nullptr;
+ };
+
+ /// Contains a call to the LB server and all the data related to the call.
+ class BalancerCallState
+ : public InternallyRefCountedWithTracing<BalancerCallState> {
+ public:
+ explicit BalancerCallState(
+ RefCountedPtr<LoadBalancingPolicy> parent_grpclb_policy);
+
+ // It's the caller's responsibility to ensure that Orphan() is called from
+ // inside the combiner.
+ void Orphan() override;
+
+ void StartQuery();
+
+ grpc_grpclb_client_stats* client_stats() const { return client_stats_; }
+ bool seen_initial_response() const { return seen_initial_response_; }
+
+ private:
+ ~BalancerCallState();
+
+ GrpcLb* grpclb_policy() const {
+ return reinterpret_cast<GrpcLb*>(grpclb_policy_.get());
+ }
-/// A linked list of pending pings waiting for the RR policy to be created.
-struct pending_ping {
- grpc_closure* on_initiate;
- grpc_closure* on_ack;
- struct pending_ping* next;
+ void ScheduleNextClientLoadReportLocked();
+ void SendClientLoadReportLocked();
+
+ static bool LoadReportCountersAreZero(grpc_grpclb_request* request);
+
+ static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error);
+ static void ClientLoadReportDoneLocked(void* arg, grpc_error* error);
+ static void OnInitialRequestSentLocked(void* arg, grpc_error* error);
+ static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error);
+ static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error);
+
+ // The owning LB policy.
+ RefCountedPtr<LoadBalancingPolicy> grpclb_policy_;
+
+ // The streaming call to the LB server. Always non-NULL.
+ grpc_call* lb_call_ = nullptr;
+
+ // recv_initial_metadata
+ grpc_metadata_array lb_initial_metadata_recv_;
+
+ // send_message
+ grpc_byte_buffer* send_message_payload_ = nullptr;
+ grpc_closure lb_on_initial_request_sent_;
+
+ // recv_message
+ grpc_byte_buffer* recv_message_payload_ = nullptr;
+ grpc_closure lb_on_balancer_message_received_;
+ bool seen_initial_response_ = false;
+
+ // recv_trailing_metadata
+ grpc_closure lb_on_balancer_status_received_;
+ grpc_metadata_array lb_trailing_metadata_recv_;
+ grpc_status_code lb_call_status_;
+ grpc_slice lb_call_status_details_;
+
+ // The stats for client-side load reporting associated with this LB call.
+ // Created after the first serverlist is received.
+ grpc_grpclb_client_stats* client_stats_ = nullptr;
+ grpc_millis client_stats_report_interval_ = 0;
+ grpc_timer client_load_report_timer_;
+ bool client_load_report_timer_callback_pending_ = false;
+ bool last_client_load_report_counters_were_zero_ = false;
+ bool client_load_report_is_due_ = false;
+ // The closure used for either the load report timer or the callback for
+ // completion of sending the load report.
+ grpc_closure client_load_report_closure_;
+ };
+
+ ~GrpcLb();
+
+ void ShutdownLocked() override;
+
+ // Helper function used in ctor and UpdateLocked().
+ void ProcessChannelArgsLocked(const grpc_channel_args& args);
+
+ // Methods for dealing with the balancer channel and call.
+ void StartPickingLocked();
+ void StartBalancerCallLocked();
+ static void OnFallbackTimerLocked(void* arg, grpc_error* error);
+ void StartBalancerCallRetryTimerLocked();
+ static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error);
+ static void OnBalancerChannelConnectivityChangedLocked(void* arg,
+ grpc_error* error);
+
+ // Pending pick methods.
+ static void PendingPickSetMetadataAndContext(PendingPick* pp);
+ PendingPick* PendingPickCreate(PickState* pick);
+ void AddPendingPick(PendingPick* pp);
+ static void OnPendingPickComplete(void* arg, grpc_error* error);
+
+ // Pending ping methods.
+ void AddPendingPing(grpc_closure* on_initiate, grpc_closure* on_ack);
+
+ // Methods for dealing with the RR policy.
+ void CreateOrUpdateRoundRobinPolicyLocked();
+ grpc_channel_args* CreateRoundRobinPolicyArgsLocked();
+ void CreateRoundRobinPolicyLocked(const Args& args);
+ bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp);
+ void UpdateConnectivityStateFromRoundRobinPolicyLocked(
+ grpc_error* rr_state_error);
+ static void OnRoundRobinConnectivityChangedLocked(void* arg,
+ grpc_error* error);
+ static void OnRoundRobinRequestReresolutionLocked(void* arg,
+ grpc_error* error);
+
+ // Who the client is trying to communicate with.
+ const char* server_name_ = nullptr;
+
+ // Current channel args from the resolver.
+ grpc_channel_args* args_ = nullptr;
+
+ // Internal state.
+ bool started_picking_ = false;
+ bool shutting_down_ = false;
+ grpc_connectivity_state_tracker state_tracker_;
+
+ // The channel for communicating with the LB server.
+ grpc_channel* lb_channel_ = nullptr;
+ grpc_connectivity_state lb_channel_connectivity_;
+ grpc_closure lb_channel_on_connectivity_changed_;
+ // Are we already watching the LB channel's connectivity?
+ bool watching_lb_channel_ = false;
+ // Response generator to inject address updates into lb_channel_.
+ RefCountedPtr<FakeResolverResponseGenerator> response_generator_;
+
+ // The data associated with the current LB call. It holds a ref to this LB
+ // policy. It's initialized every time we query for backends. It's reset to
+ // NULL whenever the current LB call is no longer needed (e.g., the LB policy
+ // is shutting down, or the LB call has ended). A non-NULL lb_calld_ always
+ // contains a non-NULL lb_call_.
+ OrphanablePtr<BalancerCallState> lb_calld_;
+ // Timeout in milliseconds for the LB call. 0 means no deadline.
+ int lb_call_timeout_ms_ = 0;
+ // Balancer call retry state.
+ BackOff lb_call_backoff_;
+ bool retry_timer_callback_pending_ = false;
+ grpc_timer lb_call_retry_timer_;
+ grpc_closure lb_on_call_retry_;
+
+ // The deserialized response from the balancer. May be nullptr until one
+ // such response has arrived.
+ grpc_grpclb_serverlist* serverlist_ = nullptr;
+ // Index into serverlist for next pick.
+ // If the server at this index is a drop, we return a drop.
+ // Otherwise, we delegate to the RR policy.
+ size_t serverlist_index_ = 0;
+
+ // Timeout in milliseconds for before using fallback backend addresses.
+ // 0 means not using fallback.
+ int lb_fallback_timeout_ms_ = 0;
+ // The backend addresses from the resolver.
+ grpc_lb_addresses* fallback_backend_addresses_ = nullptr;
+ // Fallback timer.
+ bool fallback_timer_callback_pending_ = false;
+ grpc_timer lb_fallback_timer_;
+ grpc_closure lb_on_fallback_;
+
+ // Pending picks and pings that are waiting on the RR policy's connectivity.
+ PendingPick* pending_picks_ = nullptr;
+ PendingPing* pending_pings_ = nullptr;
+
+ // The RR policy to use for the backends.
+ OrphanablePtr<LoadBalancingPolicy> rr_policy_;
+ grpc_connectivity_state rr_connectivity_state_;
+ grpc_closure on_rr_connectivity_changed_;
+ grpc_closure on_rr_request_reresolution_;
};
-} // namespace
-
-typedef struct glb_lb_call_data {
- struct glb_lb_policy* glb_policy;
- // TODO(juanlishen): c++ize this struct.
- gpr_refcount refs;
-
- /** The streaming call to the LB server. Always non-NULL. */
- grpc_call* lb_call;
-
- /** The initial metadata received from the LB server. */
- grpc_metadata_array lb_initial_metadata_recv;
-
- /** The message sent to the LB server. It's used to query for backends (the
- * value may vary if the LB server indicates a redirect) or send client load
- * report. */
- grpc_byte_buffer* send_message_payload;
- /** The callback after the initial request is sent. */
- grpc_closure lb_on_sent_initial_request;
-
- /** The response received from the LB server, if any. */
- grpc_byte_buffer* recv_message_payload;
- /** The callback to process the response received from the LB server. */
- grpc_closure lb_on_response_received;
- bool seen_initial_response;
-
- /** The callback to process the status received from the LB server, which
- * signals the end of the LB call. */
- grpc_closure lb_on_server_status_received;
- /** The trailing metadata from the LB server. */
- grpc_metadata_array lb_trailing_metadata_recv;
- /** The call status code and details. */
- grpc_status_code lb_call_status;
- grpc_slice lb_call_status_details;
-
- /** The stats for client-side load reporting associated with this LB call.
- * Created after the first serverlist is received. */
- grpc_grpclb_client_stats* client_stats;
- /** The interval and timer for next client load report. */
- grpc_millis client_stats_report_interval;
- grpc_timer client_load_report_timer;
- bool client_load_report_timer_callback_pending;
- bool last_client_load_report_counters_were_zero;
- bool client_load_report_is_due;
- /** The closure used for either the load report timer or the callback for
- * completion of sending the load report. */
- grpc_closure client_load_report_closure;
-} glb_lb_call_data;
-
-typedef struct glb_lb_policy {
- /** Base policy: must be first. */
- grpc_lb_policy base;
-
- /** Who the client is trying to communicate with. */
- const char* server_name;
-
- /** Channel related data that will be propagated to the internal RR policy. */
- grpc_client_channel_factory* cc_factory;
- grpc_channel_args* args;
-
- /** Timeout in milliseconds for before using fallback backend addresses.
- * 0 means not using fallback. */
- int lb_fallback_timeout_ms;
-
- /** The channel for communicating with the LB server. */
- grpc_channel* lb_channel;
-
- /** The data associated with the current LB call. It holds a ref to this LB
- * policy. It's initialized every time we query for backends. It's reset to
- * NULL whenever the current LB call is no longer needed (e.g., the LB policy
- * is shutting down, or the LB call has ended). A non-NULL lb_calld always
- * contains a non-NULL lb_call. */
- glb_lb_call_data* lb_calld;
-
- /** response generator to inject address updates into \a lb_channel */
- grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
- response_generator;
-
- /** the RR policy to use of the backend servers returned by the LB server */
- grpc_lb_policy* rr_policy;
-
- /** the connectivity state of the embedded RR policy */
- grpc_connectivity_state rr_connectivity_state;
-
- bool started_picking;
-
- /** our connectivity state tracker */
- grpc_connectivity_state_tracker state_tracker;
-
- /** connectivity state of the LB channel */
- grpc_connectivity_state lb_channel_connectivity;
-
- /** stores the deserialized response from the LB. May be nullptr until one
- * such response has arrived. */
- grpc_grpclb_serverlist* serverlist;
-
- /** Index into serverlist for next pick.
- * If the server at this index is a drop, we return a drop.
- * Otherwise, we delegate to the RR policy. */
- size_t serverlist_index;
-
- /** stores the backend addresses from the resolver */
- grpc_lb_addresses* fallback_backend_addresses;
-
- /** list of picks that are waiting on RR's policy connectivity */
- pending_pick* pending_picks;
-
- /** list of pings that are waiting on RR's policy connectivity */
- pending_ping* pending_pings;
-
- bool shutting_down;
-
- /** are we already watching the LB channel's connectivity? */
- bool watching_lb_channel;
-
- /** is the callback associated with \a lb_call_retry_timer pending? */
- bool retry_timer_callback_pending;
-
- /** is the callback associated with \a lb_fallback_timer pending? */
- bool fallback_timer_callback_pending;
-
- /** called upon changes to the LB channel's connectivity. */
- grpc_closure lb_channel_on_connectivity_changed;
-
- /** called upon changes to the RR's connectivity. */
- grpc_closure rr_on_connectivity_changed;
-
- /** called upon reresolution request from the RR policy. */
- grpc_closure rr_on_reresolution_requested;
-
- /************************************************************/
- /* client data associated with the LB server communication */
- /************************************************************/
-
- /** LB call retry backoff state */
- grpc_core::ManualConstructor<grpc_core::BackOff> lb_call_backoff;
-
- /** timeout in milliseconds for the LB call. 0 means no deadline. */
- int lb_call_timeout_ms;
-
- /** LB call retry timer */
- grpc_timer lb_call_retry_timer;
- /** LB call retry timer callback */
- grpc_closure lb_on_call_retry;
-
- /** LB fallback timer */
- grpc_timer lb_fallback_timer;
- /** LB fallback timer callback */
- grpc_closure lb_on_fallback;
-} glb_lb_policy;
-
-static void glb_lb_call_data_ref(glb_lb_call_data* lb_calld,
- const char* reason) {
- gpr_ref_non_zero(&lb_calld->refs);
- if (grpc_lb_glb_trace.enabled()) {
- const gpr_atm count = gpr_atm_acq_load(&lb_calld->refs.count);
- gpr_log(GPR_DEBUG, "[%s %p] lb_calld %p REF %lu->%lu (%s)",
- grpc_lb_glb_trace.name(), lb_calld->glb_policy, lb_calld,
- static_cast<unsigned long>(count - 1),
- static_cast<unsigned long>(count), reason);
- }
-}
+//
+// serverlist parsing code
+//
-static void glb_lb_call_data_unref(glb_lb_call_data* lb_calld,
- const char* reason) {
- const bool done = gpr_unref(&lb_calld->refs);
- if (grpc_lb_glb_trace.enabled()) {
- const gpr_atm count = gpr_atm_acq_load(&lb_calld->refs.count);
- gpr_log(GPR_DEBUG, "[%s %p] lb_calld %p UNREF %lu->%lu (%s)",
- grpc_lb_glb_trace.name(), lb_calld->glb_policy, lb_calld,
- static_cast<unsigned long>(count + 1),
- static_cast<unsigned long>(count), reason);
- }
- if (done) {
- GPR_ASSERT(lb_calld->lb_call != nullptr);
- grpc_call_unref(lb_calld->lb_call);
- grpc_metadata_array_destroy(&lb_calld->lb_initial_metadata_recv);
- grpc_metadata_array_destroy(&lb_calld->lb_trailing_metadata_recv);
- grpc_byte_buffer_destroy(lb_calld->send_message_payload);
- grpc_byte_buffer_destroy(lb_calld->recv_message_payload);
- grpc_slice_unref_internal(lb_calld->lb_call_status_details);
- if (lb_calld->client_stats != nullptr) {
- grpc_grpclb_client_stats_unref(lb_calld->client_stats);
- }
- GRPC_LB_POLICY_UNREF(&lb_calld->glb_policy->base, "lb_calld");
- gpr_free(lb_calld);
- }
+// vtable for LB tokens in grpc_lb_addresses
+void* lb_token_copy(void* token) {
+ return token == nullptr
+ ? nullptr
+ : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload;
}
-
-static void lb_call_data_shutdown(glb_lb_policy* glb_policy) {
- GPR_ASSERT(glb_policy->lb_calld != nullptr);
- GPR_ASSERT(glb_policy->lb_calld->lb_call != nullptr);
- // lb_on_server_status_received will complete the cancellation and clean up.
- grpc_call_cancel(glb_policy->lb_calld->lb_call, nullptr);
- if (glb_policy->lb_calld->client_load_report_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_calld->client_load_report_timer);
+void lb_token_destroy(void* token) {
+ if (token != nullptr) {
+ GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token});
}
- glb_policy->lb_calld = nullptr;
}
-
-/* add lb_token of selected subchannel (address) to the call's initial
- * metadata */
-static grpc_error* initial_metadata_add_lb_token(
- grpc_metadata_batch* initial_metadata,
- grpc_linked_mdelem* lb_token_mdelem_storage, grpc_mdelem lb_token) {
- GPR_ASSERT(lb_token_mdelem_storage != nullptr);
- GPR_ASSERT(!GRPC_MDISNULL(lb_token));
- return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
- lb_token);
-}
-
-static void destroy_client_stats(void* arg) {
- grpc_grpclb_client_stats_unref(static_cast<grpc_grpclb_client_stats*>(arg));
+int lb_token_cmp(void* token1, void* token2) {
+ if (token1 > token2) return 1;
+ if (token1 < token2) return -1;
+ return 0;
}
+const grpc_lb_user_data_vtable lb_token_vtable = {
+ lb_token_copy, lb_token_destroy, lb_token_cmp};
-static void pending_pick_set_metadata_and_context(pending_pick* pp) {
- /* if connected_subchannel is nullptr, no pick has been made by the RR
- * policy (e.g., all addresses failed to connect). There won't be any
- * user_data/token available */
- if (pp->pick->connected_subchannel != nullptr) {
- if (!GRPC_MDISNULL(pp->lb_token)) {
- initial_metadata_add_lb_token(pp->pick->initial_metadata,
- &pp->pick->lb_token_mdelem_storage,
- GRPC_MDELEM_REF(pp->lb_token));
- } else {
- gpr_log(GPR_ERROR,
- "[grpclb %p] No LB token for connected subchannel pick %p",
- pp->glb_policy, pp->pick);
- abort();
- }
- // Pass on client stats via context. Passes ownership of the reference.
- if (pp->client_stats != nullptr) {
- pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
- pp->client_stats;
- pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy =
- destroy_client_stats;
- }
- } else {
- if (pp->client_stats != nullptr) {
- grpc_grpclb_client_stats_unref(pp->client_stats);
+// Returns the backend addresses extracted from the given addresses.
+grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) {
+ // First pass: count the number of backend addresses.
+ size_t num_backends = 0;
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ if (!addresses->addresses[i].is_balancer) {
+ ++num_backends;
}
}
+ // Second pass: actually populate the addresses and (empty) LB tokens.
+ grpc_lb_addresses* backend_addresses =
+ grpc_lb_addresses_create(num_backends, &lb_token_vtable);
+ size_t num_copied = 0;
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ if (addresses->addresses[i].is_balancer) continue;
+ const grpc_resolved_address* addr = &addresses->addresses[i].address;
+ grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr,
+ addr->len, false /* is_balancer */,
+ nullptr /* balancer_name */,
+ (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload);
+ ++num_copied;
+ }
+ return backend_addresses;
}
-/* The \a on_complete closure passed as part of the pick requires keeping a
- * reference to its associated round robin instance. We wrap this closure in
- * order to unref the round robin instance upon its invocation */
-static void pending_pick_complete(void* arg, grpc_error* error) {
- pending_pick* pp = static_cast<pending_pick*>(arg);
- pending_pick_set_metadata_and_context(pp);
- GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error));
- gpr_free(pp);
-}
-
-static pending_pick* pending_pick_create(glb_lb_policy* glb_policy,
- grpc_lb_policy_pick_state* pick) {
- pending_pick* pp = static_cast<pending_pick*>(gpr_zalloc(sizeof(*pp)));
- pp->pick = pick;
- pp->glb_policy = glb_policy;
- GRPC_CLOSURE_INIT(&pp->on_complete, pending_pick_complete, pp,
- grpc_schedule_on_exec_ctx);
- pp->original_on_complete = pick->on_complete;
- pp->pick->on_complete = &pp->on_complete;
- return pp;
-}
-
-static void pending_pick_add(pending_pick** root, pending_pick* new_pp) {
- new_pp->next = *root;
- *root = new_pp;
-}
-
-static void pending_ping_add(pending_ping** root, grpc_closure* on_initiate,
- grpc_closure* on_ack) {
- pending_ping* pping = static_cast<pending_ping*>(gpr_zalloc(sizeof(*pping)));
- pping->on_initiate = on_initiate;
- pping->on_ack = on_ack;
- pping->next = *root;
- *root = pping;
-}
-
-static bool is_server_valid(const grpc_grpclb_server* server, size_t idx,
- bool log) {
+bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) {
if (server->drop) return false;
const grpc_grpclb_ip_address* ip = &server->ip_address;
if (server->port >> 16 != 0) {
if (log) {
gpr_log(GPR_ERROR,
"Invalid port '%d' at index %lu of serverlist. Ignoring.",
- server->port, static_cast<unsigned long>(idx));
+ server->port, (unsigned long)idx);
}
return false;
}
@@ -465,65 +406,43 @@ static bool is_server_valid(const grpc_grpclb_server* server, size_t idx,
gpr_log(GPR_ERROR,
"Expected IP to be 4 or 16 bytes, got %d at index %lu of "
"serverlist. Ignoring",
- ip->size, static_cast<unsigned long>(idx));
+ ip->size, (unsigned long)idx);
}
return false;
}
return true;
}
-/* vtable for LB tokens in grpc_lb_addresses. */
-static void* lb_token_copy(void* token) {
- return token == nullptr
- ? nullptr
- : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload;
-}
-static void lb_token_destroy(void* token) {
- if (token != nullptr) {
- GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token});
- }
-}
-static int lb_token_cmp(void* token1, void* token2) {
- if (token1 > token2) return 1;
- if (token1 < token2) return -1;
- return 0;
-}
-static const grpc_lb_user_data_vtable lb_token_vtable = {
- lb_token_copy, lb_token_destroy, lb_token_cmp};
-
-static void parse_server(const grpc_grpclb_server* server,
- grpc_resolved_address* addr) {
+void ParseServer(const grpc_grpclb_server* server,
+ grpc_resolved_address* addr) {
memset(addr, 0, sizeof(*addr));
if (server->drop) return;
- const uint16_t netorder_port = htons(static_cast<uint16_t>(server->port));
+ const uint16_t netorder_port = htons((uint16_t)server->port);
/* the addresses are given in binary format (a in(6)_addr struct) in
* server->ip_address.bytes. */
const grpc_grpclb_ip_address* ip = &server->ip_address;
if (ip->size == 4) {
addr->len = sizeof(struct sockaddr_in);
- struct sockaddr_in* addr4 =
- reinterpret_cast<struct sockaddr_in*>(&addr->addr);
+ struct sockaddr_in* addr4 = (struct sockaddr_in*)&addr->addr;
addr4->sin_family = AF_INET;
memcpy(&addr4->sin_addr, ip->bytes, ip->size);
addr4->sin_port = netorder_port;
} else if (ip->size == 16) {
addr->len = sizeof(struct sockaddr_in6);
- struct sockaddr_in6* addr6 =
- reinterpret_cast<struct sockaddr_in6*>(&addr->addr);
+ struct sockaddr_in6* addr6 = (struct sockaddr_in6*)&addr->addr;
addr6->sin6_family = AF_INET6;
memcpy(&addr6->sin6_addr, ip->bytes, ip->size);
addr6->sin6_port = netorder_port;
}
}
-/* Returns addresses extracted from \a serverlist. */
-static grpc_lb_addresses* process_serverlist_locked(
- const grpc_grpclb_serverlist* serverlist) {
+// Returns addresses extracted from \a serverlist.
+grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
size_t num_valid = 0;
/* first pass: count how many are valid in order to allocate the necessary
* memory in a single block */
for (size_t i = 0; i < serverlist->num_servers; ++i) {
- if (is_server_valid(serverlist->servers[i], i, true)) ++num_valid;
+ if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid;
}
grpc_lb_addresses* lb_addresses =
grpc_lb_addresses_create(num_valid, &lb_token_vtable);
@@ -535,11 +454,11 @@ static grpc_lb_addresses* process_serverlist_locked(
size_t addr_idx = 0;
for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) {
const grpc_grpclb_server* server = serverlist->servers[sl_idx];
- if (!is_server_valid(serverlist->servers[sl_idx], sl_idx, false)) continue;
+ if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue;
GPR_ASSERT(addr_idx < num_valid);
/* address processing */
grpc_resolved_address addr;
- parse_server(server, &addr);
+ ParseServer(server, &addr);
/* lb token processing */
void* user_data;
if (server->has_load_balance_token) {
@@ -570,849 +489,89 @@ static grpc_lb_addresses* process_serverlist_locked(
return lb_addresses;
}
-/* Returns the backend addresses extracted from the given addresses */
-static grpc_lb_addresses* extract_backend_addresses_locked(
- const grpc_lb_addresses* addresses) {
- /* first pass: count the number of backend addresses */
- size_t num_backends = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) {
- ++num_backends;
- }
- }
- /* second pass: actually populate the addresses and (empty) LB tokens */
- grpc_lb_addresses* backend_addresses =
- grpc_lb_addresses_create(num_backends, &lb_token_vtable);
- size_t num_copied = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) continue;
- const grpc_resolved_address* addr = &addresses->addresses[i].address;
- grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr,
- addr->len, false /* is_balancer */,
- nullptr /* balancer_name */,
- (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload);
- ++num_copied;
- }
- return backend_addresses;
-}
-
-static void update_lb_connectivity_status_locked(glb_lb_policy* glb_policy,
- grpc_error* rr_state_error) {
- const grpc_connectivity_state curr_glb_state =
- grpc_connectivity_state_check(&glb_policy->state_tracker);
- /* The new connectivity status is a function of the previous one and the new
- * input coming from the status of the RR policy.
- *
- * current state (grpclb's)
- * |
- * v || I | C | R | TF | SD | <- new state (RR's)
- * ===++====+=====+=====+======+======+
- * I || I | C | R | [I] | [I] |
- * ---++----+-----+-----+------+------+
- * C || I | C | R | [C] | [C] |
- * ---++----+-----+-----+------+------+
- * R || I | C | R | [R] | [R] |
- * ---++----+-----+-----+------+------+
- * TF || I | C | R | [TF] | [TF] |
- * ---++----+-----+-----+------+------+
- * SD || NA | NA | NA | NA | NA | (*)
- * ---++----+-----+-----+------+------+
- *
- * A [STATE] indicates that the old RR policy is kept. In those cases, STATE
- * is the current state of grpclb, which is left untouched.
- *
- * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to
- * the previous RR instance.
- *
- * Note that the status is never updated to SHUTDOWN as a result of calling
- * this function. Only glb_shutdown() has the power to set that state.
- *
- * (*) This function mustn't be called during shutting down. */
- GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN);
- switch (glb_policy->rr_connectivity_state) {
- case GRPC_CHANNEL_TRANSIENT_FAILURE:
- case GRPC_CHANNEL_SHUTDOWN:
- GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE);
- break;
- case GRPC_CHANNEL_IDLE:
- case GRPC_CHANNEL_CONNECTING:
- case GRPC_CHANNEL_READY:
- GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE);
- }
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(
- GPR_INFO,
- "[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.",
- glb_policy,
- grpc_connectivity_state_name(glb_policy->rr_connectivity_state),
- glb_policy->rr_policy);
- }
- grpc_connectivity_state_set(&glb_policy->state_tracker,
- glb_policy->rr_connectivity_state, rr_state_error,
- "update_lb_connectivity_status_locked");
-}
-
-/* Perform a pick over \a glb_policy->rr_policy. Given that a pick can return
- * immediately (ignoring its completion callback), we need to perform the
- * cleanups this callback would otherwise be responsible for.
- * If \a force_async is true, then we will manually schedule the
- * completion callback even if the pick is available immediately. */
-static bool pick_from_internal_rr_locked(glb_lb_policy* glb_policy,
- bool force_async, pending_pick* pp) {
- // Check for drops if we are not using fallback backend addresses.
- if (glb_policy->serverlist != nullptr) {
- // Look at the index into the serverlist to see if we should drop this call.
- grpc_grpclb_server* server =
- glb_policy->serverlist->servers[glb_policy->serverlist_index++];
- if (glb_policy->serverlist_index == glb_policy->serverlist->num_servers) {
- glb_policy->serverlist_index = 0; // Wrap-around.
- }
- if (server->drop) {
- // Update client load reporting stats to indicate the number of
- // dropped calls. Note that we have to do this here instead of in
- // the client_load_reporting filter, because we do not create a
- // subchannel call (and therefore no client_load_reporting filter)
- // for dropped calls.
- if (glb_policy->lb_calld != nullptr &&
- glb_policy->lb_calld->client_stats != nullptr) {
- grpc_grpclb_client_stats_add_call_dropped_locked(
- server->load_balance_token, glb_policy->lb_calld->client_stats);
- }
- if (force_async) {
- GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
- gpr_free(pp);
- return false;
- }
- gpr_free(pp);
- return true;
- }
- }
- // Set client_stats and user_data.
- if (glb_policy->lb_calld != nullptr &&
- glb_policy->lb_calld->client_stats != nullptr) {
- pp->client_stats =
- grpc_grpclb_client_stats_ref(glb_policy->lb_calld->client_stats);
- }
- GPR_ASSERT(pp->pick->user_data == nullptr);
- pp->pick->user_data = reinterpret_cast<void**>(&pp->lb_token);
- // Pick via the RR policy.
- bool pick_done = grpc_lb_policy_pick_locked(glb_policy->rr_policy, pp->pick);
- if (pick_done) {
- pending_pick_set_metadata_and_context(pp);
- if (force_async) {
- GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
- pick_done = false;
- }
- gpr_free(pp);
- }
- /* else, the pending pick will be registered and taken care of by the
- * pending pick list inside the RR policy (glb_policy->rr_policy).
- * Eventually, wrapped_on_complete will be called, which will -among other
- * things- add the LB token to the call's initial metadata */
- return pick_done;
-}
-
-static grpc_lb_policy_args* lb_policy_args_create(glb_lb_policy* glb_policy) {
- grpc_lb_addresses* addresses;
- if (glb_policy->serverlist != nullptr) {
- GPR_ASSERT(glb_policy->serverlist->num_servers > 0);
- addresses = process_serverlist_locked(glb_policy->serverlist);
- } else {
- // If rr_handover_locked() is invoked when we haven't received any
- // serverlist from the balancer, we use the fallback backends returned by
- // the resolver. Note that the fallback backend list may be empty, in which
- // case the new round_robin policy will keep the requested picks pending.
- GPR_ASSERT(glb_policy->fallback_backend_addresses != nullptr);
- addresses = grpc_lb_addresses_copy(glb_policy->fallback_backend_addresses);
- }
- GPR_ASSERT(addresses != nullptr);
- grpc_lb_policy_args* args =
- static_cast<grpc_lb_policy_args*>(gpr_zalloc(sizeof(*args)));
- args->client_channel_factory = glb_policy->cc_factory;
- args->combiner = glb_policy->base.combiner;
- // Replace the LB addresses in the channel args that we pass down to
- // the subchannel.
- static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
- const grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses);
- args->args = grpc_channel_args_copy_and_add_and_remove(
- glb_policy->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &arg,
- 1);
- grpc_lb_addresses_destroy(addresses);
- return args;
-}
-
-static void lb_policy_args_destroy(grpc_lb_policy_args* args) {
- grpc_channel_args_destroy(args->args);
- gpr_free(args);
-}
-
-static void rr_on_reresolution_requested_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
- if (glb_policy->shutting_down || error != GRPC_ERROR_NONE) {
- GRPC_LB_POLICY_UNREF(&glb_policy->base,
- "rr_on_reresolution_requested_locked");
- return;
- }
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(
- GPR_DEBUG,
- "[grpclb %p] Re-resolution requested from the internal RR policy (%p).",
- glb_policy, glb_policy->rr_policy);
- }
- // If we are talking to a balancer, we expect to get updated addresses form
- // the balancer, so we can ignore the re-resolution request from the RR
- // policy. Otherwise, handle the re-resolution request using glb's original
- // re-resolution closure.
- if (glb_policy->lb_calld == nullptr ||
- !glb_policy->lb_calld->seen_initial_response) {
- grpc_lb_policy_try_reresolve(&glb_policy->base, &grpc_lb_glb_trace,
- GRPC_ERROR_NONE);
- }
- // Give back the wrapper closure to the RR policy.
- grpc_lb_policy_set_reresolve_closure_locked(
- glb_policy->rr_policy, &glb_policy->rr_on_reresolution_requested);
-}
-
-static void create_rr_locked(glb_lb_policy* glb_policy,
- grpc_lb_policy_args* args) {
- GPR_ASSERT(glb_policy->rr_policy == nullptr);
- grpc_lb_policy* new_rr_policy = grpc_lb_policy_create("round_robin", args);
- if (new_rr_policy == nullptr) {
- gpr_log(GPR_ERROR,
- "[grpclb %p] Failure creating a RoundRobin policy for serverlist "
- "update with %" PRIuPTR
- " entries. The previous RR instance (%p), if any, will continue to "
- "be used. Future updates from the LB will attempt to create new "
- "instances.",
- glb_policy, glb_policy->serverlist->num_servers,
- glb_policy->rr_policy);
- return;
- }
- GRPC_LB_POLICY_REF(&glb_policy->base, "rr_on_reresolution_requested_locked");
- grpc_lb_policy_set_reresolve_closure_locked(
- new_rr_policy, &glb_policy->rr_on_reresolution_requested);
- glb_policy->rr_policy = new_rr_policy;
- grpc_error* rr_state_error = nullptr;
- glb_policy->rr_connectivity_state = grpc_lb_policy_check_connectivity_locked(
- glb_policy->rr_policy, &rr_state_error);
- /* Connectivity state is a function of the RR policy updated/created */
- update_lb_connectivity_status_locked(glb_policy, rr_state_error);
- /* Add the gRPC LB's interested_parties pollset_set to that of the newly
- * created RR policy. This will make the RR policy progress upon activity on
- * gRPC LB, which in turn is tied to the application's call */
- grpc_pollset_set_add_pollset_set(glb_policy->rr_policy->interested_parties,
- glb_policy->base.interested_parties);
- /* Subscribe to changes to the connectivity of the new RR */
- GRPC_LB_POLICY_REF(&glb_policy->base, "rr_on_connectivity_changed_locked");
- grpc_lb_policy_notify_on_state_change_locked(
- glb_policy->rr_policy, &glb_policy->rr_connectivity_state,
- &glb_policy->rr_on_connectivity_changed);
- grpc_lb_policy_exit_idle_locked(glb_policy->rr_policy);
- // Send pending picks to RR policy.
- pending_pick* pp;
- while ((pp = glb_policy->pending_picks)) {
- glb_policy->pending_picks = pp->next;
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Pending pick about to (async) PICK from RR %p",
- glb_policy, glb_policy->rr_policy);
- }
- pick_from_internal_rr_locked(glb_policy, true /* force_async */, pp);
- }
- // Send pending pings to RR policy.
- pending_ping* pping;
- while ((pping = glb_policy->pending_pings)) {
- glb_policy->pending_pings = pping->next;
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] Pending ping about to PING from RR %p",
- glb_policy, glb_policy->rr_policy);
- }
- grpc_lb_policy_ping_one_locked(glb_policy->rr_policy, pping->on_initiate,
- pping->on_ack);
- gpr_free(pping);
- }
-}
-
-/* glb_policy->rr_policy may be nullptr (initial handover) */
-static void rr_handover_locked(glb_lb_policy* glb_policy) {
- if (glb_policy->shutting_down) return;
- grpc_lb_policy_args* args = lb_policy_args_create(glb_policy);
- GPR_ASSERT(args != nullptr);
- if (glb_policy->rr_policy != nullptr) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Updating RR policy %p", glb_policy,
- glb_policy->rr_policy);
- }
- grpc_lb_policy_update_locked(glb_policy->rr_policy, args);
- } else {
- create_rr_locked(glb_policy, args);
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Created new RR policy %p", glb_policy,
- glb_policy->rr_policy);
- }
- }
- lb_policy_args_destroy(args);
-}
-
-static void rr_on_connectivity_changed_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = (glb_lb_policy*)arg;
- if (glb_policy->shutting_down) {
- GRPC_LB_POLICY_UNREF(&glb_policy->base,
- "rr_on_connectivity_changed_locked");
- return;
- }
- update_lb_connectivity_status_locked(glb_policy, GRPC_ERROR_REF(error));
- // Resubscribe. Reuse the "rr_on_connectivity_changed_locked" ref.
- grpc_lb_policy_notify_on_state_change_locked(
- glb_policy->rr_policy, &glb_policy->rr_connectivity_state,
- &glb_policy->rr_on_connectivity_changed);
-}
-
-static void destroy_balancer_name(void* balancer_name) {
- gpr_free(balancer_name);
-}
-
-static grpc_slice_hash_table_entry targets_info_entry_create(
- const char* address, const char* balancer_name) {
- grpc_slice_hash_table_entry entry;
- entry.key = grpc_slice_from_copied_string(address);
- entry.value = gpr_strdup(balancer_name);
- return entry;
-}
-
-static int balancer_name_cmp_fn(void* a, void* b) {
- const char* a_str = static_cast<const char*>(a);
- const char* b_str = static_cast<const char*>(b);
- return strcmp(a_str, b_str);
-}
-
-/* Returns the channel args for the LB channel, used to create a bidirectional
- * stream for the reception of load balancing updates.
- *
- * Inputs:
- * - \a addresses: corresponding to the balancers.
- * - \a response_generator: in order to propagate updates from the resolver
- * above the grpclb policy.
- * - \a args: other args inherited from the grpclb policy. */
-static grpc_channel_args* build_lb_channel_args(
- const grpc_lb_addresses* addresses,
- grpc_core::FakeResolverResponseGenerator* response_generator,
- const grpc_channel_args* args) {
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
- }
- /* All input addresses come from a resolver that claims they are LB services.
- * It's the resolver's responsibility to make sure this policy is only
- * instantiated and used in that case. Otherwise, something has gone wrong. */
- GPR_ASSERT(num_grpclb_addrs > 0);
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_grpclb_addrs, nullptr);
- grpc_slice_hash_table_entry* targets_info_entries =
- static_cast<grpc_slice_hash_table_entry*>(
- gpr_zalloc(sizeof(*targets_info_entries) * num_grpclb_addrs));
-
- size_t lb_addresses_idx = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) continue;
- if (addresses->addresses[i].user_data != nullptr) {
- gpr_log(GPR_ERROR,
- "This LB policy doesn't support user data. It will be ignored");
- }
- char* addr_str;
- GPR_ASSERT(grpc_sockaddr_to_string(
- &addr_str, &addresses->addresses[i].address, true) > 0);
- targets_info_entries[lb_addresses_idx] = targets_info_entry_create(
- addr_str, addresses->addresses[i].balancer_name);
- gpr_free(addr_str);
-
- grpc_lb_addresses_set_address(
- lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr,
- addresses->addresses[i].address.len, false /* is balancer */,
- addresses->addresses[i].balancer_name, nullptr /* user data */);
- }
- GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx);
- grpc_slice_hash_table* targets_info =
- grpc_slice_hash_table_create(num_grpclb_addrs, targets_info_entries,
- destroy_balancer_name, balancer_name_cmp_fn);
- gpr_free(targets_info_entries);
-
- grpc_channel_args* lb_channel_args =
- grpc_lb_policy_grpclb_build_lb_channel_args(targets_info,
- response_generator, args);
-
- grpc_arg lb_channel_addresses_arg =
- grpc_lb_addresses_create_channel_arg(lb_addresses);
-
- grpc_channel_args* result = grpc_channel_args_copy_and_add(
- lb_channel_args, &lb_channel_addresses_arg, 1);
- grpc_slice_hash_table_unref(targets_info);
- grpc_channel_args_destroy(lb_channel_args);
- grpc_lb_addresses_destroy(lb_addresses);
- return result;
-}
-
-static void glb_destroy(grpc_lb_policy* pol) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- GPR_ASSERT(glb_policy->pending_picks == nullptr);
- GPR_ASSERT(glb_policy->pending_pings == nullptr);
- gpr_free((void*)glb_policy->server_name);
- grpc_channel_args_destroy(glb_policy->args);
- grpc_connectivity_state_destroy(&glb_policy->state_tracker);
- if (glb_policy->serverlist != nullptr) {
- grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
- }
- if (glb_policy->fallback_backend_addresses != nullptr) {
- grpc_lb_addresses_destroy(glb_policy->fallback_backend_addresses);
- }
- // TODO(roth): Remove this once the LB policy becomes a C++ object.
- glb_policy->response_generator.reset();
- grpc_subchannel_index_unref();
- gpr_free(glb_policy);
-}
-
-static void glb_shutdown_locked(grpc_lb_policy* pol,
- grpc_lb_policy* new_policy) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
- glb_policy->shutting_down = true;
- if (glb_policy->lb_calld != nullptr) {
- lb_call_data_shutdown(glb_policy);
- }
- if (glb_policy->retry_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_call_retry_timer);
- }
- if (glb_policy->fallback_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_fallback_timer);
- }
- if (glb_policy->rr_policy != nullptr) {
- grpc_lb_policy_shutdown_locked(glb_policy->rr_policy, nullptr);
- GRPC_LB_POLICY_UNREF(glb_policy->rr_policy, "glb_shutdown");
- }
- // We destroy the LB channel here because
- // glb_lb_channel_on_connectivity_changed_cb needs a valid glb_policy
- // instance. Destroying the lb channel in glb_destroy would likely result in
- // a callback invocation without a valid glb_policy arg.
- if (glb_policy->lb_channel != nullptr) {
- grpc_channel_destroy(glb_policy->lb_channel);
- glb_policy->lb_channel = nullptr;
- }
- grpc_connectivity_state_set(&glb_policy->state_tracker, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_REF(error), "glb_shutdown");
- grpc_lb_policy_try_reresolve(pol, &grpc_lb_glb_trace, GRPC_ERROR_CANCELLED);
- // Clear pending picks.
- pending_pick* pp = glb_policy->pending_picks;
- glb_policy->pending_picks = nullptr;
- while (pp != nullptr) {
- pending_pick* next = pp->next;
- if (new_policy != nullptr) {
- // Hand pick over to new policy.
- if (pp->client_stats != nullptr) {
- grpc_grpclb_client_stats_unref(pp->client_stats);
- }
- pp->pick->on_complete = pp->original_on_complete;
- if (grpc_lb_policy_pick_locked(new_policy, pp->pick)) {
- // Synchronous return; schedule callback.
- GRPC_CLOSURE_SCHED(pp->pick->on_complete, GRPC_ERROR_NONE);
- }
- gpr_free(pp);
- } else {
- pp->pick->connected_subchannel.reset();
- GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error));
- }
- pp = next;
- }
- // Clear pending pings.
- pending_ping* pping = glb_policy->pending_pings;
- glb_policy->pending_pings = nullptr;
- while (pping != nullptr) {
- pending_ping* next = pping->next;
- GRPC_CLOSURE_SCHED(pping->on_initiate, GRPC_ERROR_REF(error));
- GRPC_CLOSURE_SCHED(pping->on_ack, GRPC_ERROR_REF(error));
- gpr_free(pping);
- pping = next;
- }
- GRPC_ERROR_UNREF(error);
-}
-
-// Cancel a specific pending pick.
//
-// A grpclb pick progresses as follows:
-// - If there's a Round Robin policy (glb_policy->rr_policy) available, it'll be
-// handed over to the RR policy (in create_rr_locked()). From that point
-// onwards, it'll be RR's responsibility. For cancellations, that implies the
-// pick needs also be cancelled by the RR instance.
-// - Otherwise, without an RR instance, picks stay pending at this policy's
-// level (grpclb), inside the glb_policy->pending_picks list. To cancel these,
-// we invoke the completion closure and set *target to nullptr right here.
-static void glb_cancel_pick_locked(grpc_lb_policy* pol,
- grpc_lb_policy_pick_state* pick,
- grpc_error* error) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- pending_pick* pp = glb_policy->pending_picks;
- glb_policy->pending_picks = nullptr;
- while (pp != nullptr) {
- pending_pick* next = pp->next;
- if (pp->pick == pick) {
- pick->connected_subchannel.reset();
- GRPC_CLOSURE_SCHED(&pp->on_complete,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick Cancelled", &error, 1));
- } else {
- pp->next = glb_policy->pending_picks;
- glb_policy->pending_picks = pp;
- }
- pp = next;
- }
- if (glb_policy->rr_policy != nullptr) {
- grpc_lb_policy_cancel_pick_locked(glb_policy->rr_policy, pick,
- GRPC_ERROR_REF(error));
- }
- GRPC_ERROR_UNREF(error);
-}
-
-// Cancel all pending picks.
+// GrpcLb::BalancerCallState
//
-// A grpclb pick progresses as follows:
-// - If there's a Round Robin policy (glb_policy->rr_policy) available, it'll be
-// handed over to the RR policy (in create_rr_locked()). From that point
-// onwards, it'll be RR's responsibility. For cancellations, that implies the
-// pick needs also be cancelled by the RR instance.
-// - Otherwise, without an RR instance, picks stay pending at this policy's
-// level (grpclb), inside the glb_policy->pending_picks list. To cancel these,
-// we invoke the completion closure and set *target to nullptr right here.
-static void glb_cancel_picks_locked(grpc_lb_policy* pol,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error* error) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- pending_pick* pp = glb_policy->pending_picks;
- glb_policy->pending_picks = nullptr;
- while (pp != nullptr) {
- pending_pick* next = pp->next;
- if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) ==
- initial_metadata_flags_eq) {
- GRPC_CLOSURE_SCHED(&pp->on_complete,
- GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick Cancelled", &error, 1));
- } else {
- pp->next = glb_policy->pending_picks;
- glb_policy->pending_picks = pp;
- }
- pp = next;
- }
- if (glb_policy->rr_policy != nullptr) {
- grpc_lb_policy_cancel_picks_locked(
- glb_policy->rr_policy, initial_metadata_flags_mask,
- initial_metadata_flags_eq, GRPC_ERROR_REF(error));
- }
- GRPC_ERROR_UNREF(error);
-}
-
-static void lb_on_fallback_timer_locked(void* arg, grpc_error* error);
-static void query_for_backends_locked(glb_lb_policy* glb_policy);
-static void start_picking_locked(glb_lb_policy* glb_policy) {
- /* start a timer to fall back */
- if (glb_policy->lb_fallback_timeout_ms > 0 &&
- glb_policy->serverlist == nullptr &&
- !glb_policy->fallback_timer_callback_pending) {
- grpc_millis deadline =
- grpc_core::ExecCtx::Get()->Now() + glb_policy->lb_fallback_timeout_ms;
- GRPC_LB_POLICY_REF(&glb_policy->base, "grpclb_fallback_timer");
- GRPC_CLOSURE_INIT(&glb_policy->lb_on_fallback, lb_on_fallback_timer_locked,
- glb_policy,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- glb_policy->fallback_timer_callback_pending = true;
- grpc_timer_init(&glb_policy->lb_fallback_timer, deadline,
- &glb_policy->lb_on_fallback);
- }
- glb_policy->started_picking = true;
- glb_policy->lb_call_backoff->Reset();
- query_for_backends_locked(glb_policy);
-}
-
-static void glb_exit_idle_locked(grpc_lb_policy* pol) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- if (!glb_policy->started_picking) {
- start_picking_locked(glb_policy);
- }
-}
-
-static int glb_pick_locked(grpc_lb_policy* pol,
- grpc_lb_policy_pick_state* pick) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- pending_pick* pp = pending_pick_create(glb_policy, pick);
- bool pick_done = false;
- if (glb_policy->rr_policy != nullptr) {
- const grpc_connectivity_state rr_connectivity_state =
- grpc_lb_policy_check_connectivity_locked(glb_policy->rr_policy,
- nullptr);
- // The glb_policy->rr_policy may have transitioned to SHUTDOWN but the
- // callback registered to capture this event
- // (on_rr_connectivity_changed_locked) may not have been invoked yet. We
- // need to make sure we aren't trying to pick from a RR policy instance
- // that's in shutdown.
- if (rr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] NOT picking from from RR %p: RR conn state=%s",
- glb_policy, glb_policy->rr_policy,
- grpc_connectivity_state_name(rr_connectivity_state));
- }
- pending_pick_add(&glb_policy->pending_picks, pp);
- pick_done = false;
- } else { // RR not in shutdown
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", glb_policy,
- glb_policy->rr_policy);
- }
- pick_done =
- pick_from_internal_rr_locked(glb_policy, false /* force_async */, pp);
- }
- } else { // glb_policy->rr_policy == NULL
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG,
- "[grpclb %p] No RR policy. Adding to grpclb's pending picks",
- glb_policy);
- }
- pending_pick_add(&glb_policy->pending_picks, pp);
- if (!glb_policy->started_picking) {
- start_picking_locked(glb_policy);
- }
- pick_done = false;
- }
- return pick_done;
-}
-static grpc_connectivity_state glb_check_connectivity_locked(
- grpc_lb_policy* pol, grpc_error** connectivity_error) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- return grpc_connectivity_state_get(&glb_policy->state_tracker,
- connectivity_error);
-}
-
-static void glb_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
- grpc_closure* on_ack) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- if (glb_policy->rr_policy) {
- grpc_lb_policy_ping_one_locked(glb_policy->rr_policy, on_initiate, on_ack);
- } else {
- pending_ping_add(&glb_policy->pending_pings, on_initiate, on_ack);
- if (!glb_policy->started_picking) {
- start_picking_locked(glb_policy);
- }
- }
-}
-
-static void glb_notify_on_state_change_locked(grpc_lb_policy* pol,
- grpc_connectivity_state* current,
- grpc_closure* notify) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(pol);
- grpc_connectivity_state_notify_on_state_change(&glb_policy->state_tracker,
- current, notify);
-}
-
-static void lb_call_on_retry_timer_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = static_cast<glb_lb_policy*>(arg);
- glb_policy->retry_timer_callback_pending = false;
- if (!glb_policy->shutting_down && error == GRPC_ERROR_NONE &&
- glb_policy->lb_calld == nullptr) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] Restarting call to LB server", glb_policy);
- }
- query_for_backends_locked(glb_policy);
- }
- GRPC_LB_POLICY_UNREF(&glb_policy->base, "grpclb_retry_timer");
-}
-
-static void start_lb_call_retry_timer_locked(glb_lb_policy* glb_policy) {
- grpc_millis next_try = glb_policy->lb_call_backoff->NextAttemptTime();
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...",
- glb_policy);
- grpc_millis timeout = next_try - grpc_core::ExecCtx::Get()->Now();
- if (timeout > 0) {
- gpr_log(GPR_DEBUG,
- "[grpclb %p] ... retry_timer_active in %" PRIuPTR "ms.",
- glb_policy, timeout);
- } else {
- gpr_log(GPR_DEBUG, "[grpclb %p] ... retry_timer_active immediately.",
- glb_policy);
- }
- }
- GRPC_LB_POLICY_REF(&glb_policy->base, "grpclb_retry_timer");
- GRPC_CLOSURE_INIT(&glb_policy->lb_on_call_retry,
- lb_call_on_retry_timer_locked, glb_policy,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- glb_policy->retry_timer_callback_pending = true;
- grpc_timer_init(&glb_policy->lb_call_retry_timer, next_try,
- &glb_policy->lb_on_call_retry);
-}
-
-static void maybe_send_client_load_report_locked(void* arg, grpc_error* error);
-
-static void schedule_next_client_load_report(glb_lb_call_data* lb_calld) {
- const grpc_millis next_client_load_report_time =
- grpc_core::ExecCtx::Get()->Now() + lb_calld->client_stats_report_interval;
- GRPC_CLOSURE_INIT(
- &lb_calld->client_load_report_closure,
- maybe_send_client_load_report_locked, lb_calld,
- grpc_combiner_scheduler(lb_calld->glb_policy->base.combiner));
- grpc_timer_init(&lb_calld->client_load_report_timer,
- next_client_load_report_time,
- &lb_calld->client_load_report_closure);
- lb_calld->client_load_report_timer_callback_pending = true;
-}
-
-static void client_load_report_done_locked(void* arg, grpc_error* error) {
- glb_lb_call_data* lb_calld = static_cast<glb_lb_call_data*>(arg);
- glb_lb_policy* glb_policy = lb_calld->glb_policy;
- grpc_byte_buffer_destroy(lb_calld->send_message_payload);
- lb_calld->send_message_payload = nullptr;
- if (error != GRPC_ERROR_NONE || lb_calld != glb_policy->lb_calld) {
- glb_lb_call_data_unref(lb_calld, "client_load_report");
- return;
- }
- schedule_next_client_load_report(lb_calld);
-}
-
-static bool load_report_counters_are_zero(grpc_grpclb_request* request) {
- grpc_grpclb_dropped_call_counts* drop_entries =
- static_cast<grpc_grpclb_dropped_call_counts*>(
- request->client_stats.calls_finished_with_drop.arg);
- return request->client_stats.num_calls_started == 0 &&
- request->client_stats.num_calls_finished == 0 &&
- request->client_stats.num_calls_finished_with_client_failed_to_send ==
- 0 &&
- request->client_stats.num_calls_finished_known_received == 0 &&
- (drop_entries == nullptr || drop_entries->num_entries == 0);
-}
-
-static void send_client_load_report_locked(glb_lb_call_data* lb_calld) {
- glb_lb_policy* glb_policy = lb_calld->glb_policy;
- // Construct message payload.
- GPR_ASSERT(lb_calld->send_message_payload == nullptr);
- grpc_grpclb_request* request =
- grpc_grpclb_load_report_request_create_locked(lb_calld->client_stats);
- // Skip client load report if the counters were all zero in the last
- // report and they are still zero in this one.
- if (load_report_counters_are_zero(request)) {
- if (lb_calld->last_client_load_report_counters_were_zero) {
- grpc_grpclb_request_destroy(request);
- schedule_next_client_load_report(lb_calld);
- return;
- }
- lb_calld->last_client_load_report_counters_were_zero = true;
- } else {
- lb_calld->last_client_load_report_counters_were_zero = false;
- }
- grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
- lb_calld->send_message_payload =
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
- grpc_slice_unref_internal(request_payload_slice);
- grpc_grpclb_request_destroy(request);
- // Send the report.
- grpc_op op;
- memset(&op, 0, sizeof(op));
- op.op = GRPC_OP_SEND_MESSAGE;
- op.data.send_message.send_message = lb_calld->send_message_payload;
- GRPC_CLOSURE_INIT(&lb_calld->client_load_report_closure,
- client_load_report_done_locked, lb_calld,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- grpc_call_error call_error = grpc_call_start_batch_and_execute(
- lb_calld->lb_call, &op, 1, &lb_calld->client_load_report_closure);
- if (call_error != GRPC_CALL_OK) {
- gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", glb_policy, call_error);
- GPR_ASSERT(GRPC_CALL_OK == call_error);
- }
-}
-
-static void maybe_send_client_load_report_locked(void* arg, grpc_error* error) {
- glb_lb_call_data* lb_calld = static_cast<glb_lb_call_data*>(arg);
- glb_lb_policy* glb_policy = lb_calld->glb_policy;
- lb_calld->client_load_report_timer_callback_pending = false;
- if (error != GRPC_ERROR_NONE || lb_calld != glb_policy->lb_calld) {
- glb_lb_call_data_unref(lb_calld, "client_load_report");
- return;
- }
- // If we've already sent the initial request, then we can go ahead and send
- // the load report. Otherwise, we need to wait until the initial request has
- // been sent to send this (see lb_on_sent_initial_request_locked()).
- if (lb_calld->send_message_payload == nullptr) {
- send_client_load_report_locked(lb_calld);
- } else {
- lb_calld->client_load_report_is_due = true;
- }
-}
-
-static void lb_on_sent_initial_request_locked(void* arg, grpc_error* error);
-static void lb_on_server_status_received_locked(void* arg, grpc_error* error);
-static void lb_on_response_received_locked(void* arg, grpc_error* error);
-static glb_lb_call_data* lb_call_data_create_locked(glb_lb_policy* glb_policy) {
- GPR_ASSERT(!glb_policy->shutting_down);
+GrpcLb::BalancerCallState::BalancerCallState(
+ RefCountedPtr<LoadBalancingPolicy> parent_grpclb_policy)
+ : InternallyRefCountedWithTracing<BalancerCallState>(&grpc_lb_glb_trace),
+ grpclb_policy_(std::move(parent_grpclb_policy)) {
+ GPR_ASSERT(grpclb_policy_ != nullptr);
+ GPR_ASSERT(!grpclb_policy()->shutting_down_);
// Init the LB call. Note that the LB call will progress every time there's
- // activity in glb_policy->base.interested_parties, which is comprised of the
- // polling entities from client_channel.
- GPR_ASSERT(glb_policy->server_name != nullptr);
- GPR_ASSERT(glb_policy->server_name[0] != '\0');
- grpc_slice host = grpc_slice_from_copied_string(glb_policy->server_name);
+ // activity in grpclb_policy_->interested_parties(), which is comprised of
+ // the polling entities from client_channel.
+ GPR_ASSERT(grpclb_policy()->server_name_ != nullptr);
+ GPR_ASSERT(grpclb_policy()->server_name_[0] != '\0');
+ grpc_slice host =
+ grpc_slice_from_copied_string(grpclb_policy()->server_name_);
grpc_millis deadline =
- glb_policy->lb_call_timeout_ms == 0
+ grpclb_policy()->lb_call_timeout_ms_ == 0
? GRPC_MILLIS_INF_FUTURE
- : grpc_core::ExecCtx::Get()->Now() + glb_policy->lb_call_timeout_ms;
- glb_lb_call_data* lb_calld =
- static_cast<glb_lb_call_data*>(gpr_zalloc(sizeof(*lb_calld)));
- lb_calld->lb_call = grpc_channel_create_pollset_set_call(
- glb_policy->lb_channel, nullptr, GRPC_PROPAGATE_DEFAULTS,
- glb_policy->base.interested_parties,
+ : ExecCtx::Get()->Now() + grpclb_policy()->lb_call_timeout_ms_;
+ lb_call_ = grpc_channel_create_pollset_set_call(
+ grpclb_policy()->lb_channel_, nullptr, GRPC_PROPAGATE_DEFAULTS,
+ grpclb_policy_->interested_parties(),
GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD,
&host, deadline, nullptr);
grpc_slice_unref_internal(host);
// Init the LB call request payload.
grpc_grpclb_request* request =
- grpc_grpclb_request_create(glb_policy->server_name);
+ grpc_grpclb_request_create(grpclb_policy()->server_name_);
grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
- lb_calld->send_message_payload =
+ send_message_payload_ =
grpc_raw_byte_buffer_create(&request_payload_slice, 1);
grpc_slice_unref_internal(request_payload_slice);
grpc_grpclb_request_destroy(request);
// Init other data associated with the LB call.
- lb_calld->glb_policy = glb_policy;
- gpr_ref_init(&lb_calld->refs, 1);
- grpc_metadata_array_init(&lb_calld->lb_initial_metadata_recv);
- grpc_metadata_array_init(&lb_calld->lb_trailing_metadata_recv);
- GRPC_CLOSURE_INIT(&lb_calld->lb_on_sent_initial_request,
- lb_on_sent_initial_request_locked, lb_calld,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- GRPC_CLOSURE_INIT(&lb_calld->lb_on_response_received,
- lb_on_response_received_locked, lb_calld,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- GRPC_CLOSURE_INIT(&lb_calld->lb_on_server_status_received,
- lb_on_server_status_received_locked, lb_calld,
- grpc_combiner_scheduler(glb_policy->base.combiner));
- // Hold a ref to the glb_policy.
- GRPC_LB_POLICY_REF(&glb_policy->base, "lb_calld");
- return lb_calld;
+ grpc_metadata_array_init(&lb_initial_metadata_recv_);
+ grpc_metadata_array_init(&lb_trailing_metadata_recv_);
+ GRPC_CLOSURE_INIT(&lb_on_initial_request_sent_, OnInitialRequestSentLocked,
+ this, grpc_combiner_scheduler(grpclb_policy()->combiner()));
+ GRPC_CLOSURE_INIT(&lb_on_balancer_message_received_,
+ OnBalancerMessageReceivedLocked, this,
+ grpc_combiner_scheduler(grpclb_policy()->combiner()));
+ GRPC_CLOSURE_INIT(&lb_on_balancer_status_received_,
+ OnBalancerStatusReceivedLocked, this,
+ grpc_combiner_scheduler(grpclb_policy()->combiner()));
}
-/*
- * Auxiliary functions and LB client callbacks.
- */
+GrpcLb::BalancerCallState::~BalancerCallState() {
+ GPR_ASSERT(lb_call_ != nullptr);
+ grpc_call_unref(lb_call_);
+ grpc_metadata_array_destroy(&lb_initial_metadata_recv_);
+ grpc_metadata_array_destroy(&lb_trailing_metadata_recv_);
+ grpc_byte_buffer_destroy(send_message_payload_);
+ grpc_byte_buffer_destroy(recv_message_payload_);
+ grpc_slice_unref_internal(lb_call_status_details_);
+ if (client_stats_ != nullptr) {
+ grpc_grpclb_client_stats_unref(client_stats_);
+ }
+}
-static void query_for_backends_locked(glb_lb_policy* glb_policy) {
- GPR_ASSERT(glb_policy->lb_channel != nullptr);
- if (glb_policy->shutting_down) return;
- // Init the LB call data.
- GPR_ASSERT(glb_policy->lb_calld == nullptr);
- glb_policy->lb_calld = lb_call_data_create_locked(glb_policy);
+void GrpcLb::BalancerCallState::Orphan() {
+ GPR_ASSERT(lb_call_ != nullptr);
+ // If we are here because grpclb_policy wants to cancel the call,
+ // lb_on_balancer_status_received_ will complete the cancellation and clean
+ // up. Otherwise, we are here because grpclb_policy has to orphan a failed
+ // call, then the following cancellation will be a no-op.
+ grpc_call_cancel(lb_call_, nullptr);
+ if (client_load_report_timer_callback_pending_) {
+ grpc_timer_cancel(&client_load_report_timer_);
+ }
+ // Note that the initial ref is hold by lb_on_balancer_status_received_
+ // instead of the caller of this function. So the corresponding unref happens
+ // in lb_on_balancer_status_received_ instead of here.
+}
+
+void GrpcLb::BalancerCallState::StartQuery() {
+ GPR_ASSERT(lb_call_ != nullptr);
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
- "[grpclb %p] Query for backends (lb_channel: %p, lb_calld: %p, "
- "lb_call: %p)",
- glb_policy, glb_policy->lb_channel, glb_policy->lb_calld,
- glb_policy->lb_calld->lb_call);
+ "[grpclb %p] Starting LB call (lb_calld: %p, lb_call: %p)",
+ grpclb_policy_.get(), this, lb_call_);
}
- GPR_ASSERT(glb_policy->lb_calld->lb_call != nullptr);
// Create the ops.
grpc_call_error call_error;
grpc_op ops[3];
@@ -1425,47 +584,49 @@ static void query_for_backends_locked(glb_lb_policy* glb_policy) {
op->reserved = nullptr;
op++;
// Op: send request message.
- GPR_ASSERT(glb_policy->lb_calld->send_message_payload != nullptr);
+ GPR_ASSERT(send_message_payload_ != nullptr);
op->op = GRPC_OP_SEND_MESSAGE;
- op->data.send_message.send_message =
- glb_policy->lb_calld->send_message_payload;
+ op->data.send_message.send_message = send_message_payload_;
op->flags = 0;
op->reserved = nullptr;
op++;
- glb_lb_call_data_ref(glb_policy->lb_calld,
- "lb_on_sent_initial_request_locked");
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = Ref(DEBUG_LOCATION, "on_initial_request_sent");
+ self.release();
call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_calld->lb_call, ops, static_cast<size_t>(op - ops),
- &glb_policy->lb_calld->lb_on_sent_initial_request);
+ lb_call_, ops, (size_t)(op - ops), &lb_on_initial_request_sent_);
GPR_ASSERT(GRPC_CALL_OK == call_error);
// Op: recv initial metadata.
op = ops;
op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata.recv_initial_metadata =
- &glb_policy->lb_calld->lb_initial_metadata_recv;
+ &lb_initial_metadata_recv_;
op->flags = 0;
op->reserved = nullptr;
op++;
// Op: recv response.
op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message =
- &glb_policy->lb_calld->recv_message_payload;
+ op->data.recv_message.recv_message = &recv_message_payload_;
op->flags = 0;
op->reserved = nullptr;
op++;
- glb_lb_call_data_ref(glb_policy->lb_calld, "lb_on_response_received_locked");
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ self = Ref(DEBUG_LOCATION, "on_message_received");
+ self.release();
call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_calld->lb_call, ops, static_cast<size_t>(op - ops),
- &glb_policy->lb_calld->lb_on_response_received);
+ lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_message_received_);
GPR_ASSERT(GRPC_CALL_OK == call_error);
// Op: recv server status.
op = ops;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata =
- &glb_policy->lb_calld->lb_trailing_metadata_recv;
- op->data.recv_status_on_client.status = &glb_policy->lb_calld->lb_call_status;
- op->data.recv_status_on_client.status_details =
- &glb_policy->lb_calld->lb_call_status_details;
+ &lb_trailing_metadata_recv_;
+ op->data.recv_status_on_client.status = &lb_call_status_;
+ op->data.recv_status_on_client.status_details = &lb_call_status_details_;
op->flags = 0;
op->reserved = nullptr;
op++;
@@ -1473,83 +634,174 @@ static void query_for_backends_locked(glb_lb_policy* glb_policy) {
// ref instead of a new ref. When it's invoked, it's the initial ref that is
// unreffed.
call_error = grpc_call_start_batch_and_execute(
- glb_policy->lb_calld->lb_call, ops, static_cast<size_t>(op - ops),
- &glb_policy->lb_calld->lb_on_server_status_received);
+ lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_status_received_);
GPR_ASSERT(GRPC_CALL_OK == call_error);
+};
+
+void GrpcLb::BalancerCallState::ScheduleNextClientLoadReportLocked() {
+ const grpc_millis next_client_load_report_time =
+ ExecCtx::Get()->Now() + client_stats_report_interval_;
+ GRPC_CLOSURE_INIT(&client_load_report_closure_,
+ MaybeSendClientLoadReportLocked, this,
+ grpc_combiner_scheduler(grpclb_policy()->combiner()));
+ grpc_timer_init(&client_load_report_timer_, next_client_load_report_time,
+ &client_load_report_closure_);
+ client_load_report_timer_callback_pending_ = true;
+}
+
+void GrpcLb::BalancerCallState::MaybeSendClientLoadReportLocked(
+ void* arg, grpc_error* error) {
+ BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
+ GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
+ lb_calld->client_load_report_timer_callback_pending_ = false;
+ if (error != GRPC_ERROR_NONE || lb_calld != grpclb_policy->lb_calld_.get()) {
+ lb_calld->Unref(DEBUG_LOCATION, "client_load_report");
+ return;
+ }
+ // If we've already sent the initial request, then we can go ahead and send
+ // the load report. Otherwise, we need to wait until the initial request has
+ // been sent to send this (see OnInitialRequestSentLocked()).
+ if (lb_calld->send_message_payload_ == nullptr) {
+ lb_calld->SendClientLoadReportLocked();
+ } else {
+ lb_calld->client_load_report_is_due_ = true;
+ }
+}
+
+bool GrpcLb::BalancerCallState::LoadReportCountersAreZero(
+ grpc_grpclb_request* request) {
+ grpc_grpclb_dropped_call_counts* drop_entries =
+ static_cast<grpc_grpclb_dropped_call_counts*>(
+ request->client_stats.calls_finished_with_drop.arg);
+ return request->client_stats.num_calls_started == 0 &&
+ request->client_stats.num_calls_finished == 0 &&
+ request->client_stats.num_calls_finished_with_client_failed_to_send ==
+ 0 &&
+ request->client_stats.num_calls_finished_known_received == 0 &&
+ (drop_entries == nullptr || drop_entries->num_entries == 0);
+}
+
+void GrpcLb::BalancerCallState::SendClientLoadReportLocked() {
+ // Construct message payload.
+ GPR_ASSERT(send_message_payload_ == nullptr);
+ grpc_grpclb_request* request =
+ grpc_grpclb_load_report_request_create_locked(client_stats_);
+ // Skip client load report if the counters were all zero in the last
+ // report and they are still zero in this one.
+ if (LoadReportCountersAreZero(request)) {
+ if (last_client_load_report_counters_were_zero_) {
+ grpc_grpclb_request_destroy(request);
+ ScheduleNextClientLoadReportLocked();
+ return;
+ }
+ last_client_load_report_counters_were_zero_ = true;
+ } else {
+ last_client_load_report_counters_were_zero_ = false;
+ }
+ grpc_slice request_payload_slice = grpc_grpclb_request_encode(request);
+ send_message_payload_ =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_slice_unref_internal(request_payload_slice);
+ grpc_grpclb_request_destroy(request);
+ // Send the report.
+ grpc_op op;
+ memset(&op, 0, sizeof(op));
+ op.op = GRPC_OP_SEND_MESSAGE;
+ op.data.send_message.send_message = send_message_payload_;
+ GRPC_CLOSURE_INIT(&client_load_report_closure_, ClientLoadReportDoneLocked,
+ this, grpc_combiner_scheduler(grpclb_policy()->combiner()));
+ grpc_call_error call_error = grpc_call_start_batch_and_execute(
+ lb_call_, &op, 1, &client_load_report_closure_);
+ if (call_error != GRPC_CALL_OK) {
+ gpr_log(GPR_ERROR, "[grpclb %p] call_error=%d", grpclb_policy_.get(),
+ call_error);
+ GPR_ASSERT(GRPC_CALL_OK == call_error);
+ }
}
-static void lb_on_sent_initial_request_locked(void* arg, grpc_error* error) {
- glb_lb_call_data* lb_calld = static_cast<glb_lb_call_data*>(arg);
- grpc_byte_buffer_destroy(lb_calld->send_message_payload);
- lb_calld->send_message_payload = nullptr;
+void GrpcLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg,
+ grpc_error* error) {
+ BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
+ GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
+ grpc_byte_buffer_destroy(lb_calld->send_message_payload_);
+ lb_calld->send_message_payload_ = nullptr;
+ if (error != GRPC_ERROR_NONE || lb_calld != grpclb_policy->lb_calld_.get()) {
+ lb_calld->Unref(DEBUG_LOCATION, "client_load_report");
+ return;
+ }
+ lb_calld->ScheduleNextClientLoadReportLocked();
+}
+
+void GrpcLb::BalancerCallState::OnInitialRequestSentLocked(void* arg,
+ grpc_error* error) {
+ BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
+ grpc_byte_buffer_destroy(lb_calld->send_message_payload_);
+ lb_calld->send_message_payload_ = nullptr;
// If we attempted to send a client load report before the initial request was
// sent (and this lb_calld is still in use), send the load report now.
- if (lb_calld->client_load_report_is_due &&
- lb_calld == lb_calld->glb_policy->lb_calld) {
- send_client_load_report_locked(lb_calld);
- lb_calld->client_load_report_is_due = false;
+ if (lb_calld->client_load_report_is_due_ &&
+ lb_calld == lb_calld->grpclb_policy()->lb_calld_.get()) {
+ lb_calld->SendClientLoadReportLocked();
+ lb_calld->client_load_report_is_due_ = false;
}
- glb_lb_call_data_unref(lb_calld, "lb_on_sent_initial_request_locked");
+ lb_calld->Unref(DEBUG_LOCATION, "on_initial_request_sent");
}
-static void lb_on_response_received_locked(void* arg, grpc_error* error) {
- glb_lb_call_data* lb_calld = static_cast<glb_lb_call_data*>(arg);
- glb_lb_policy* glb_policy = lb_calld->glb_policy;
+void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
+ void* arg, grpc_error* error) {
+ BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
+ GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
// Empty payload means the LB call was cancelled.
- if (lb_calld != glb_policy->lb_calld ||
- lb_calld->recv_message_payload == nullptr) {
- glb_lb_call_data_unref(lb_calld, "lb_on_response_received_locked");
+ if (lb_calld != grpclb_policy->lb_calld_.get() ||
+ lb_calld->recv_message_payload_ == nullptr) {
+ lb_calld->Unref(DEBUG_LOCATION, "on_message_received");
return;
}
- grpc_op ops[2];
- memset(ops, 0, sizeof(ops));
- grpc_op* op = ops;
- glb_policy->lb_call_backoff->Reset();
grpc_byte_buffer_reader bbr;
- grpc_byte_buffer_reader_init(&bbr, lb_calld->recv_message_payload);
+ grpc_byte_buffer_reader_init(&bbr, lb_calld->recv_message_payload_);
grpc_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
grpc_byte_buffer_reader_destroy(&bbr);
- grpc_byte_buffer_destroy(lb_calld->recv_message_payload);
- lb_calld->recv_message_payload = nullptr;
+ grpc_byte_buffer_destroy(lb_calld->recv_message_payload_);
+ lb_calld->recv_message_payload_ = nullptr;
grpc_grpclb_initial_response* initial_response;
grpc_grpclb_serverlist* serverlist;
- if (!lb_calld->seen_initial_response &&
+ if (!lb_calld->seen_initial_response_ &&
(initial_response = grpc_grpclb_initial_response_parse(response_slice)) !=
nullptr) {
// Have NOT seen initial response, look for initial response.
if (initial_response->has_client_stats_report_interval) {
- lb_calld->client_stats_report_interval = GPR_MAX(
+ lb_calld->client_stats_report_interval_ = GPR_MAX(
GPR_MS_PER_SEC, grpc_grpclb_duration_to_millis(
&initial_response->client_stats_report_interval));
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Received initial LB response message; "
"client load reporting interval = %" PRIdPTR " milliseconds",
- glb_policy, lb_calld->client_stats_report_interval);
+ grpclb_policy, lb_calld->client_stats_report_interval_);
}
} else if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Received initial LB response message; client load "
"reporting NOT enabled",
- glb_policy);
+ grpclb_policy);
}
grpc_grpclb_initial_response_destroy(initial_response);
- lb_calld->seen_initial_response = true;
+ lb_calld->seen_initial_response_ = true;
} else if ((serverlist = grpc_grpclb_response_parse_serverlist(
response_slice)) != nullptr) {
// Have seen initial response, look for serverlist.
- GPR_ASSERT(lb_calld->lb_call != nullptr);
+ GPR_ASSERT(lb_calld->lb_call_ != nullptr);
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Serverlist with %" PRIuPTR " servers received",
- glb_policy, serverlist->num_servers);
+ grpclb_policy, serverlist->num_servers);
for (size_t i = 0; i < serverlist->num_servers; ++i) {
grpc_resolved_address addr;
- parse_server(serverlist->servers[i], &addr);
+ ParseServer(serverlist->servers[i], &addr);
char* ipport;
grpc_sockaddr_to_string(&ipport, &addr, false);
gpr_log(GPR_INFO, "[grpclb %p] Serverlist[%" PRIuPTR "]: %s",
- glb_policy, i, ipport);
+ grpclb_policy, i, ipport);
gpr_free(ipport);
}
}
@@ -1557,44 +809,48 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
if (serverlist->num_servers > 0) {
// Start sending client load report only after we start using the
// serverlist returned from the current LB call.
- if (lb_calld->client_stats_report_interval > 0 &&
- lb_calld->client_stats == nullptr) {
- lb_calld->client_stats = grpc_grpclb_client_stats_create();
- glb_lb_call_data_ref(lb_calld, "client_load_report");
- schedule_next_client_load_report(lb_calld);
+ if (lb_calld->client_stats_report_interval_ > 0 &&
+ lb_calld->client_stats_ == nullptr) {
+ lb_calld->client_stats_ = grpc_grpclb_client_stats_create();
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
+ self.release();
+ lb_calld->ScheduleNextClientLoadReportLocked();
}
- if (grpc_grpclb_serverlist_equals(glb_policy->serverlist, serverlist)) {
+ if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_,
+ serverlist)) {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
"[grpclb %p] Incoming server list identical to current, "
"ignoring.",
- glb_policy);
+ grpclb_policy);
}
grpc_grpclb_destroy_serverlist(serverlist);
} else { /* new serverlist */
- if (glb_policy->serverlist != nullptr) {
+ if (grpclb_policy->serverlist_ != nullptr) {
/* dispose of the old serverlist */
- grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
+ grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
} else {
/* or dispose of the fallback */
- grpc_lb_addresses_destroy(glb_policy->fallback_backend_addresses);
- glb_policy->fallback_backend_addresses = nullptr;
- if (glb_policy->fallback_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_fallback_timer);
- glb_policy->fallback_timer_callback_pending = false;
+ grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
+ grpclb_policy->fallback_backend_addresses_ = nullptr;
+ if (grpclb_policy->fallback_timer_callback_pending_) {
+ grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
}
}
- /* and update the copy in the glb_lb_policy instance. This
- * serverlist instance will be destroyed either upon the next
- * update or in glb_destroy() */
- glb_policy->serverlist = serverlist;
- glb_policy->serverlist_index = 0;
- rr_handover_locked(glb_policy);
+ // and update the copy in the GrpcLb instance. This
+ // serverlist instance will be destroyed either upon the next
+ // update or when the GrpcLb instance is destroyed.
+ grpclb_policy->serverlist_ = serverlist;
+ grpclb_policy->serverlist_index_ = 0;
+ grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
}
} else {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.",
- glb_policy);
+ grpclb_policy);
}
grpc_grpclb_destroy_serverlist(serverlist);
}
@@ -1602,335 +858,1021 @@ static void lb_on_response_received_locked(void* arg, grpc_error* error) {
// No valid initial response or serverlist found.
gpr_log(GPR_ERROR,
"[grpclb %p] Invalid LB response received: '%s'. Ignoring.",
- glb_policy,
+ grpclb_policy,
grpc_dump_slice(response_slice, GPR_DUMP_ASCII | GPR_DUMP_HEX));
}
grpc_slice_unref_internal(response_slice);
- if (!glb_policy->shutting_down) {
+ if (!grpclb_policy->shutting_down_) {
// Keep listening for serverlist updates.
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &lb_calld->recv_message_payload;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- // Reuse the "lb_on_response_received_locked" ref taken in
- // query_for_backends_locked().
+ grpc_op op;
+ memset(&op, 0, sizeof(op));
+ op.op = GRPC_OP_RECV_MESSAGE;
+ op.data.recv_message.recv_message = &lb_calld->recv_message_payload_;
+ op.flags = 0;
+ op.reserved = nullptr;
+ // Reuse the "OnBalancerMessageReceivedLocked" ref taken in StartQuery().
const grpc_call_error call_error = grpc_call_start_batch_and_execute(
- lb_calld->lb_call, ops, static_cast<size_t>(op - ops),
- &lb_calld->lb_on_response_received);
+ lb_calld->lb_call_, &op, 1,
+ &lb_calld->lb_on_balancer_message_received_);
GPR_ASSERT(GRPC_CALL_OK == call_error);
} else {
- glb_lb_call_data_unref(lb_calld,
- "lb_on_response_received_locked+glb_shutdown");
+ lb_calld->Unref(DEBUG_LOCATION, "on_message_received+grpclb_shutdown");
}
}
-static void lb_on_server_status_received_locked(void* arg, grpc_error* error) {
- glb_lb_call_data* lb_calld = static_cast<glb_lb_call_data*>(arg);
- glb_lb_policy* glb_policy = lb_calld->glb_policy;
- GPR_ASSERT(lb_calld->lb_call != nullptr);
+void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
+ void* arg, grpc_error* error) {
+ BalancerCallState* lb_calld = reinterpret_cast<BalancerCallState*>(arg);
+ GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
+ GPR_ASSERT(lb_calld->lb_call_ != nullptr);
if (grpc_lb_glb_trace.enabled()) {
char* status_details =
- grpc_slice_to_c_string(lb_calld->lb_call_status_details);
+ grpc_slice_to_c_string(lb_calld->lb_call_status_details_);
gpr_log(GPR_INFO,
"[grpclb %p] Status from LB server received. Status = %d, details "
"= '%s', (lb_calld: %p, lb_call: %p), error '%s'",
- lb_calld->glb_policy, lb_calld->lb_call_status, status_details,
- lb_calld, lb_calld->lb_call, grpc_error_string(error));
+ grpclb_policy, lb_calld->lb_call_status_, status_details, lb_calld,
+ lb_calld->lb_call_, grpc_error_string(error));
gpr_free(status_details);
}
- grpc_lb_policy_try_reresolve(&glb_policy->base, &grpc_lb_glb_trace,
- GRPC_ERROR_NONE);
+ grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE);
// If this lb_calld is still in use, this call ended because of a failure so
// we want to retry connecting. Otherwise, we have deliberately ended this
// call and no further action is required.
- if (lb_calld == glb_policy->lb_calld) {
- glb_policy->lb_calld = nullptr;
- if (lb_calld->client_load_report_timer_callback_pending) {
- grpc_timer_cancel(&lb_calld->client_load_report_timer);
- }
- GPR_ASSERT(!glb_policy->shutting_down);
- if (lb_calld->seen_initial_response) {
+ if (lb_calld == grpclb_policy->lb_calld_.get()) {
+ grpclb_policy->lb_calld_.reset();
+ GPR_ASSERT(!grpclb_policy->shutting_down_);
+ if (lb_calld->seen_initial_response_) {
// If we lose connection to the LB server, reset the backoff and restart
// the LB call immediately.
- glb_policy->lb_call_backoff->Reset();
- query_for_backends_locked(glb_policy);
+ grpclb_policy->lb_call_backoff_.Reset();
+ grpclb_policy->StartBalancerCallLocked();
} else {
// If this LB call fails establishing any connection to the LB server,
// retry later.
- start_lb_call_retry_timer_locked(glb_policy);
+ grpclb_policy->StartBalancerCallRetryTimerLocked();
}
}
- glb_lb_call_data_unref(lb_calld, "lb_call_ended");
+ lb_calld->Unref(DEBUG_LOCATION, "lb_call_ended");
}
-static void lb_on_fallback_timer_locked(void* arg, grpc_error* error) {
- glb_lb_policy* glb_policy = static_cast<glb_lb_policy*>(arg);
- glb_policy->fallback_timer_callback_pending = false;
- /* If we receive a serverlist after the timer fires but before this callback
- * actually runs, don't fall back. */
- if (glb_policy->serverlist == nullptr && !glb_policy->shutting_down &&
- error == GRPC_ERROR_NONE) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Falling back to use backends from resolver",
- glb_policy);
+//
+// helper code for creating balancer channel
+//
+
+grpc_lb_addresses* ExtractBalancerAddresses(
+ const grpc_lb_addresses* addresses) {
+ size_t num_grpclb_addrs = 0;
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+ }
+ // There must be at least one balancer address, or else the
+ // client_channel would not have chosen this LB policy.
+ GPR_ASSERT(num_grpclb_addrs > 0);
+ grpc_lb_addresses* lb_addresses =
+ grpc_lb_addresses_create(num_grpclb_addrs, nullptr);
+ size_t lb_addresses_idx = 0;
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ if (!addresses->addresses[i].is_balancer) continue;
+ if (addresses->addresses[i].user_data != nullptr) {
+ gpr_log(GPR_ERROR,
+ "This LB policy doesn't support user data. It will be ignored");
+ }
+ grpc_lb_addresses_set_address(
+ lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr,
+ addresses->addresses[i].address.len, false /* is balancer */,
+ addresses->addresses[i].balancer_name, nullptr /* user data */);
+ }
+ GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx);
+ return lb_addresses;
+}
+
+/* Returns the channel args for the LB channel, used to create a bidirectional
+ * stream for the reception of load balancing updates.
+ *
+ * Inputs:
+ * - \a addresses: corresponding to the balancers.
+ * - \a response_generator: in order to propagate updates from the resolver
+ * above the grpclb policy.
+ * - \a args: other args inherited from the grpclb policy. */
+grpc_channel_args* BuildBalancerChannelArgs(
+ const grpc_lb_addresses* addresses,
+ FakeResolverResponseGenerator* response_generator,
+ const grpc_channel_args* args) {
+ grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses);
+ // Channel args to remove.
+ static const char* args_to_remove[] = {
+ // LB policy name, since we want to use the default (pick_first) in
+ // the LB channel.
+ GRPC_ARG_LB_POLICY_NAME,
+ // The channel arg for the server URI, since that will be different for
+ // the LB channel than for the parent channel. The client channel
+ // factory will re-add this arg with the right value.
+ GRPC_ARG_SERVER_URI,
+ // The resolved addresses, which will be generated by the name resolver
+ // used in the LB channel. Note that the LB channel will use the fake
+ // resolver, so this won't actually generate a query to DNS (or some
+ // other name service). However, the addresses returned by the fake
+ // resolver will have is_balancer=false, whereas our own addresses have
+ // is_balancer=true. We need the LB channel to return addresses with
+ // is_balancer=false so that it does not wind up recursively using the
+ // grpclb LB policy, as per the special case logic in client_channel.c.
+ GRPC_ARG_LB_ADDRESSES,
+ // The fake resolver response generator, because we are replacing it
+ // with the one from the grpclb policy, used to propagate updates to
+ // the LB channel.
+ GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
+ };
+ // Channel args to add.
+ const grpc_arg args_to_add[] = {
+ // New LB addresses.
+ // Note that we pass these in both when creating the LB channel
+ // and via the fake resolver. The latter is what actually gets used.
+ grpc_lb_addresses_create_channel_arg(lb_addresses),
+ // The fake resolver response generator, which we use to inject
+ // address updates into the LB channel.
+ grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
+ response_generator),
+ };
+ // Construct channel args.
+ grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
+ args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
+ GPR_ARRAY_SIZE(args_to_add));
+ // Make any necessary modifications for security.
+ new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
+ // Clean up.
+ grpc_lb_addresses_destroy(lb_addresses);
+ return new_args;
+}
+
+//
+// ctor and dtor
+//
+
+GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
+ const LoadBalancingPolicy::Args& args)
+ : LoadBalancingPolicy(args),
+ response_generator_(MakeRefCounted<FakeResolverResponseGenerator>()),
+ lb_call_backoff_(
+ BackOff::Options()
+ .set_initial_backoff(GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS *
+ 1000)
+ .set_multiplier(GRPC_GRPCLB_RECONNECT_BACKOFF_MULTIPLIER)
+ .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER)
+ .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS *
+ 1000)) {
+ // Initialization.
+ grpc_subchannel_index_ref();
+ GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_,
+ &GrpcLb::OnBalancerChannelConnectivityChangedLocked, this,
+ grpc_combiner_scheduler(args.combiner));
+ GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_,
+ &GrpcLb::OnRoundRobinConnectivityChangedLocked, this,
+ grpc_combiner_scheduler(args.combiner));
+ GRPC_CLOSURE_INIT(&on_rr_request_reresolution_,
+ &GrpcLb::OnRoundRobinRequestReresolutionLocked, this,
+ grpc_combiner_scheduler(args.combiner));
+ grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb");
+ // Record server name.
+ const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI);
+ const char* server_uri = grpc_channel_arg_get_string(arg);
+ GPR_ASSERT(server_uri != nullptr);
+ grpc_uri* uri = grpc_uri_parse(server_uri, true);
+ GPR_ASSERT(uri->path[0] != '\0');
+ server_name_ = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Will use '%s' as the server name for LB request.",
+ this, server_name_);
+ }
+ grpc_uri_destroy(uri);
+ // Record LB call timeout.
+ arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
+ lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX});
+ // Record fallback timeout.
+ arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS);
+ lb_fallback_timeout_ms_ = grpc_channel_arg_get_integer(
+ arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX});
+ // Process channel args.
+ ProcessChannelArgsLocked(*args.args);
+}
+
+GrpcLb::~GrpcLb() {
+ GPR_ASSERT(pending_picks_ == nullptr);
+ GPR_ASSERT(pending_pings_ == nullptr);
+ gpr_free((void*)server_name_);
+ grpc_channel_args_destroy(args_);
+ grpc_connectivity_state_destroy(&state_tracker_);
+ if (serverlist_ != nullptr) {
+ grpc_grpclb_destroy_serverlist(serverlist_);
+ }
+ if (fallback_backend_addresses_ != nullptr) {
+ grpc_lb_addresses_destroy(fallback_backend_addresses_);
+ }
+ grpc_subchannel_index_unref();
+}
+
+void GrpcLb::ShutdownLocked() {
+ grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
+ shutting_down_ = true;
+ lb_calld_.reset();
+ if (retry_timer_callback_pending_) {
+ grpc_timer_cancel(&lb_call_retry_timer_);
+ }
+ if (fallback_timer_callback_pending_) {
+ grpc_timer_cancel(&lb_fallback_timer_);
+ }
+ rr_policy_.reset();
+ TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_CANCELLED);
+ // We destroy the LB channel here instead of in our destructor because
+ // destroying the channel triggers a last callback to
+ // OnBalancerChannelConnectivityChangedLocked(), and we need to be
+ // alive when that callback is invoked.
+ if (lb_channel_ != nullptr) {
+ grpc_channel_destroy(lb_channel_);
+ lb_channel_ = nullptr;
+ }
+ grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
+ GRPC_ERROR_REF(error), "grpclb_shutdown");
+ // Clear pending picks.
+ PendingPick* pp;
+ while ((pp = pending_picks_) != nullptr) {
+ pending_picks_ = pp->next;
+ pp->pick->connected_subchannel.reset();
+ // Note: pp is deleted in this callback.
+ GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error));
+ }
+ // Clear pending pings.
+ PendingPing* pping;
+ while ((pping = pending_pings_) != nullptr) {
+ pending_pings_ = pping->next;
+ GRPC_CLOSURE_SCHED(pping->on_initiate, GRPC_ERROR_REF(error));
+ GRPC_CLOSURE_SCHED(pping->on_ack, GRPC_ERROR_REF(error));
+ Delete(pping);
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+//
+// public methods
+//
+
+void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
+ PendingPick* pp;
+ while ((pp = pending_picks_) != nullptr) {
+ pending_picks_ = pp->next;
+ pp->pick->on_complete = pp->original_on_complete;
+ pp->pick->user_data = nullptr;
+ if (new_policy->PickLocked(pp->pick)) {
+ // Synchronous return; schedule closure.
+ GRPC_CLOSURE_SCHED(pp->pick->on_complete, GRPC_ERROR_NONE);
}
- GPR_ASSERT(glb_policy->fallback_backend_addresses != nullptr);
- rr_handover_locked(glb_policy);
+ Delete(pp);
}
- GRPC_LB_POLICY_UNREF(&glb_policy->base, "grpclb_fallback_timer");
}
-static void fallback_update_locked(glb_lb_policy* glb_policy,
- const grpc_lb_addresses* addresses) {
- GPR_ASSERT(glb_policy->fallback_backend_addresses != nullptr);
- grpc_lb_addresses_destroy(glb_policy->fallback_backend_addresses);
- glb_policy->fallback_backend_addresses =
- extract_backend_addresses_locked(addresses);
- if (glb_policy->lb_fallback_timeout_ms > 0 &&
- glb_policy->rr_policy != nullptr) {
- rr_handover_locked(glb_policy);
+// Cancel a specific pending pick.
+//
+// A grpclb pick progresses as follows:
+// - If there's a Round Robin policy (rr_policy_) available, it'll be
+// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From
+// that point onwards, it'll be RR's responsibility. For cancellations, that
+// implies the pick needs also be cancelled by the RR instance.
+// - Otherwise, without an RR instance, picks stay pending at this policy's
+// level (grpclb), inside the pending_picks_ list. To cancel these,
+// we invoke the completion closure and set the pick's connected
+// subchannel to nullptr right here.
+void GrpcLb::CancelPickLocked(PickState* pick, grpc_error* error) {
+ PendingPick* pp = pending_picks_;
+ pending_picks_ = nullptr;
+ while (pp != nullptr) {
+ PendingPick* next = pp->next;
+ if (pp->pick == pick) {
+ pick->connected_subchannel.reset();
+ // Note: pp is deleted in this callback.
+ GRPC_CLOSURE_SCHED(&pp->on_complete,
+ GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+ "Pick Cancelled", &error, 1));
+ } else {
+ pp->next = pending_picks_;
+ pending_picks_ = pp;
+ }
+ pp = next;
+ }
+ if (rr_policy_ != nullptr) {
+ rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error));
}
+ GRPC_ERROR_UNREF(error);
}
-static void glb_update_locked(grpc_lb_policy* policy,
- const grpc_lb_policy_args* args) {
- glb_lb_policy* glb_policy = reinterpret_cast<glb_lb_policy*>(policy);
- const grpc_arg* arg =
- grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- if (glb_policy->lb_channel == nullptr) {
- // If we don't have a current channel to the LB, go into TRANSIENT
- // FAILURE.
- grpc_connectivity_state_set(
- &glb_policy->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
- "glb_update_missing");
+// Cancel all pending picks.
+//
+// A grpclb pick progresses as follows:
+// - If there's a Round Robin policy (rr_policy_) available, it'll be
+// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From
+// that point onwards, it'll be RR's responsibility. For cancellations, that
+// implies the pick needs also be cancelled by the RR instance.
+// - Otherwise, without an RR instance, picks stay pending at this policy's
+// level (grpclb), inside the pending_picks_ list. To cancel these,
+// we invoke the completion closure and set the pick's connected
+// subchannel to nullptr right here.
+void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) {
+ PendingPick* pp = pending_picks_;
+ pending_picks_ = nullptr;
+ while (pp != nullptr) {
+ PendingPick* next = pp->next;
+ if ((pp->pick->initial_metadata_flags & initial_metadata_flags_mask) ==
+ initial_metadata_flags_eq) {
+ // Note: pp is deleted in this callback.
+ GRPC_CLOSURE_SCHED(&pp->on_complete,
+ GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
+ "Pick Cancelled", &error, 1));
} else {
- // otherwise, keep using the current LB channel (ignore this update).
- gpr_log(
- GPR_ERROR,
- "[grpclb %p] No valid LB addresses channel arg in update, ignoring.",
- glb_policy);
+ pp->next = pending_picks_;
+ pending_picks_ = pp;
+ }
+ pp = next;
+ }
+ if (rr_policy_ != nullptr) {
+ rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask,
+ initial_metadata_flags_eq,
+ GRPC_ERROR_REF(error));
+ }
+ GRPC_ERROR_UNREF(error);
+}
+
+void GrpcLb::ExitIdleLocked() {
+ if (!started_picking_) {
+ StartPickingLocked();
+ }
+}
+
+bool GrpcLb::PickLocked(PickState* pick) {
+ PendingPick* pp = PendingPickCreate(pick);
+ bool pick_done = false;
+ if (rr_policy_ != nullptr) {
+ const grpc_connectivity_state rr_connectivity_state =
+ rr_policy_->CheckConnectivityLocked(nullptr);
+ // The RR policy may have transitioned to SHUTDOWN but the callback
+ // registered to capture this event (on_rr_connectivity_changed_) may not
+ // have been invoked yet. We need to make sure we aren't trying to pick
+ // from an RR policy instance that's in shutdown.
+ if (rr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] NOT picking from from RR %p: RR conn state=%s",
+ this, rr_policy_.get(),
+ grpc_connectivity_state_name(rr_connectivity_state));
+ }
+ AddPendingPick(pp);
+ pick_done = false;
+ } else { // RR not in shutdown
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this,
+ rr_policy_.get());
+ }
+ pick_done = PickFromRoundRobinPolicyLocked(false /* force_async */, pp);
+ }
+ } else { // rr_policy_ == NULL
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_DEBUG,
+ "[grpclb %p] No RR policy. Adding to grpclb's pending picks",
+ this);
}
+ AddPendingPick(pp);
+ if (!started_picking_) {
+ StartPickingLocked();
+ }
+ pick_done = false;
+ }
+ return pick_done;
+}
+
+void GrpcLb::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
+ if (rr_policy_ != nullptr) {
+ rr_policy_->PingOneLocked(on_initiate, on_ack);
+ } else {
+ AddPendingPing(on_initiate, on_ack);
+ if (!started_picking_) {
+ StartPickingLocked();
+ }
+ }
+}
+
+grpc_connectivity_state GrpcLb::CheckConnectivityLocked(
+ grpc_error** connectivity_error) {
+ return grpc_connectivity_state_get(&state_tracker_, connectivity_error);
+}
+
+void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
+ grpc_closure* notify) {
+ grpc_connectivity_state_notify_on_state_change(&state_tracker_, current,
+ notify);
+}
+
+void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
+ const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
+ if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
+ // Ignore this update.
+ gpr_log(
+ GPR_ERROR,
+ "[grpclb %p] No valid LB addresses channel arg in update, ignoring.",
+ this);
return;
}
const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
- // If a non-empty serverlist hasn't been received from the balancer,
- // propagate the update to fallback_backend_addresses.
- if (glb_policy->serverlist == nullptr) {
- fallback_update_locked(glb_policy, addresses);
+ reinterpret_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
+ // Update fallback address list.
+ if (fallback_backend_addresses_ != nullptr) {
+ grpc_lb_addresses_destroy(fallback_backend_addresses_);
+ }
+ fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
+ // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
+ // since we use this to trigger the client_load_reporting filter.
+ static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
+ grpc_arg new_arg = grpc_channel_arg_string_create(
+ (char*)GRPC_ARG_LB_POLICY_NAME, (char*)"grpclb");
+ grpc_channel_args_destroy(args_);
+ args_ = grpc_channel_args_copy_and_add_and_remove(
+ &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
+ // Construct args for balancer channel.
+ grpc_channel_args* lb_channel_args =
+ BuildBalancerChannelArgs(addresses, response_generator_.get(), &args);
+ // Create balancer channel if needed.
+ if (lb_channel_ == nullptr) {
+ char* uri_str;
+ gpr_asprintf(&uri_str, "fake:///%s", server_name_);
+ lb_channel_ = grpc_client_channel_factory_create_channel(
+ client_channel_factory(), uri_str,
+ GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args);
+ GPR_ASSERT(lb_channel_ != nullptr);
+ gpr_free(uri_str);
}
- GPR_ASSERT(glb_policy->lb_channel != nullptr);
// Propagate updates to the LB channel (pick_first) through the fake
// resolver.
- grpc_channel_args* lb_channel_args = build_lb_channel_args(
- addresses, glb_policy->response_generator.get(), args->args);
- glb_policy->response_generator->SetResponse(lb_channel_args);
+ response_generator_->SetResponse(lb_channel_args);
grpc_channel_args_destroy(lb_channel_args);
+}
+
+void GrpcLb::UpdateLocked(const grpc_channel_args& args) {
+ ProcessChannelArgsLocked(args);
+ // If fallback is configured and the RR policy already exists, update
+ // it with the new fallback addresses.
+ if (lb_fallback_timeout_ms_ > 0 && rr_policy_ != nullptr) {
+ CreateOrUpdateRoundRobinPolicyLocked();
+ }
// Start watching the LB channel connectivity for connection, if not
// already doing so.
- if (!glb_policy->watching_lb_channel) {
- glb_policy->lb_channel_connectivity = grpc_channel_check_connectivity_state(
- glb_policy->lb_channel, true /* try to connect */);
+ if (!watching_lb_channel_) {
+ lb_channel_connectivity_ = grpc_channel_check_connectivity_state(
+ lb_channel_, true /* try to connect */);
grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(
- grpc_channel_get_channel_stack(glb_policy->lb_channel));
+ grpc_channel_get_channel_stack(lb_channel_));
GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
- glb_policy->watching_lb_channel = true;
- GRPC_LB_POLICY_REF(&glb_policy->base, "watch_lb_channel_connectivity");
+ watching_lb_channel_ = true;
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity");
+ self.release();
grpc_client_channel_watch_connectivity_state(
client_channel_elem,
- grpc_polling_entity_create_from_pollset_set(
- glb_policy->base.interested_parties),
- &glb_policy->lb_channel_connectivity,
- &glb_policy->lb_channel_on_connectivity_changed, nullptr);
+ grpc_polling_entity_create_from_pollset_set(interested_parties()),
+ &lb_channel_connectivity_, &lb_channel_on_connectivity_changed_,
+ nullptr);
}
}
+//
+// code for balancer channel and call
+//
+
+void GrpcLb::StartPickingLocked() {
+ // Start a timer to fall back.
+ if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr &&
+ !fallback_timer_callback_pending_) {
+ grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_;
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = Ref(DEBUG_LOCATION, "on_fallback_timer");
+ self.release();
+ GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this,
+ grpc_combiner_scheduler(combiner()));
+ fallback_timer_callback_pending_ = true;
+ grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_);
+ }
+ started_picking_ = true;
+ StartBalancerCallLocked();
+}
+
+void GrpcLb::StartBalancerCallLocked() {
+ GPR_ASSERT(lb_channel_ != nullptr);
+ if (shutting_down_) return;
+ // Init the LB call data.
+ GPR_ASSERT(lb_calld_ == nullptr);
+ lb_calld_ = MakeOrphanable<BalancerCallState>(Ref());
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Query for backends (lb_channel: %p, lb_calld: %p)",
+ this, lb_channel_, lb_calld_.get());
+ }
+ lb_calld_->StartQuery();
+}
+
+void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
+ GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
+ grpclb_policy->fallback_timer_callback_pending_ = false;
+ // If we receive a serverlist after the timer fires but before this callback
+ // actually runs, don't fall back.
+ if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ &&
+ error == GRPC_ERROR_NONE) {
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Falling back to use backends from resolver",
+ grpclb_policy);
+ }
+ GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr);
+ grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
+ }
+ grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer");
+}
+
+void GrpcLb::StartBalancerCallRetryTimerLocked() {
+ grpc_millis next_try = lb_call_backoff_.NextAttemptTime();
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "[grpclb %p] Connection to LB server lost...", this);
+ grpc_millis timeout = next_try - ExecCtx::Get()->Now();
+ if (timeout > 0) {
+ gpr_log(GPR_DEBUG,
+ "[grpclb %p] ... retry_timer_active in %" PRIuPTR "ms.", this,
+ timeout);
+ } else {
+ gpr_log(GPR_DEBUG, "[grpclb %p] ... retry_timer_active immediately.",
+ this);
+ }
+ }
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = Ref(DEBUG_LOCATION, "on_balancer_call_retry_timer");
+ self.release();
+ GRPC_CLOSURE_INIT(&lb_on_call_retry_, &GrpcLb::OnBalancerCallRetryTimerLocked,
+ this, grpc_combiner_scheduler(combiner()));
+ retry_timer_callback_pending_ = true;
+ grpc_timer_init(&lb_call_retry_timer_, next_try, &lb_on_call_retry_);
+}
+
+void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) {
+ GrpcLb* grpclb_policy = reinterpret_cast<GrpcLb*>(arg);
+ grpclb_policy->retry_timer_callback_pending_ = false;
+ if (!grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE &&
+ grpclb_policy->lb_calld_ == nullptr) {
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO, "[grpclb %p] Restarting call to LB server",
+ grpclb_policy);
+ }
+ grpclb_policy->StartBalancerCallLocked();
+ }
+ grpclb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer");
+}
+
// Invoked as part of the update process. It continues watching the LB channel
// until it shuts down or becomes READY. It's invoked even if the LB channel
// stayed READY throughout the update (for example if the update is identical).
-static void glb_lb_channel_on_connectivity_changed_cb(void* arg,
- grpc_error* error) {
- glb_lb_policy* glb_policy = static_cast<glb_lb_policy*>(arg);
- if (glb_policy->shutting_down) goto done;
+void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
+ grpc_error* error) {
+ GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
+ if (grpclb_policy->shutting_down_) goto done;
// Re-initialize the lb_call. This should also take care of updating the
// embedded RR policy. Note that the current RR policy, if any, will stay in
// effect until an update from the new lb_call is received.
- switch (glb_policy->lb_channel_connectivity) {
+ switch (grpclb_policy->lb_channel_connectivity_) {
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
// Keep watching the LB channel.
grpc_channel_element* client_channel_elem =
grpc_channel_stack_last_element(
- grpc_channel_get_channel_stack(glb_policy->lb_channel));
+ grpc_channel_get_channel_stack(grpclb_policy->lb_channel_));
GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
grpc_client_channel_watch_connectivity_state(
client_channel_elem,
grpc_polling_entity_create_from_pollset_set(
- glb_policy->base.interested_parties),
- &glb_policy->lb_channel_connectivity,
- &glb_policy->lb_channel_on_connectivity_changed, nullptr);
+ grpclb_policy->interested_parties()),
+ &grpclb_policy->lb_channel_connectivity_,
+ &grpclb_policy->lb_channel_on_connectivity_changed_, nullptr);
break;
}
// The LB channel may be IDLE because it's shut down before the update.
// Restart the LB call to kick the LB channel into gear.
case GRPC_CHANNEL_IDLE:
case GRPC_CHANNEL_READY:
- if (glb_policy->lb_calld != nullptr) {
- lb_call_data_shutdown(glb_policy);
- }
- if (glb_policy->started_picking) {
- if (glb_policy->retry_timer_callback_pending) {
- grpc_timer_cancel(&glb_policy->lb_call_retry_timer);
+ grpclb_policy->lb_calld_.reset();
+ if (grpclb_policy->started_picking_) {
+ if (grpclb_policy->retry_timer_callback_pending_) {
+ grpc_timer_cancel(&grpclb_policy->lb_call_retry_timer_);
}
- glb_policy->lb_call_backoff->Reset();
- query_for_backends_locked(glb_policy);
+ grpclb_policy->lb_call_backoff_.Reset();
+ grpclb_policy->StartBalancerCallLocked();
}
// Fall through.
case GRPC_CHANNEL_SHUTDOWN:
done:
- glb_policy->watching_lb_channel = false;
- GRPC_LB_POLICY_UNREF(&glb_policy->base,
+ grpclb_policy->watching_lb_channel_ = false;
+ grpclb_policy->Unref(DEBUG_LOCATION,
"watch_lb_channel_connectivity_cb_shutdown");
}
}
-/* Code wiring the policy with the rest of the core */
-static const grpc_lb_policy_vtable glb_lb_policy_vtable = {
- glb_destroy,
- glb_shutdown_locked,
- glb_pick_locked,
- glb_cancel_pick_locked,
- glb_cancel_picks_locked,
- glb_ping_one_locked,
- glb_exit_idle_locked,
- glb_check_connectivity_locked,
- glb_notify_on_state_change_locked,
- glb_update_locked};
-
-static grpc_lb_policy* glb_create(grpc_lb_policy_factory* factory,
- grpc_lb_policy_args* args) {
- /* Count the number of gRPC-LB addresses. There must be at least one. */
- const grpc_arg* arg =
- grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- return nullptr;
+//
+// PendingPick
+//
+
+// Adds lb_token of selected subchannel (address) to the call's initial
+// metadata.
+grpc_error* AddLbTokenToInitialMetadata(
+ grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage,
+ grpc_metadata_batch* initial_metadata) {
+ GPR_ASSERT(lb_token_mdelem_storage != nullptr);
+ GPR_ASSERT(!GRPC_MDISNULL(lb_token));
+ return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
+ lb_token);
+}
+
+// Destroy function used when embedding client stats in call context.
+void DestroyClientStats(void* arg) {
+ grpc_grpclb_client_stats_unref(
+ reinterpret_cast<grpc_grpclb_client_stats*>(arg));
+}
+
+void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
+ /* if connected_subchannel is nullptr, no pick has been made by the RR
+ * policy (e.g., all addresses failed to connect). There won't be any
+ * user_data/token available */
+ if (pp->pick->connected_subchannel != nullptr) {
+ if (!GRPC_MDISNULL(pp->lb_token)) {
+ AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token),
+ &pp->pick->lb_token_mdelem_storage,
+ pp->pick->initial_metadata);
+ } else {
+ gpr_log(GPR_ERROR,
+ "[grpclb %p] No LB token for connected subchannel pick %p",
+ pp->grpclb_policy, pp->pick);
+ abort();
+ }
+ // Pass on client stats via context. Passes ownership of the reference.
+ if (pp->client_stats != nullptr) {
+ pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
+ pp->client_stats;
+ pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy =
+ DestroyClientStats;
+ }
+ } else {
+ if (pp->client_stats != nullptr) {
+ grpc_grpclb_client_stats_unref(pp->client_stats);
+ }
}
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+}
+
+/* The \a on_complete closure passed as part of the pick requires keeping a
+ * reference to its associated round robin instance. We wrap this closure in
+ * order to unref the round robin instance upon its invocation */
+void GrpcLb::OnPendingPickComplete(void* arg, grpc_error* error) {
+ PendingPick* pp = reinterpret_cast<PendingPick*>(arg);
+ PendingPickSetMetadataAndContext(pp);
+ GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error));
+ Delete(pp);
+}
+
+GrpcLb::PendingPick* GrpcLb::PendingPickCreate(PickState* pick) {
+ PendingPick* pp = New<PendingPick>();
+ pp->grpclb_policy = this;
+ pp->pick = pick;
+ GRPC_CLOSURE_INIT(&pp->on_complete, &GrpcLb::OnPendingPickComplete, pp,
+ grpc_schedule_on_exec_ctx);
+ pp->original_on_complete = pick->on_complete;
+ pick->on_complete = &pp->on_complete;
+ return pp;
+}
+
+void GrpcLb::AddPendingPick(PendingPick* pp) {
+ pp->next = pending_picks_;
+ pending_picks_ = pp;
+}
+
+//
+// PendingPing
+//
+
+void GrpcLb::AddPendingPing(grpc_closure* on_initiate, grpc_closure* on_ack) {
+ PendingPing* pping = New<PendingPing>();
+ pping->on_initiate = on_initiate;
+ pping->on_ack = on_ack;
+ pping->next = pending_pings_;
+ pending_pings_ = pping;
+}
+
+//
+// code for interacting with the RR policy
+//
+
+// Performs a pick over \a rr_policy_. Given that a pick can return
+// immediately (ignoring its completion callback), we need to perform the
+// cleanups this callback would otherwise be responsible for.
+// If \a force_async is true, then we will manually schedule the
+// completion callback even if the pick is available immediately.
+bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp) {
+ // Check for drops if we are not using fallback backend addresses.
+ if (serverlist_ != nullptr) {
+ // Look at the index into the serverlist to see if we should drop this call.
+ grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++];
+ if (serverlist_index_ == serverlist_->num_servers) {
+ serverlist_index_ = 0; // Wrap-around.
+ }
+ if (server->drop) {
+ // Update client load reporting stats to indicate the number of
+ // dropped calls. Note that we have to do this here instead of in
+ // the client_load_reporting filter, because we do not create a
+ // subchannel call (and therefore no client_load_reporting filter)
+ // for dropped calls.
+ if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
+ grpc_grpclb_client_stats_add_call_dropped_locked(
+ server->load_balance_token, lb_calld_->client_stats());
+ }
+ if (force_async) {
+ GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
+ Delete(pp);
+ return false;
+ }
+ Delete(pp);
+ return true;
+ }
}
- if (num_grpclb_addrs == 0) return nullptr;
+ // Set client_stats and user_data.
+ if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
+ pp->client_stats = grpc_grpclb_client_stats_ref(lb_calld_->client_stats());
+ }
+ GPR_ASSERT(pp->pick->user_data == nullptr);
+ pp->pick->user_data = (void**)&pp->lb_token;
+ // Pick via the RR policy.
+ bool pick_done = rr_policy_->PickLocked(pp->pick);
+ if (pick_done) {
+ PendingPickSetMetadataAndContext(pp);
+ if (force_async) {
+ GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
+ pick_done = false;
+ }
+ Delete(pp);
+ }
+ // else, the pending pick will be registered and taken care of by the
+ // pending pick list inside the RR policy. Eventually,
+ // OnPendingPickComplete() will be called, which will (among other
+ // things) add the LB token to the call's initial metadata.
+ return pick_done;
+}
- glb_lb_policy* glb_policy =
- static_cast<glb_lb_policy*>(gpr_zalloc(sizeof(*glb_policy)));
+void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) {
+ GPR_ASSERT(rr_policy_ == nullptr);
+ rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
+ "round_robin", args);
+ if (rr_policy_ == nullptr) {
+ gpr_log(GPR_ERROR, "[grpclb %p] Failure creating a RoundRobin policy",
+ this);
+ return;
+ }
+ // TODO(roth): We currently track this ref manually. Once the new
+ // ClosureRef API is done, pass the RefCountedPtr<> along with the closure.
+ auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested");
+ self.release();
+ rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_);
+ grpc_error* rr_state_error = nullptr;
+ rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error);
+ // Connectivity state is a function of the RR policy updated/created.
+ UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error);
+ // Add the gRPC LB's interested_parties pollset_set to that of the newly
+ // created RR policy. This will make the RR policy progress upon activity on
+ // gRPC LB, which in turn is tied to the application's call.
+ grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(),
+ interested_parties());
+ // Subscribe to changes to the connectivity of the new RR.
+ // TODO(roth): We currently track this ref manually. Once the new
+ // ClosureRef API is done, pass the RefCountedPtr<> along with the closure.
+ self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed");
+ self.release();
+ rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_,
+ &on_rr_connectivity_changed_);
+ rr_policy_->ExitIdleLocked();
+ // Send pending picks to RR policy.
+ PendingPick* pp;
+ while ((pp = pending_picks_)) {
+ pending_picks_ = pp->next;
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Pending pick about to (async) PICK from RR %p", this,
+ rr_policy_.get());
+ }
+ PickFromRoundRobinPolicyLocked(true /* force_async */, pp);
+ }
+ // Send pending pings to RR policy.
+ PendingPing* pping;
+ while ((pping = pending_pings_)) {
+ pending_pings_ = pping->next;
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO, "[grpclb %p] Pending ping about to PING from RR %p",
+ this, rr_policy_.get());
+ }
+ rr_policy_->PingOneLocked(pping->on_initiate, pping->on_ack);
+ Delete(pping);
+ }
+}
- /* Get server name. */
- arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
- GPR_ASSERT(arg != nullptr);
- GPR_ASSERT(arg->type == GRPC_ARG_STRING);
- grpc_uri* uri = grpc_uri_parse(arg->value.string, true);
- GPR_ASSERT(uri->path[0] != '\0');
- glb_policy->server_name =
- gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Will use '%s' as the server name for LB request.",
- glb_policy, glb_policy->server_name);
+grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
+ grpc_lb_addresses* addresses;
+ if (serverlist_ != nullptr) {
+ GPR_ASSERT(serverlist_->num_servers > 0);
+ addresses = ProcessServerlist(serverlist_);
+ } else {
+ // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't
+ // received any serverlist from the balancer, we use the fallback backends
+ // returned by the resolver. Note that the fallback backend list may be
+ // empty, in which case the new round_robin policy will keep the requested
+ // picks pending.
+ GPR_ASSERT(fallback_backend_addresses_ != nullptr);
+ addresses = grpc_lb_addresses_copy(fallback_backend_addresses_);
}
- grpc_uri_destroy(uri);
+ GPR_ASSERT(addresses != nullptr);
+ // Replace the LB addresses in the channel args that we pass down to
+ // the subchannel.
+ static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
+ const grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove(
+ args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &arg, 1);
+ grpc_lb_addresses_destroy(addresses);
+ return args;
+}
- glb_policy->cc_factory = args->client_channel_factory;
- GPR_ASSERT(glb_policy->cc_factory != nullptr);
+void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() {
+ if (shutting_down_) return;
+ grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked();
+ GPR_ASSERT(args != nullptr);
+ if (rr_policy_ != nullptr) {
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "[grpclb %p] Updating RR policy %p", this,
+ rr_policy_.get());
+ }
+ rr_policy_->UpdateLocked(*args);
+ } else {
+ LoadBalancingPolicy::Args lb_policy_args;
+ lb_policy_args.combiner = combiner();
+ lb_policy_args.client_channel_factory = client_channel_factory();
+ lb_policy_args.args = args;
+ CreateRoundRobinPolicyLocked(lb_policy_args);
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "[grpclb %p] Created new RR policy %p", this,
+ rr_policy_.get());
+ }
+ }
+ grpc_channel_args_destroy(args);
+}
- arg = grpc_channel_args_find(args->args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
- glb_policy->lb_call_timeout_ms =
- grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX});
+void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg,
+ grpc_error* error) {
+ GrpcLb* grpclb_policy = reinterpret_cast<GrpcLb*>(arg);
+ if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) {
+ grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested");
+ return;
+ }
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(
+ GPR_DEBUG,
+ "[grpclb %p] Re-resolution requested from the internal RR policy (%p).",
+ grpclb_policy, grpclb_policy->rr_policy_.get());
+ }
+ // If we are talking to a balancer, we expect to get updated addresses form
+ // the balancer, so we can ignore the re-resolution request from the RR
+ // policy. Otherwise, handle the re-resolution request using the
+ // grpclb policy's original re-resolution closure.
+ if (grpclb_policy->lb_calld_ == nullptr ||
+ !grpclb_policy->lb_calld_->seen_initial_response()) {
+ grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE);
+ }
+ // Give back the wrapper closure to the RR policy.
+ grpclb_policy->rr_policy_->SetReresolutionClosureLocked(
+ &grpclb_policy->on_rr_request_reresolution_);
+}
- arg = grpc_channel_args_find(args->args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS);
- glb_policy->lb_fallback_timeout_ms = grpc_channel_arg_get_integer(
- arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX});
+void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked(
+ grpc_error* rr_state_error) {
+ const grpc_connectivity_state curr_glb_state =
+ grpc_connectivity_state_check(&state_tracker_);
+ /* The new connectivity status is a function of the previous one and the new
+ * input coming from the status of the RR policy.
+ *
+ * current state (grpclb's)
+ * |
+ * v || I | C | R | TF | SD | <- new state (RR's)
+ * ===++====+=====+=====+======+======+
+ * I || I | C | R | [I] | [I] |
+ * ---++----+-----+-----+------+------+
+ * C || I | C | R | [C] | [C] |
+ * ---++----+-----+-----+------+------+
+ * R || I | C | R | [R] | [R] |
+ * ---++----+-----+-----+------+------+
+ * TF || I | C | R | [TF] | [TF] |
+ * ---++----+-----+-----+------+------+
+ * SD || NA | NA | NA | NA | NA | (*)
+ * ---++----+-----+-----+------+------+
+ *
+ * A [STATE] indicates that the old RR policy is kept. In those cases, STATE
+ * is the current state of grpclb, which is left untouched.
+ *
+ * In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to
+ * the previous RR instance.
+ *
+ * Note that the status is never updated to SHUTDOWN as a result of calling
+ * this function. Only glb_shutdown() has the power to set that state.
+ *
+ * (*) This function mustn't be called during shutting down. */
+ GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN);
+ switch (rr_connectivity_state_) {
+ case GRPC_CHANNEL_TRANSIENT_FAILURE:
+ case GRPC_CHANNEL_SHUTDOWN:
+ GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE);
+ break;
+ case GRPC_CHANNEL_IDLE:
+ case GRPC_CHANNEL_CONNECTING:
+ case GRPC_CHANNEL_READY:
+ GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE);
+ }
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(
+ GPR_INFO,
+ "[grpclb %p] Setting grpclb's state to %s from new RR policy %p state.",
+ this, grpc_connectivity_state_name(rr_connectivity_state_),
+ rr_policy_.get());
+ }
+ grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_,
+ rr_state_error,
+ "update_lb_connectivity_status_locked");
+}
- // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
- // since we use this to trigger the client_load_reporting filter.
- grpc_arg new_arg = grpc_channel_arg_string_create(
- (char*)GRPC_ARG_LB_POLICY_NAME, (char*)"grpclb");
- static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
- glb_policy->args = grpc_channel_args_copy_and_add_and_remove(
- args->args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
-
- /* Extract the backend addresses (may be empty) from the resolver for
- * fallback. */
- glb_policy->fallback_backend_addresses =
- extract_backend_addresses_locked(addresses);
-
- /* Create a client channel over them to communicate with a LB service */
- glb_policy->response_generator =
- grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>();
- grpc_channel_args* lb_channel_args = build_lb_channel_args(
- addresses, glb_policy->response_generator.get(), args->args);
- char* uri_str;
- gpr_asprintf(&uri_str, "fake:///%s", glb_policy->server_name);
- glb_policy->lb_channel = grpc_lb_policy_grpclb_create_lb_channel(
- uri_str, args->client_channel_factory, lb_channel_args);
-
- /* Propagate initial resolution */
- glb_policy->response_generator->SetResponse(lb_channel_args);
- grpc_channel_args_destroy(lb_channel_args);
- gpr_free(uri_str);
- if (glb_policy->lb_channel == nullptr) {
- gpr_free((void*)glb_policy->server_name);
- grpc_channel_args_destroy(glb_policy->args);
- gpr_free(glb_policy);
- return nullptr;
+void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg,
+ grpc_error* error) {
+ GrpcLb* grpclb_policy = reinterpret_cast<GrpcLb*>(arg);
+ if (grpclb_policy->shutting_down_) {
+ grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed");
+ return;
}
- grpc_subchannel_index_ref();
- GRPC_CLOSURE_INIT(&glb_policy->rr_on_connectivity_changed,
- rr_on_connectivity_changed_locked, glb_policy,
- grpc_combiner_scheduler(args->combiner));
- GRPC_CLOSURE_INIT(&glb_policy->rr_on_reresolution_requested,
- rr_on_reresolution_requested_locked, glb_policy,
- grpc_combiner_scheduler(args->combiner));
- GRPC_CLOSURE_INIT(&glb_policy->lb_channel_on_connectivity_changed,
- glb_lb_channel_on_connectivity_changed_cb, glb_policy,
- grpc_combiner_scheduler(args->combiner));
- grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable, args->combiner);
- grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE,
- "grpclb");
- // Init LB call backoff option.
- grpc_core::BackOff::Options backoff_options;
- backoff_options
- .set_initial_backoff(GRPC_GRPCLB_INITIAL_CONNECT_BACKOFF_SECONDS * 1000)
- .set_multiplier(GRPC_GRPCLB_RECONNECT_BACKOFF_MULTIPLIER)
- .set_jitter(GRPC_GRPCLB_RECONNECT_JITTER)
- .set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
- glb_policy->lb_call_backoff.Init(backoff_options);
- return &glb_policy->base;
+ grpclb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked(
+ GRPC_ERROR_REF(error));
+ // Resubscribe. Reuse the "on_rr_connectivity_changed" ref.
+ grpclb_policy->rr_policy_->NotifyOnStateChangeLocked(
+ &grpclb_policy->rr_connectivity_state_,
+ &grpclb_policy->on_rr_connectivity_changed_);
}
-static void glb_factory_ref(grpc_lb_policy_factory* factory) {}
+//
+// factory
+//
-static void glb_factory_unref(grpc_lb_policy_factory* factory) {}
+class GrpcLbFactory : public LoadBalancingPolicyFactory {
+ public:
+ OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+ const LoadBalancingPolicy::Args& args) const override {
+ /* Count the number of gRPC-LB addresses. There must be at least one. */
+ const grpc_arg* arg =
+ grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES);
+ if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
+ return nullptr;
+ }
+ grpc_lb_addresses* addresses =
+ reinterpret_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ size_t num_grpclb_addrs = 0;
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+ }
+ if (num_grpclb_addrs == 0) return nullptr;
+ return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(addresses, args));
+ }
-static const grpc_lb_policy_factory_vtable glb_factory_vtable = {
- glb_factory_ref, glb_factory_unref, glb_create, "grpclb"};
+ const char* name() const override { return "grpclb"; }
+};
-static grpc_lb_policy_factory glb_lb_policy_factory = {&glb_factory_vtable};
+} // namespace
-grpc_lb_policy_factory* grpc_glb_lb_factory_create() {
- return &glb_lb_policy_factory;
-}
+} // namespace grpc_core
-/* Plugin registration */
+//
+// Plugin registration
+//
+
+namespace {
// Only add client_load_reporting filter if the grpclb LB policy is used.
-static bool maybe_add_client_load_reporting_filter(
- grpc_channel_stack_builder* builder, void* arg) {
+bool maybe_add_client_load_reporting_filter(grpc_channel_stack_builder* builder,
+ void* arg) {
const grpc_channel_args* args =
grpc_channel_stack_builder_get_channel_arguments(builder);
const grpc_arg* channel_arg =
@@ -1938,14 +1880,18 @@ static bool maybe_add_client_load_reporting_filter(
if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_STRING &&
strcmp(channel_arg->value.string, "grpclb") == 0) {
return grpc_channel_stack_builder_append_filter(
- builder, static_cast<const grpc_channel_filter*>(arg), nullptr,
- nullptr);
+ builder, (const grpc_channel_filter*)arg, nullptr, nullptr);
}
return true;
}
+} // namespace
+
void grpc_lb_policy_grpclb_init() {
- grpc_register_lb_policy(grpc_glb_lb_factory_create());
+ grpc_core::LoadBalancingPolicyRegistry::Builder::
+ RegisterLoadBalancingPolicyFactory(
+ grpc_core::UniquePtr<grpc_core::LoadBalancingPolicyFactory>(
+ grpc_core::New<grpc_core::GrpcLbFactory>()));
grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL,
GRPC_CHANNEL_INIT_BUILTIN_PRIORITY,
maybe_add_client_load_reporting_filter,
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
index 013fb12aea..fd873f096d 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc
@@ -16,57 +16,11 @@
*
*/
-#include <grpc/support/alloc.h>
-#include <grpc/support/string_util.h>
+#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/iomgr/sockaddr_utils.h"
-grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
- const char* lb_service_target_addresses,
- grpc_client_channel_factory* client_channel_factory,
+grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args) {
- grpc_channel* lb_channel = grpc_client_channel_factory_create_channel(
- client_channel_factory, lb_service_target_addresses,
- GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, args);
- return lb_channel;
-}
-
-grpc_channel_args* grpc_lb_policy_grpclb_build_lb_channel_args(
- grpc_slice_hash_table* targets_info,
- grpc_core::FakeResolverResponseGenerator* response_generator,
- const grpc_channel_args* args) {
- const grpc_arg to_add[] = {
- grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
- response_generator)};
- /* We remove:
- *
- * - The channel arg for the LB policy name, since we want to use the default
- * (pick_first) in this case.
- *
- * - The channel arg for the resolved addresses, since that will be generated
- * by the name resolver used in the LB channel. Note that the LB channel
- * will use the fake resolver, so this won't actually generate a query
- * to DNS (or some other name service). However, the addresses returned by
- * the fake resolver will have is_balancer=false, whereas our own
- * addresses have is_balancer=true. We need the LB channel to return
- * addresses with is_balancer=false so that it does not wind up recursively
- * using the grpclb LB policy, as per the special case logic in
- * client_channel.c.
- *
- * - The channel arg for the server URI, since that will be different for the
- * LB channel than for the parent channel (the client channel factory will
- * re-add this arg with the right value).
- *
- * - The fake resolver generator, because we are replacing it with the one
- * from the grpclb policy, used to propagate updates to the LB channel. */
- static const char* keys_to_remove[] = {
- GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI,
- GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR};
- return grpc_channel_args_copy_and_add_and_remove(
- args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), to_add,
- GPR_ARRAY_SIZE(to_add));
+ return args;
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
index 2e34e3cab5..825065a9c3 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
@@ -19,26 +19,18 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
-#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
-#include "src/core/lib/slice/slice_hash_table.h"
-/** Create the channel used for communicating with an LB service.
- * Note that an LB *service* may be comprised of several LB *servers*.
- *
- * \a lb_service_target_addresses is the target URI containing the addresses
- * from resolving the LB service's name (eg, ipv4:10.0.0.1:1234,10.2.3.4:9876).
- * \a client_channel_factory will be used for the creation of the LB channel,
- * alongside the channel args passed in \a args. */
-grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
- const char* lb_service_target_addresses,
- grpc_client_channel_factory* client_channel_factory,
+/// Makes any necessary modifications to \a args for use in the grpclb
+/// balancer channel.
+///
+/// Takes ownership of \a args.
+///
+/// Caller takes ownership of the returned args.
+grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args);
-grpc_channel_args* grpc_lb_policy_grpclb_build_lb_channel_args(
- grpc_slice_hash_table* targets_info,
- grpc_core::FakeResolverResponseGenerator* response_generator,
- const grpc_channel_args* args);
-
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CHANNEL_H \
*/
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
index 5e615addbf..441efd5e23 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
@@ -16,85 +16,93 @@
*
*/
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
+
+#include <string.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
-#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/lb_targets_info.h"
+#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/lib/slice/slice_internal.h"
-grpc_channel* grpc_lb_policy_grpclb_create_lb_channel(
- const char* lb_service_target_addresses,
- grpc_client_channel_factory* client_channel_factory,
+namespace grpc_core {
+namespace {
+
+int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
+ const grpc_core::UniquePtr<char>& b) {
+ return strcmp(a.get(), b.get());
+}
+
+RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
+ grpc_lb_addresses* addresses) {
+ TargetAuthorityTable::Entry* target_authority_entries =
+ static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
+ sizeof(*target_authority_entries) * addresses->num_addresses));
+ for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ char* addr_str;
+ GPR_ASSERT(grpc_sockaddr_to_string(
+ &addr_str, &addresses->addresses[i].address, true) > 0);
+ target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
+ target_authority_entries[i].value.reset(
+ gpr_strdup(addresses->addresses[i].balancer_name));
+ gpr_free(addr_str);
+ }
+ RefCountedPtr<TargetAuthorityTable> target_authority_table =
+ TargetAuthorityTable::Create(addresses->num_addresses,
+ target_authority_entries, BalancerNameCmp);
+ gpr_free(target_authority_entries);
+ return target_authority_table;
+}
+
+} // namespace
+} // namespace grpc_core
+
+grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_channel_args* args) {
- grpc_channel_args* new_args = args;
+ const char* args_to_remove[1];
+ size_t num_args_to_remove = 0;
+ grpc_arg args_to_add[2];
+ size_t num_args_to_add = 0;
+ // Add arg for targets info table.
+ const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
+ GPR_ASSERT(arg != nullptr);
+ GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
+ grpc_lb_addresses* addresses =
+ static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
+ target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
+ args_to_add[num_args_to_add++] =
+ grpc_core::CreateTargetAuthorityTableChannelArg(
+ target_authority_table.get());
+ // Substitute the channel credentials with a version without call
+ // credentials: the load balancer is not necessarily trusted to handle
+ // bearer token credentials.
grpc_channel_credentials* channel_credentials =
grpc_channel_credentials_find_in_args(args);
+ grpc_channel_credentials* creds_sans_call_creds = nullptr;
if (channel_credentials != nullptr) {
- /* Substitute the channel credentials with a version without call
- * credentials: the load balancer is not necessarily trusted to handle
- * bearer token credentials */
- static const char* keys_to_remove[] = {GRPC_ARG_CHANNEL_CREDENTIALS};
- grpc_channel_credentials* creds_sans_call_creds =
+ creds_sans_call_creds =
grpc_channel_credentials_duplicate_without_call_credentials(
channel_credentials);
GPR_ASSERT(creds_sans_call_creds != nullptr);
- grpc_arg args_to_add[] = {
- grpc_channel_credentials_to_arg(creds_sans_call_creds)};
- /* Create the new set of channel args */
- new_args = grpc_channel_args_copy_and_add_and_remove(
- args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add,
- GPR_ARRAY_SIZE(args_to_add));
- grpc_channel_credentials_unref(creds_sans_call_creds);
+ args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS;
+ args_to_add[num_args_to_add++] =
+ grpc_channel_credentials_to_arg(creds_sans_call_creds);
}
- grpc_channel* lb_channel = grpc_client_channel_factory_create_channel(
- client_channel_factory, lb_service_target_addresses,
- GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, new_args);
- if (channel_credentials != nullptr) {
- grpc_channel_args_destroy(new_args);
+ grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove(
+ args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add);
+ // Clean up.
+ grpc_channel_args_destroy(args);
+ if (creds_sans_call_creds != nullptr) {
+ grpc_channel_credentials_unref(creds_sans_call_creds);
}
- return lb_channel;
-}
-
-grpc_channel_args* grpc_lb_policy_grpclb_build_lb_channel_args(
- grpc_slice_hash_table* targets_info,
- grpc_core::FakeResolverResponseGenerator* response_generator,
- const grpc_channel_args* args) {
- const grpc_arg to_add[] = {
- grpc_lb_targets_info_create_channel_arg(targets_info),
- grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
- response_generator)};
- /* We remove:
- *
- * - The channel arg for the LB policy name, since we want to use the default
- * (pick_first) in this case.
- *
- * - The channel arg for the resolved addresses, since that will be generated
- * by the name resolver used in the LB channel. Note that the LB channel
- * will use the fake resolver, so this won't actually generate a query
- * to DNS (or some other name service). However, the addresses returned by
- * the fake resolver will have is_balancer=false, whereas our own
- * addresses have is_balancer=true. We need the LB channel to return
- * addresses with is_balancer=false so that it does not wind up recursively
- * using the grpclb LB policy, as per the special case logic in
- * client_channel.c.
- *
- * - The channel arg for the server URI, since that will be different for the
- * LB channel than for the parent channel (the client channel factory will
- * re-add this arg with the right value).
- *
- * - The fake resolver generator, because we are replacing it with the one
- * from the grpclb policy, used to propagate updates to the LB channel. */
- static const char* keys_to_remove[] = {
- GRPC_ARG_LB_POLICY_NAME, GRPC_ARG_LB_ADDRESSES, GRPC_ARG_SERVER_URI,
- GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR};
- /* Add the targets info table to be used for secure naming */
- return grpc_channel_args_copy_and_add_and_remove(
- args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), to_add,
- GPR_ARRAY_SIZE(to_add));
+ return result;
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
index 0b5a798be3..dfbaead7d5 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include <string.h>
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
index d4b9d06848..c971e56883 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_CLIENT_STATS_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/impl/codegen/grpc_types.h>
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
index c388b6ba77..7ef3bcf24f 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
#include "third_party/nanopb/pb_decode.h"
#include "third_party/nanopb/pb_encode.h"
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
index ccb0212643..d4270f2536 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_LOAD_BALANCER_API_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice_buffer.h>
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index 296bdcb247..818b93c882 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
@@ -29,194 +31,225 @@
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/transport/connectivity_state.h"
-grpc_core::TraceFlag grpc_lb_pick_first_trace(false, "pick_first");
+namespace grpc_core {
+
+TraceFlag grpc_lb_pick_first_trace(false, "pick_first");
+
+namespace {
+
+//
+// pick_first LB policy
+//
+
+class PickFirst : public LoadBalancingPolicy {
+ public:
+ explicit PickFirst(const Args& args);
+
+ void UpdateLocked(const grpc_channel_args& args) override;
+ bool PickLocked(PickState* pick) override;
+ void CancelPickLocked(PickState* pick, grpc_error* error) override;
+ void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) override;
+ void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
+ grpc_closure* closure) override;
+ grpc_connectivity_state CheckConnectivityLocked(
+ grpc_error** connectivity_error) override;
+ void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
+ void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
+ void ExitIdleLocked() override;
+
+ private:
+ ~PickFirst();
+
+ void ShutdownLocked() override;
+
+ void StartPickingLocked();
+ void DestroyUnselectedSubchannelsLocked();
+
+ static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
+
+ void SubchannelListRefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason);
+ void SubchannelListUnrefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason);
-typedef struct {
- /** base policy: must be first */
- grpc_lb_policy base;
/** all our subchannels */
- grpc_lb_subchannel_list* subchannel_list;
+ grpc_lb_subchannel_list* subchannel_list_ = nullptr;
/** latest pending subchannel list */
- grpc_lb_subchannel_list* latest_pending_subchannel_list;
+ grpc_lb_subchannel_list* latest_pending_subchannel_list_ = nullptr;
/** selected subchannel in \a subchannel_list */
- grpc_lb_subchannel_data* selected;
+ grpc_lb_subchannel_data* selected_ = nullptr;
/** have we started picking? */
- bool started_picking;
+ bool started_picking_ = false;
/** are we shut down? */
- bool shutdown;
+ bool shutdown_ = false;
/** list of picks that are waiting on connectivity */
- grpc_lb_policy_pick_state* pending_picks;
+ PickState* pending_picks_ = nullptr;
/** our connectivity state tracker */
- grpc_connectivity_state_tracker state_tracker;
-} pick_first_lb_policy;
-
-static void pf_destroy(grpc_lb_policy* pol) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- GPR_ASSERT(p->subchannel_list == nullptr);
- GPR_ASSERT(p->latest_pending_subchannel_list == nullptr);
- GPR_ASSERT(p->pending_picks == nullptr);
- grpc_connectivity_state_destroy(&p->state_tracker);
- gpr_free(p);
- grpc_subchannel_index_unref();
+ grpc_connectivity_state_tracker state_tracker_;
+};
+
+PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) {
+ GPR_ASSERT(args.client_channel_factory != nullptr);
+ grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
+ "pick_first");
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Pick First %p destroyed.", (void*)p);
+ gpr_log(GPR_DEBUG, "Pick First %p created.", this);
}
+ UpdateLocked(*args.args);
+ grpc_subchannel_index_ref();
}
-static void pf_shutdown_locked(grpc_lb_policy* pol,
- grpc_lb_policy* new_policy) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
+PickFirst::~PickFirst() {
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Pick First %p Shutting down", p);
+ gpr_log(GPR_DEBUG, "Destroying Pick First %p", this);
}
- p->shutdown = true;
- grpc_lb_policy_pick_state* pick;
- while ((pick = p->pending_picks) != nullptr) {
- p->pending_picks = pick->next;
- if (new_policy != nullptr) {
- // Hand off to new LB policy.
- if (grpc_lb_policy_pick_locked(new_policy, pick)) {
- // Synchronous return, schedule closure.
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
- }
- } else {
- pick->connected_subchannel.reset();
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
+ GPR_ASSERT(subchannel_list_ == nullptr);
+ GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
+ GPR_ASSERT(pending_picks_ == nullptr);
+ grpc_connectivity_state_destroy(&state_tracker_);
+ grpc_subchannel_index_unref();
+}
+
+void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
+ PickState* pick;
+ while ((pick = pending_picks_) != nullptr) {
+ pending_picks_ = pick->next;
+ if (new_policy->PickLocked(pick)) {
+ // Synchronous return, schedule closure.
+ GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
}
}
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
+}
+
+void PickFirst::ShutdownLocked() {
+ grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
+ if (grpc_lb_pick_first_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "Pick First %p Shutting down", this);
+ }
+ shutdown_ = true;
+ PickState* pick;
+ while ((pick = pending_picks_) != nullptr) {
+ pending_picks_ = pick->next;
+ pick->connected_subchannel.reset();
+ GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
+ }
+ grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "shutdown");
- if (p->subchannel_list != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
- "pf_shutdown");
- p->subchannel_list = nullptr;
+ if (subchannel_list_ != nullptr) {
+ grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_, "pf_shutdown");
+ subchannel_list_ = nullptr;
}
- if (p->latest_pending_subchannel_list != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(
- p->latest_pending_subchannel_list, "pf_shutdown");
- p->latest_pending_subchannel_list = nullptr;
+ if (latest_pending_subchannel_list_ != nullptr) {
+ grpc_lb_subchannel_list_shutdown_and_unref(latest_pending_subchannel_list_,
+ "pf_shutdown");
+ latest_pending_subchannel_list_ = nullptr;
}
- grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
- GRPC_ERROR_CANCELLED);
+ TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED);
GRPC_ERROR_UNREF(error);
}
-static void pf_cancel_pick_locked(grpc_lb_policy* pol,
- grpc_lb_policy_pick_state* pick,
- grpc_error* error) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- grpc_lb_policy_pick_state* pp = p->pending_picks;
- p->pending_picks = nullptr;
+void PickFirst::CancelPickLocked(PickState* pick, grpc_error* error) {
+ PickState* pp = pending_picks_;
+ pending_picks_ = nullptr;
while (pp != nullptr) {
- grpc_lb_policy_pick_state* next = pp->next;
+ PickState* next = pp->next;
if (pp == pick) {
pick->connected_subchannel.reset();
GRPC_CLOSURE_SCHED(pick->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
} else {
- pp->next = p->pending_picks;
- p->pending_picks = pp;
+ pp->next = pending_picks_;
+ pending_picks_ = pp;
}
pp = next;
}
GRPC_ERROR_UNREF(error);
}
-static void pf_cancel_picks_locked(grpc_lb_policy* pol,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error* error) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- grpc_lb_policy_pick_state* pick = p->pending_picks;
- p->pending_picks = nullptr;
+void PickFirst::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) {
+ PickState* pick = pending_picks_;
+ pending_picks_ = nullptr;
while (pick != nullptr) {
- grpc_lb_policy_pick_state* next = pick->next;
+ PickState* next = pick->next;
if ((pick->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
GRPC_CLOSURE_SCHED(pick->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Pick Cancelled", &error, 1));
} else {
- pick->next = p->pending_picks;
- p->pending_picks = pick;
+ pick->next = pending_picks_;
+ pending_picks_ = pick;
}
pick = next;
}
GRPC_ERROR_UNREF(error);
}
-static void start_picking_locked(pick_first_lb_policy* p) {
- p->started_picking = true;
- if (p->subchannel_list != nullptr &&
- p->subchannel_list->num_subchannels > 0) {
- p->subchannel_list->checking_subchannel = 0;
- for (size_t i = 0; i < p->subchannel_list->num_subchannels; ++i) {
- if (p->subchannel_list->subchannels[i].subchannel != nullptr) {
- grpc_lb_subchannel_list_ref_for_connectivity_watch(
- p->subchannel_list, "connectivity_watch+start_picking");
+void PickFirst::StartPickingLocked() {
+ started_picking_ = true;
+ if (subchannel_list_ != nullptr && subchannel_list_->num_subchannels > 0) {
+ subchannel_list_->checking_subchannel = 0;
+ for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
+ if (subchannel_list_->subchannels[i].subchannel != nullptr) {
+ SubchannelListRefForConnectivityWatch(
+ subchannel_list_, "connectivity_watch+start_picking");
grpc_lb_subchannel_data_start_connectivity_watch(
- &p->subchannel_list->subchannels[i]);
+ &subchannel_list_->subchannels[i]);
break;
}
}
}
}
-static void pf_exit_idle_locked(grpc_lb_policy* pol) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- if (!p->started_picking) {
- start_picking_locked(p);
+void PickFirst::ExitIdleLocked() {
+ if (!started_picking_) {
+ StartPickingLocked();
}
}
-static int pf_pick_locked(grpc_lb_policy* pol,
- grpc_lb_policy_pick_state* pick) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
+bool PickFirst::PickLocked(PickState* pick) {
// If we have a selected subchannel already, return synchronously.
- if (p->selected != nullptr) {
- pick->connected_subchannel = p->selected->connected_subchannel;
- return 1;
+ if (selected_ != nullptr) {
+ pick->connected_subchannel = selected_->connected_subchannel;
+ return true;
}
// No subchannel selected yet, so handle asynchronously.
- if (!p->started_picking) {
- start_picking_locked(p);
+ if (!started_picking_) {
+ StartPickingLocked();
}
- pick->next = p->pending_picks;
- p->pending_picks = pick;
- return 0;
+ pick->next = pending_picks_;
+ pending_picks_ = pick;
+ return false;
}
-static void destroy_unselected_subchannels_locked(pick_first_lb_policy* p) {
- for (size_t i = 0; i < p->subchannel_list->num_subchannels; ++i) {
- grpc_lb_subchannel_data* sd = &p->subchannel_list->subchannels[i];
- if (p->selected != sd) {
+void PickFirst::DestroyUnselectedSubchannelsLocked() {
+ for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
+ grpc_lb_subchannel_data* sd = &subchannel_list_->subchannels[i];
+ if (selected_ != sd) {
grpc_lb_subchannel_data_unref_subchannel(sd,
"selected_different_subchannel");
}
}
}
-static grpc_connectivity_state pf_check_connectivity_locked(
- grpc_lb_policy* pol, grpc_error** error) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- return grpc_connectivity_state_get(&p->state_tracker, error);
+grpc_connectivity_state PickFirst::CheckConnectivityLocked(grpc_error** error) {
+ return grpc_connectivity_state_get(&state_tracker_, error);
}
-static void pf_notify_on_state_change_locked(grpc_lb_policy* pol,
- grpc_connectivity_state* current,
- grpc_closure* notify) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- grpc_connectivity_state_notify_on_state_change(&p->state_tracker, current,
+void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
+ grpc_closure* notify) {
+ grpc_connectivity_state_notify_on_state_change(&state_tracker_, current,
notify);
}
-static void pf_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
- grpc_closure* on_ack) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(pol);
- if (p->selected) {
- p->selected->connected_subchannel->Ping(on_initiate, on_ack);
+void PickFirst::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
+ if (selected_ != nullptr) {
+ selected_->connected_subchannel->Ping(on_initiate, on_ack);
} else {
GRPC_CLOSURE_SCHED(on_initiate,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
@@ -225,18 +258,31 @@ static void pf_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
}
}
-static void pf_connectivity_changed_locked(void* arg, grpc_error* error);
+void PickFirst::SubchannelListRefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason) {
+ // TODO(roth): We currently track this ref manually. Once the new
+ // ClosureRef API is ready and the subchannel_list code has been
+ // converted to a C++ API, find a way to hold the RefCountedPtr<>
+ // somewhere (maybe in the subchannel_data object) instead of doing
+ // this manually.
+ auto self = Ref(DEBUG_LOCATION, reason);
+ self.release();
+ grpc_lb_subchannel_list_ref(subchannel_list, reason);
+}
+
+void PickFirst::SubchannelListUnrefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason) {
+ Unref(DEBUG_LOCATION, reason);
+ grpc_lb_subchannel_list_unref(subchannel_list, reason);
+}
-static void pf_update_locked(grpc_lb_policy* policy,
- const grpc_lb_policy_args* args) {
- pick_first_lb_policy* p = reinterpret_cast<pick_first_lb_policy*>(policy);
- const grpc_arg* arg =
- grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
+void PickFirst::UpdateLocked(const grpc_channel_args& args) {
+ const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- if (p->subchannel_list == nullptr) {
+ if (subchannel_list_ == nullptr) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
- &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
"pf_update_missing");
} else {
@@ -244,77 +290,78 @@ static void pf_update_locked(grpc_lb_policy* policy,
gpr_log(GPR_ERROR,
"No valid LB addresses channel arg for Pick First %p update, "
"ignoring.",
- (void*)p);
+ this);
}
return;
}
const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
+ (const grpc_lb_addresses*)arg->value.pointer.p;
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_INFO, "Pick First %p received update with %lu addresses",
- (void*)p, static_cast<unsigned long>(addresses->num_addresses));
+ gpr_log(GPR_INFO,
+ "Pick First %p received update with %" PRIuPTR " addresses", this,
+ addresses->num_addresses);
}
grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
- &p->base, &grpc_lb_pick_first_trace, addresses, args,
- pf_connectivity_changed_locked);
+ this, &grpc_lb_pick_first_trace, addresses, combiner(),
+ client_channel_factory(), args, &PickFirst::OnConnectivityChangedLocked);
if (subchannel_list->num_subchannels == 0) {
// Empty update or no valid subchannels. Unsubscribe from all current
// subchannels and put the channel in TRANSIENT_FAILURE.
grpc_connectivity_state_set(
- &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
"pf_update_empty");
- if (p->subchannel_list != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
+ if (subchannel_list_ != nullptr) {
+ grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
"sl_shutdown_empty_update");
}
- p->subchannel_list = subchannel_list; // Empty list.
- p->selected = nullptr;
+ subchannel_list_ = subchannel_list; // Empty list.
+ selected_ = nullptr;
return;
}
- if (p->selected == nullptr) {
+ if (selected_ == nullptr) {
// We don't yet have a selected subchannel, so replace the current
// subchannel list immediately.
- if (p->subchannel_list != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
+ if (subchannel_list_ != nullptr) {
+ grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
"pf_update_before_selected");
}
- p->subchannel_list = subchannel_list;
+ subchannel_list_ = subchannel_list;
} else {
// We do have a selected subchannel.
// Check if it's present in the new list. If so, we're done.
for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
grpc_lb_subchannel_data* sd = &subchannel_list->subchannels[i];
- if (sd->subchannel == p->selected->subchannel) {
+ if (sd->subchannel == selected_->subchannel) {
// The currently selected subchannel is in the update: we are done.
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p found already selected subchannel %p "
"at update index %" PRIuPTR " of %" PRIuPTR "; update done",
- p, p->selected->subchannel, i,
+ this, selected_->subchannel, i,
subchannel_list->num_subchannels);
}
- if (p->selected->connected_subchannel != nullptr) {
- sd->connected_subchannel = p->selected->connected_subchannel;
+ if (selected_->connected_subchannel != nullptr) {
+ sd->connected_subchannel = selected_->connected_subchannel;
}
- p->selected = sd;
- if (p->subchannel_list != nullptr) {
+ selected_ = sd;
+ if (subchannel_list_ != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
- p->subchannel_list, "pf_update_includes_selected");
+ subchannel_list_, "pf_update_includes_selected");
}
- p->subchannel_list = subchannel_list;
- destroy_unselected_subchannels_locked(p);
- grpc_lb_subchannel_list_ref_for_connectivity_watch(
+ subchannel_list_ = subchannel_list;
+ DestroyUnselectedSubchannelsLocked();
+ SubchannelListRefForConnectivityWatch(
subchannel_list, "connectivity_watch+replace_selected");
grpc_lb_subchannel_data_start_connectivity_watch(sd);
// If there was a previously pending update (which may or may
// not have contained the currently selected subchannel), drop
// it, so that it doesn't override what we've done here.
- if (p->latest_pending_subchannel_list != nullptr) {
+ if (latest_pending_subchannel_list_ != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
- p->latest_pending_subchannel_list,
+ latest_pending_subchannel_list_,
"pf_update_includes_selected+outdated");
- p->latest_pending_subchannel_list = nullptr;
+ latest_pending_subchannel_list_ = nullptr;
}
return;
}
@@ -323,84 +370,81 @@ static void pf_update_locked(grpc_lb_policy* policy,
// pending subchannel list to the new subchannel list. We will wait
// for it to report READY before swapping it into the current
// subchannel list.
- if (p->latest_pending_subchannel_list != nullptr) {
+ if (latest_pending_subchannel_list_ != nullptr) {
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG,
"Pick First %p Shutting down latest pending subchannel list "
"%p, about to be replaced by newer latest %p",
- (void*)p, (void*)p->latest_pending_subchannel_list,
- (void*)subchannel_list);
+ this, latest_pending_subchannel_list_, subchannel_list);
}
grpc_lb_subchannel_list_shutdown_and_unref(
- p->latest_pending_subchannel_list, "sl_outdated_dont_smash");
+ latest_pending_subchannel_list_, "sl_outdated_dont_smash");
}
- p->latest_pending_subchannel_list = subchannel_list;
+ latest_pending_subchannel_list_ = subchannel_list;
}
// If we've started picking, start trying to connect to the first
// subchannel in the new list.
- if (p->started_picking) {
- grpc_lb_subchannel_list_ref_for_connectivity_watch(
- subchannel_list, "connectivity_watch+update");
+ if (started_picking_) {
+ SubchannelListRefForConnectivityWatch(subchannel_list,
+ "connectivity_watch+update");
grpc_lb_subchannel_data_start_connectivity_watch(
&subchannel_list->subchannels[0]);
}
}
-static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
- grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
- pick_first_lb_policy* p =
- reinterpret_cast<pick_first_lb_policy*>(sd->subchannel_list->policy);
+void PickFirst::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
+ grpc_lb_subchannel_data* sd = reinterpret_cast<grpc_lb_subchannel_data*>(arg);
+ PickFirst* p = reinterpret_cast<PickFirst*>(sd->subchannel_list->policy);
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_DEBUG,
"Pick First %p connectivity changed for subchannel %p (%" PRIuPTR
" of %" PRIuPTR
- "), subchannel_list %p: state=%s p->shutdown=%d "
+ "), subchannel_list %p: state=%s p->shutdown_=%d "
"sd->subchannel_list->shutting_down=%d error=%s",
- (void*)p, (void*)sd->subchannel,
- sd->subchannel_list->checking_subchannel,
- sd->subchannel_list->num_subchannels, (void*)sd->subchannel_list,
+ p, sd->subchannel, sd->subchannel_list->checking_subchannel,
+ sd->subchannel_list->num_subchannels, sd->subchannel_list,
grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
- p->shutdown, sd->subchannel_list->shutting_down,
+ p->shutdown_, sd->subchannel_list->shutting_down,
grpc_error_string(error));
}
// If the policy is shutting down, unref and return.
- if (p->shutdown) {
+ if (p->shutdown_) {
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_shutdown");
- grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
- "pf_shutdown");
+ p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
+ "pf_shutdown");
return;
}
// If the subchannel list is shutting down, stop watching.
if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "pf_sl_shutdown");
- grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
- "pf_sl_shutdown");
+ p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
+ "pf_sl_shutdown");
return;
}
// If we're still here, the notification must be for a subchannel in
// either the current or latest pending subchannel lists.
- GPR_ASSERT(sd->subchannel_list == p->subchannel_list ||
- sd->subchannel_list == p->latest_pending_subchannel_list);
+ GPR_ASSERT(sd->subchannel_list == p->subchannel_list_ ||
+ sd->subchannel_list == p->latest_pending_subchannel_list_);
// Update state.
sd->curr_connectivity_state = sd->pending_connectivity_state_unsafe;
// Handle updates for the currently selected subchannel.
- if (p->selected == sd) {
+ if (p->selected_ == sd) {
// If the new state is anything other than READY and there is a
// pending update, switch to the pending update.
if (sd->curr_connectivity_state != GRPC_CHANNEL_READY &&
- p->latest_pending_subchannel_list != nullptr) {
- p->selected = nullptr;
+ p->latest_pending_subchannel_list_ != nullptr) {
+ p->selected_ = nullptr;
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- grpc_lb_subchannel_list_unref_for_connectivity_watch(
+ p->SubchannelListUnrefForConnectivityWatch(
sd->subchannel_list, "selected_not_ready+switch_to_update");
grpc_lb_subchannel_list_shutdown_and_unref(
- p->subchannel_list, "selected_not_ready+switch_to_update");
- p->subchannel_list = p->latest_pending_subchannel_list;
- p->latest_pending_subchannel_list = nullptr;
+ p->subchannel_list_, "selected_not_ready+switch_to_update");
+ p->subchannel_list_ = p->latest_pending_subchannel_list_;
+ p->latest_pending_subchannel_list_ = nullptr;
grpc_connectivity_state_set(
- &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "selected_not_ready+switch_to_update");
} else {
// TODO(juanlishen): we re-resolve when the selected subchannel goes to
@@ -411,21 +455,20 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
if (sd->curr_connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
// If the selected channel goes bad, request a re-resolution.
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_IDLE,
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE,
"selected_changed+reresolve");
- p->started_picking = false;
- grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_pick_first_trace,
- GRPC_ERROR_NONE);
- // in transient failure. Rely on re-resolution to recover.
- p->selected = nullptr;
+ p->started_picking_ = false;
+ p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
+ // In transient failure. Rely on re-resolution to recover.
+ p->selected_ = nullptr;
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
- grpc_lb_subchannel_list_unref_for_connectivity_watch(
- sd->subchannel_list, "pf_selected_shutdown");
+ p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
+ "pf_selected_shutdown");
grpc_lb_subchannel_data_unref_subchannel(
sd, "pf_selected_shutdown"); // Unrefs connected subchannel
} else {
- grpc_connectivity_state_set(&p->state_tracker,
+ grpc_connectivity_state_set(&p->state_tracker_,
sd->curr_connectivity_state,
GRPC_ERROR_REF(error), "selected_changed");
// Renew notification.
@@ -436,45 +479,45 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
}
// If we get here, there are two possible cases:
// 1. We do not currently have a selected subchannel, and the update is
- // for a subchannel in p->subchannel_list that we're trying to
+ // for a subchannel in p->subchannel_list_ that we're trying to
// connect to. The goal here is to find a subchannel that we can
// select.
// 2. We do currently have a selected subchannel, and the update is
- // for a subchannel in p->latest_pending_subchannel_list. The
+ // for a subchannel in p->latest_pending_subchannel_list_. The
// goal here is to find a subchannel from the update that we can
// select in place of the current one.
switch (sd->curr_connectivity_state) {
case GRPC_CHANNEL_READY: {
- // Case 2. Promote p->latest_pending_subchannel_list to
- // p->subchannel_list.
+ // Case 2. Promote p->latest_pending_subchannel_list_ to
+ // p->subchannel_list_.
sd->connected_subchannel =
grpc_subchannel_get_connected_subchannel(sd->subchannel);
- if (sd->subchannel_list == p->latest_pending_subchannel_list) {
- GPR_ASSERT(p->subchannel_list != nullptr);
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
+ if (sd->subchannel_list == p->latest_pending_subchannel_list_) {
+ GPR_ASSERT(p->subchannel_list_ != nullptr);
+ grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list_,
"finish_update");
- p->subchannel_list = p->latest_pending_subchannel_list;
- p->latest_pending_subchannel_list = nullptr;
+ p->subchannel_list_ = p->latest_pending_subchannel_list_;
+ p->latest_pending_subchannel_list_ = nullptr;
}
// Cases 1 and 2.
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_READY,
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "connecting_ready");
- p->selected = sd;
+ p->selected_ = sd;
if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", (void*)p,
- (void*)sd->subchannel);
+ gpr_log(GPR_INFO, "Pick First %p selected subchannel %p", p,
+ sd->subchannel);
}
// Drop all other subchannels, since we are now connected.
- destroy_unselected_subchannels_locked(p);
+ p->DestroyUnselectedSubchannelsLocked();
// Update any calls that were waiting for a pick.
- grpc_lb_policy_pick_state* pick;
- while ((pick = p->pending_picks)) {
- p->pending_picks = pick->next;
- pick->connected_subchannel = p->selected->connected_subchannel;
+ PickState* pick;
+ while ((pick = p->pending_picks_)) {
+ p->pending_picks_ = pick->next;
+ pick->connected_subchannel = p->selected_->connected_subchannel;
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Servicing pending pick with selected subchannel %p",
- (void*)p->selected);
+ p->selected_);
}
GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
}
@@ -494,9 +537,9 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
// Case 1: Only set state to TRANSIENT_FAILURE if we've tried
// all subchannels.
if (sd->subchannel_list->checking_subchannel == 0 &&
- sd->subchannel_list == p->subchannel_list) {
+ sd->subchannel_list == p->subchannel_list_) {
grpc_connectivity_state_set(
- &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_REF(error), "connecting_transient_failure");
}
// Reuses the connectivity refs from the previous watch.
@@ -506,8 +549,8 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE: {
// Only update connectivity state in case 1.
- if (sd->subchannel_list == p->subchannel_list) {
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_CONNECTING,
+ if (sd->subchannel_list == p->subchannel_list_) {
+ grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_REF(error),
"connecting_changed");
}
@@ -520,51 +563,29 @@ static void pf_connectivity_changed_locked(void* arg, grpc_error* error) {
}
}
-static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = {
- pf_destroy,
- pf_shutdown_locked,
- pf_pick_locked,
- pf_cancel_pick_locked,
- pf_cancel_picks_locked,
- pf_ping_one_locked,
- pf_exit_idle_locked,
- pf_check_connectivity_locked,
- pf_notify_on_state_change_locked,
- pf_update_locked};
-
-static void pick_first_factory_ref(grpc_lb_policy_factory* factory) {}
-
-static void pick_first_factory_unref(grpc_lb_policy_factory* factory) {}
-
-static grpc_lb_policy* create_pick_first(grpc_lb_policy_factory* factory,
- grpc_lb_policy_args* args) {
- GPR_ASSERT(args->client_channel_factory != nullptr);
- pick_first_lb_policy* p =
- static_cast<pick_first_lb_policy*>(gpr_zalloc(sizeof(*p)));
- if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_DEBUG, "Pick First %p created.", (void*)p);
- }
- pf_update_locked(&p->base, args);
- grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable, args->combiner);
- grpc_subchannel_index_ref();
- return &p->base;
-}
+//
+// factory
+//
-static const grpc_lb_policy_factory_vtable pick_first_factory_vtable = {
- pick_first_factory_ref, pick_first_factory_unref, create_pick_first,
- "pick_first"};
+class PickFirstFactory : public LoadBalancingPolicyFactory {
+ public:
+ OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+ const LoadBalancingPolicy::Args& args) const override {
+ return OrphanablePtr<LoadBalancingPolicy>(New<PickFirst>(args));
+ }
-static grpc_lb_policy_factory pick_first_lb_policy_factory = {
- &pick_first_factory_vtable};
+ const char* name() const override { return "pick_first"; }
+};
-static grpc_lb_policy_factory* pick_first_lb_factory_create() {
- return &pick_first_lb_policy_factory;
-}
+} // namespace
-/* Plugin registration */
+} // namespace grpc_core
void grpc_lb_policy_pick_first_init() {
- grpc_register_lb_policy(pick_first_lb_factory_create());
+ grpc_core::LoadBalancingPolicyRegistry::Builder::
+ RegisterLoadBalancingPolicyFactory(
+ grpc_core::UniquePtr<grpc_core::LoadBalancingPolicyFactory>(
+ grpc_core::New<grpc_core::PickFirstFactory>()));
}
void grpc_lb_policy_pick_first_shutdown() {}
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index b5b4c44ef1..7ef7b0f6fc 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -24,6 +24,8 @@
* updates. Note however that updates will start picking from the beginning of
* the updated list. */
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
@@ -40,34 +42,94 @@
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/static_metadata.h"
-grpc_core::TraceFlag grpc_lb_round_robin_trace(false, "round_robin");
+namespace grpc_core {
+
+TraceFlag grpc_lb_round_robin_trace(false, "round_robin");
+
+namespace {
+
+//
+// round_robin LB policy
+//
+
+class RoundRobin : public LoadBalancingPolicy {
+ public:
+ explicit RoundRobin(const Args& args);
+
+ void UpdateLocked(const grpc_channel_args& args) override;
+ bool PickLocked(PickState* pick) override;
+ void CancelPickLocked(PickState* pick, grpc_error* error) override;
+ void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) override;
+ void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
+ grpc_closure* closure) override;
+ grpc_connectivity_state CheckConnectivityLocked(
+ grpc_error** connectivity_error) override;
+ void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
+ void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
+ void ExitIdleLocked() override;
-typedef struct round_robin_lb_policy {
- /** base policy: must be first */
- grpc_lb_policy base;
+ private:
+ ~RoundRobin();
- grpc_lb_subchannel_list* subchannel_list;
+ void ShutdownLocked() override;
+ void StartPickingLocked();
+ size_t GetNextReadySubchannelIndexLocked();
+ void UpdateLastReadySubchannelIndexLocked(size_t last_ready_index);
+ void UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
+ grpc_error* error);
+
+ static void OnConnectivityChangedLocked(void* arg, grpc_error* error);
+
+ void SubchannelListRefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason);
+ void SubchannelListUnrefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason);
+
+ /** list of subchannels */
+ grpc_lb_subchannel_list* subchannel_list_ = nullptr;
/** have we started picking? */
- bool started_picking;
+ bool started_picking_ = false;
/** are we shutting down? */
- bool shutdown;
+ bool shutdown_ = false;
/** List of picks that are waiting on connectivity */
- grpc_lb_policy_pick_state* pending_picks;
-
+ PickState* pending_picks_ = nullptr;
/** our connectivity state tracker */
- grpc_connectivity_state_tracker state_tracker;
-
+ grpc_connectivity_state_tracker state_tracker_;
/** Index into subchannels for last pick. */
- size_t last_ready_subchannel_index;
-
+ size_t last_ready_subchannel_index_ = 0;
/** Latest version of the subchannel list.
* Subchannel connectivity callbacks will only promote updated subchannel
* lists if they equal \a latest_pending_subchannel_list. In other words,
* racing callbacks that reference outdated subchannel lists won't perform any
* update. */
- grpc_lb_subchannel_list* latest_pending_subchannel_list;
-} round_robin_lb_policy;
+ grpc_lb_subchannel_list* latest_pending_subchannel_list_ = nullptr;
+};
+
+RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
+ GPR_ASSERT(args.client_channel_factory != nullptr);
+ grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
+ "round_robin");
+ UpdateLocked(*args.args);
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "[RR %p] Created with %" PRIuPTR " subchannels", this,
+ subchannel_list_->num_subchannels);
+ }
+ grpc_subchannel_index_ref();
+}
+
+RoundRobin::~RoundRobin() {
+ if (grpc_lb_round_robin_trace.enabled()) {
+ gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy", this);
+ }
+ GPR_ASSERT(subchannel_list_ == nullptr);
+ GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
+ GPR_ASSERT(pending_picks_ == nullptr);
+ grpc_connectivity_state_destroy(&state_tracker_);
+ grpc_subchannel_index_unref();
+}
/** Returns the index into p->subchannel_list->subchannels of the next
* subchannel in READY state, or p->subchannel_list->num_subchannels if no
@@ -75,195 +137,190 @@ typedef struct round_robin_lb_policy {
*
* Note that this function does *not* update p->last_ready_subchannel_index.
* The caller must do that if it returns a pick. */
-static size_t get_next_ready_subchannel_index_locked(
- const round_robin_lb_policy* p) {
- GPR_ASSERT(p->subchannel_list != nullptr);
+size_t RoundRobin::GetNextReadySubchannelIndexLocked() {
+ GPR_ASSERT(subchannel_list_ != nullptr);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO,
- "[RR %p] getting next ready subchannel (out of %lu), "
- "last_ready_subchannel_index=%lu",
- (void*)p,
- static_cast<unsigned long>(p->subchannel_list->num_subchannels),
- static_cast<unsigned long>(p->last_ready_subchannel_index));
- }
- for (size_t i = 0; i < p->subchannel_list->num_subchannels; ++i) {
- const size_t index = (i + p->last_ready_subchannel_index + 1) %
- p->subchannel_list->num_subchannels;
+ "[RR %p] getting next ready subchannel (out of %" PRIuPTR
+ "), "
+ "last_ready_subchannel_index=%" PRIuPTR,
+ this, subchannel_list_->num_subchannels,
+ last_ready_subchannel_index_);
+ }
+ for (size_t i = 0; i < subchannel_list_->num_subchannels; ++i) {
+ const size_t index = (i + last_ready_subchannel_index_ + 1) %
+ subchannel_list_->num_subchannels;
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
GPR_DEBUG,
- "[RR %p] checking subchannel %p, subchannel_list %p, index %lu: "
- "state=%s",
- (void*)p, (void*)p->subchannel_list->subchannels[index].subchannel,
- (void*)p->subchannel_list, static_cast<unsigned long>(index),
+ "[RR %p] checking subchannel %p, subchannel_list %p, index %" PRIuPTR
+ ": state=%s",
+ this, subchannel_list_->subchannels[index].subchannel,
+ subchannel_list_, index,
grpc_connectivity_state_name(
- p->subchannel_list->subchannels[index].curr_connectivity_state));
+ subchannel_list_->subchannels[index].curr_connectivity_state));
}
- if (p->subchannel_list->subchannels[index].curr_connectivity_state ==
+ if (subchannel_list_->subchannels[index].curr_connectivity_state ==
GRPC_CHANNEL_READY) {
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
- "[RR %p] found next ready subchannel (%p) at index %lu of "
- "subchannel_list %p",
- (void*)p,
- (void*)p->subchannel_list->subchannels[index].subchannel,
- static_cast<unsigned long>(index), (void*)p->subchannel_list);
+ "[RR %p] found next ready subchannel (%p) at index %" PRIuPTR
+ " of subchannel_list %p",
+ this, subchannel_list_->subchannels[index].subchannel, index,
+ subchannel_list_);
}
return index;
}
}
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] no subchannels in ready state", (void*)p);
+ gpr_log(GPR_DEBUG, "[RR %p] no subchannels in ready state", this);
}
- return p->subchannel_list->num_subchannels;
+ return subchannel_list_->num_subchannels;
}
-// Sets p->last_ready_subchannel_index to last_ready_index.
-static void update_last_ready_subchannel_index_locked(round_robin_lb_policy* p,
- size_t last_ready_index) {
- GPR_ASSERT(last_ready_index < p->subchannel_list->num_subchannels);
- p->last_ready_subchannel_index = last_ready_index;
+// Sets last_ready_subchannel_index_ to last_ready_index.
+void RoundRobin::UpdateLastReadySubchannelIndexLocked(size_t last_ready_index) {
+ GPR_ASSERT(last_ready_index < subchannel_list_->num_subchannels);
+ last_ready_subchannel_index_ = last_ready_index;
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
- "[RR %p] setting last_ready_subchannel_index=%lu (SC %p, CSC %p)",
- (void*)p, static_cast<unsigned long>(last_ready_index),
- (void*)p->subchannel_list->subchannels[last_ready_index].subchannel,
- (void*)p->subchannel_list->subchannels[last_ready_index]
+ "[RR %p] setting last_ready_subchannel_index=%" PRIuPTR
+ " (SC %p, CSC %p)",
+ this, last_ready_index,
+ subchannel_list_->subchannels[last_ready_index].subchannel,
+ subchannel_list_->subchannels[last_ready_index]
.connected_subchannel.get());
}
}
-static void rr_destroy(grpc_lb_policy* pol) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Destroying Round Robin policy at %p",
- (void*)pol, (void*)pol);
+void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
+ PickState* pick;
+ while ((pick = pending_picks_) != nullptr) {
+ pending_picks_ = pick->next;
+ if (new_policy->PickLocked(pick)) {
+ // Synchronous return, schedule closure.
+ GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
+ }
}
- GPR_ASSERT(p->subchannel_list == nullptr);
- GPR_ASSERT(p->latest_pending_subchannel_list == nullptr);
- grpc_connectivity_state_destroy(&p->state_tracker);
- grpc_subchannel_index_unref();
- gpr_free(p);
}
-static void rr_shutdown_locked(grpc_lb_policy* pol,
- grpc_lb_policy* new_policy) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
+void RoundRobin::ShutdownLocked() {
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Shutting down", p);
- }
- p->shutdown = true;
- grpc_lb_policy_pick_state* pick;
- while ((pick = p->pending_picks) != nullptr) {
- p->pending_picks = pick->next;
- if (new_policy != nullptr) {
- // Hand off to new LB policy.
- if (grpc_lb_policy_pick_locked(new_policy, pick)) {
- // Synchronous return; schedule callback.
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
- }
- } else {
- pick->connected_subchannel.reset();
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
- }
+ gpr_log(GPR_DEBUG, "[RR %p] Shutting down", this);
+ }
+ shutdown_ = true;
+ PickState* pick;
+ while ((pick = pending_picks_) != nullptr) {
+ pending_picks_ = pick->next;
+ pick->connected_subchannel.reset();
+ GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_REF(error));
}
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_SHUTDOWN,
+ grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "rr_shutdown");
- if (p->subchannel_list != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
+ if (subchannel_list_ != nullptr) {
+ grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
"sl_shutdown_rr_shutdown");
- p->subchannel_list = nullptr;
+ subchannel_list_ = nullptr;
}
- if (p->latest_pending_subchannel_list != nullptr) {
+ if (latest_pending_subchannel_list_ != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
- p->latest_pending_subchannel_list, "sl_shutdown_pending_rr_shutdown");
- p->latest_pending_subchannel_list = nullptr;
+ latest_pending_subchannel_list_, "sl_shutdown_pending_rr_shutdown");
+ latest_pending_subchannel_list_ = nullptr;
}
- grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_round_robin_trace,
- GRPC_ERROR_CANCELLED);
+ TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_CANCELLED);
GRPC_ERROR_UNREF(error);
}
-static void rr_cancel_pick_locked(grpc_lb_policy* pol,
- grpc_lb_policy_pick_state* pick,
- grpc_error* error) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- grpc_lb_policy_pick_state* pp = p->pending_picks;
- p->pending_picks = nullptr;
+void RoundRobin::CancelPickLocked(PickState* pick, grpc_error* error) {
+ PickState* pp = pending_picks_;
+ pending_picks_ = nullptr;
while (pp != nullptr) {
- grpc_lb_policy_pick_state* next = pp->next;
+ PickState* next = pp->next;
if (pp == pick) {
pick->connected_subchannel.reset();
GRPC_CLOSURE_SCHED(pick->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick cancelled", &error, 1));
+ "Pick Cancelled", &error, 1));
} else {
- pp->next = p->pending_picks;
- p->pending_picks = pp;
+ pp->next = pending_picks_;
+ pending_picks_ = pp;
}
pp = next;
}
GRPC_ERROR_UNREF(error);
}
-static void rr_cancel_picks_locked(grpc_lb_policy* pol,
- uint32_t initial_metadata_flags_mask,
- uint32_t initial_metadata_flags_eq,
- grpc_error* error) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- grpc_lb_policy_pick_state* pick = p->pending_picks;
- p->pending_picks = nullptr;
+void RoundRobin::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
+ uint32_t initial_metadata_flags_eq,
+ grpc_error* error) {
+ PickState* pick = pending_picks_;
+ pending_picks_ = nullptr;
while (pick != nullptr) {
- grpc_lb_policy_pick_state* next = pick->next;
+ PickState* next = pick->next;
if ((pick->initial_metadata_flags & initial_metadata_flags_mask) ==
initial_metadata_flags_eq) {
pick->connected_subchannel.reset();
GRPC_CLOSURE_SCHED(pick->on_complete,
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
- "Pick cancelled", &error, 1));
+ "Pick Cancelled", &error, 1));
} else {
- pick->next = p->pending_picks;
- p->pending_picks = pick;
+ pick->next = pending_picks_;
+ pending_picks_ = pick;
}
pick = next;
}
GRPC_ERROR_UNREF(error);
}
-static void start_picking_locked(round_robin_lb_policy* p) {
- p->started_picking = true;
- for (size_t i = 0; i < p->subchannel_list->num_subchannels; i++) {
- if (p->subchannel_list->subchannels[i].subchannel != nullptr) {
- grpc_lb_subchannel_list_ref_for_connectivity_watch(p->subchannel_list,
- "connectivity_watch");
+void RoundRobin::SubchannelListRefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason) {
+ // TODO(roth): We currently track this ref manually. Once the new
+ // ClosureRef API is ready and the subchannel_list code has been
+ // converted to a C++ API, find a way to hold the RefCountedPtr<>
+ // somewhere (maybe in the subchannel_data object) instead of doing
+ // this manually.
+ auto self = Ref(DEBUG_LOCATION, reason);
+ self.release();
+ grpc_lb_subchannel_list_ref(subchannel_list, reason);
+}
+
+void RoundRobin::SubchannelListUnrefForConnectivityWatch(
+ grpc_lb_subchannel_list* subchannel_list, const char* reason) {
+ Unref(DEBUG_LOCATION, reason);
+ grpc_lb_subchannel_list_unref(subchannel_list, reason);
+}
+
+void RoundRobin::StartPickingLocked() {
+ started_picking_ = true;
+ for (size_t i = 0; i < subchannel_list_->num_subchannels; i++) {
+ if (subchannel_list_->subchannels[i].subchannel != nullptr) {
+ SubchannelListRefForConnectivityWatch(subchannel_list_,
+ "connectivity_watch");
grpc_lb_subchannel_data_start_connectivity_watch(
- &p->subchannel_list->subchannels[i]);
+ &subchannel_list_->subchannels[i]);
}
}
}
-static void rr_exit_idle_locked(grpc_lb_policy* pol) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- if (!p->started_picking) {
- start_picking_locked(p);
+void RoundRobin::ExitIdleLocked() {
+ if (!started_picking_) {
+ StartPickingLocked();
}
}
-static int rr_pick_locked(grpc_lb_policy* pol,
- grpc_lb_policy_pick_state* pick) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
+bool RoundRobin::PickLocked(PickState* pick) {
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", pol,
- p->shutdown);
+ gpr_log(GPR_DEBUG, "[RR %p] Trying to pick (shutdown: %d)", this,
+ shutdown_);
}
- GPR_ASSERT(!p->shutdown);
- if (p->subchannel_list != nullptr) {
- const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
- if (next_ready_index < p->subchannel_list->num_subchannels) {
+ GPR_ASSERT(!shutdown_);
+ if (subchannel_list_ != nullptr) {
+ const size_t next_ready_index = GetNextReadySubchannelIndexLocked();
+ if (next_ready_index < subchannel_list_->num_subchannels) {
/* readily available, report right away */
grpc_lb_subchannel_data* sd =
- &p->subchannel_list->subchannels[next_ready_index];
+ &subchannel_list_->subchannels[next_ready_index];
pick->connected_subchannel = sd->connected_subchannel;
if (pick->user_data != nullptr) {
*pick->user_data = sd->user_data;
@@ -273,24 +330,24 @@ static int rr_pick_locked(grpc_lb_policy* pol,
GPR_DEBUG,
"[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
"index %" PRIuPTR ")",
- p, sd->subchannel, pick->connected_subchannel.get(),
+ this, sd->subchannel, pick->connected_subchannel.get(),
sd->subchannel_list, next_ready_index);
}
/* only advance the last picked pointer if the selection was used */
- update_last_ready_subchannel_index_locked(p, next_ready_index);
- return 1;
+ UpdateLastReadySubchannelIndexLocked(next_ready_index);
+ return true;
}
}
/* no pick currently available. Save for later in list of pending picks */
- if (!p->started_picking) {
- start_picking_locked(p);
+ if (!started_picking_) {
+ StartPickingLocked();
}
- pick->next = p->pending_picks;
- p->pending_picks = pick;
- return 0;
+ pick->next = pending_picks_;
+ pending_picks_ = pick;
+ return false;
}
-static void update_state_counters_locked(grpc_lb_subchannel_data* sd) {
+void UpdateStateCountersLocked(grpc_lb_subchannel_data* sd) {
grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
GPR_ASSERT(sd->prev_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_SHUTDOWN);
@@ -318,8 +375,8 @@ static void update_state_counters_locked(grpc_lb_subchannel_data* sd) {
* (the grpc_lb_subchannel_data associated with the updated subchannel) and the
* subchannel list \a sd belongs to (sd->subchannel_list). \a error will be used
* only if the policy transitions to state TRANSIENT_FAILURE. */
-static void update_lb_connectivity_status_locked(grpc_lb_subchannel_data* sd,
- grpc_error* error) {
+void RoundRobin::UpdateConnectivityStatusLocked(grpc_lb_subchannel_data* sd,
+ grpc_error* error) {
/* In priority order. The first rule to match terminates the search (ie, if we
* are on rule n, all previous rules were unfulfilled).
*
@@ -335,64 +392,61 @@ static void update_lb_connectivity_status_locked(grpc_lb_subchannel_data* sd,
* subchannel_list->num_subchannels.
*/
grpc_lb_subchannel_list* subchannel_list = sd->subchannel_list;
- round_robin_lb_policy* p =
- reinterpret_cast<round_robin_lb_policy*>(subchannel_list->policy);
GPR_ASSERT(sd->curr_connectivity_state != GRPC_CHANNEL_IDLE);
if (subchannel_list->num_ready > 0) {
/* 1) READY */
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_READY,
+ grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_READY,
GRPC_ERROR_NONE, "rr_ready");
} else if (sd->curr_connectivity_state == GRPC_CHANNEL_CONNECTING) {
/* 2) CONNECTING */
- grpc_connectivity_state_set(&p->state_tracker, GRPC_CHANNEL_CONNECTING,
+ grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_CONNECTING,
GRPC_ERROR_NONE, "rr_connecting");
} else if (subchannel_list->num_transient_failures ==
subchannel_list->num_subchannels) {
/* 3) TRANSIENT_FAILURE */
- grpc_connectivity_state_set(&p->state_tracker,
- GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_REF(error), "rr_transient_failure");
+ grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ GRPC_ERROR_REF(error),
+ "rr_exhausted_subchannels");
}
GRPC_ERROR_UNREF(error);
}
-static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
- grpc_lb_subchannel_data* sd = static_cast<grpc_lb_subchannel_data*>(arg);
- round_robin_lb_policy* p =
- reinterpret_cast<round_robin_lb_policy*>(sd->subchannel_list->policy);
+void RoundRobin::OnConnectivityChangedLocked(void* arg, grpc_error* error) {
+ grpc_lb_subchannel_data* sd = reinterpret_cast<grpc_lb_subchannel_data*>(arg);
+ RoundRobin* p = reinterpret_cast<RoundRobin*>(sd->subchannel_list->policy);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(
GPR_DEBUG,
"[RR %p] connectivity changed for subchannel %p, subchannel_list %p: "
"prev_state=%s new_state=%s p->shutdown=%d "
"sd->subchannel_list->shutting_down=%d error=%s",
- (void*)p, (void*)sd->subchannel, (void*)sd->subchannel_list,
+ p, sd->subchannel, sd->subchannel_list,
grpc_connectivity_state_name(sd->prev_connectivity_state),
grpc_connectivity_state_name(sd->pending_connectivity_state_unsafe),
- p->shutdown, sd->subchannel_list->shutting_down,
+ p->shutdown_, sd->subchannel_list->shutting_down,
grpc_error_string(error));
}
GPR_ASSERT(sd->subchannel != nullptr);
// If the policy is shutting down, unref and return.
- if (p->shutdown) {
+ if (p->shutdown_) {
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "rr_shutdown");
- grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
- "rr_shutdown");
+ p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
+ "rr_shutdown");
return;
}
// If the subchannel list is shutting down, stop watching.
if (sd->subchannel_list->shutting_down || error == GRPC_ERROR_CANCELLED) {
grpc_lb_subchannel_data_stop_connectivity_watch(sd);
grpc_lb_subchannel_data_unref_subchannel(sd, "rr_sl_shutdown");
- grpc_lb_subchannel_list_unref_for_connectivity_watch(sd->subchannel_list,
- "rr_sl_shutdown");
+ p->SubchannelListUnrefForConnectivityWatch(sd->subchannel_list,
+ "rr_sl_shutdown");
return;
}
// If we're still here, the notification must be for a subchannel in
// either the current or latest pending subchannel lists.
- GPR_ASSERT(sd->subchannel_list == p->subchannel_list ||
- sd->subchannel_list == p->latest_pending_subchannel_list);
+ GPR_ASSERT(sd->subchannel_list == p->subchannel_list_ ||
+ sd->subchannel_list == p->latest_pending_subchannel_list_);
GPR_ASSERT(sd->pending_connectivity_state_unsafe != GRPC_CHANNEL_SHUTDOWN);
// Now that we're inside the combiner, copy the pending connectivity
// state (which was set by the connectivity state watcher) to
@@ -409,8 +463,7 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
"Requesting re-resolution",
p, sd->subchannel);
}
- grpc_lb_policy_try_reresolve(&p->base, &grpc_lb_round_robin_trace,
- GRPC_ERROR_NONE);
+ p->TryReresolutionLocked(&grpc_lb_round_robin_trace, GRPC_ERROR_NONE);
break;
}
case GRPC_CHANNEL_READY: {
@@ -418,49 +471,47 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
sd->connected_subchannel =
grpc_subchannel_get_connected_subchannel(sd->subchannel);
}
- if (sd->subchannel_list != p->subchannel_list) {
- // promote sd->subchannel_list to p->subchannel_list.
+ if (sd->subchannel_list != p->subchannel_list_) {
+ // promote sd->subchannel_list to p->subchannel_list_.
// sd->subchannel_list must be equal to
- // p->latest_pending_subchannel_list because we have already filtered
+ // p->latest_pending_subchannel_list_ because we have already filtered
// for sds belonging to outdated subchannel lists.
- GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list);
+ GPR_ASSERT(sd->subchannel_list == p->latest_pending_subchannel_list_);
GPR_ASSERT(!sd->subchannel_list->shutting_down);
if (grpc_lb_round_robin_trace.enabled()) {
- const unsigned long num_subchannels =
- p->subchannel_list != nullptr
- ? static_cast<unsigned long>(
- p->subchannel_list->num_subchannels)
+ const size_t num_subchannels =
+ p->subchannel_list_ != nullptr
+ ? p->subchannel_list_->num_subchannels
: 0;
gpr_log(GPR_DEBUG,
- "[RR %p] phasing out subchannel list %p (size %lu) in favor "
- "of %p (size %lu)",
- p, p->subchannel_list, num_subchannels, sd->subchannel_list,
+ "[RR %p] phasing out subchannel list %p (size %" PRIuPTR
+ ") in favor of %p (size %" PRIuPTR ")",
+ p, p->subchannel_list_, num_subchannels, sd->subchannel_list,
num_subchannels);
}
- if (p->subchannel_list != nullptr) {
+ if (p->subchannel_list_ != nullptr) {
// dispose of the current subchannel_list
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
+ grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list_,
"sl_phase_out_shutdown");
}
- p->subchannel_list = p->latest_pending_subchannel_list;
- p->latest_pending_subchannel_list = nullptr;
+ p->subchannel_list_ = p->latest_pending_subchannel_list_;
+ p->latest_pending_subchannel_list_ = nullptr;
}
/* at this point we know there's at least one suitable subchannel. Go
* ahead and pick one and notify the pending suitors in
- * p->pending_picks. This preemptively replicates rr_pick()'s actions.
- */
- const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
- GPR_ASSERT(next_ready_index < p->subchannel_list->num_subchannels);
+ * p->pending_picks. This preemptively replicates rr_pick()'s actions. */
+ const size_t next_ready_index = p->GetNextReadySubchannelIndexLocked();
+ GPR_ASSERT(next_ready_index < p->subchannel_list_->num_subchannels);
grpc_lb_subchannel_data* selected =
- &p->subchannel_list->subchannels[next_ready_index];
- if (p->pending_picks != nullptr) {
+ &p->subchannel_list_->subchannels[next_ready_index];
+ if (p->pending_picks_ != nullptr) {
// if the selected subchannel is going to be used for the pending
// picks, update the last picked pointer
- update_last_ready_subchannel_index_locked(p, next_ready_index);
+ p->UpdateLastReadySubchannelIndexLocked(next_ready_index);
}
- grpc_lb_policy_pick_state* pick;
- while ((pick = p->pending_picks)) {
- p->pending_picks = pick->next;
+ PickState* pick;
+ while ((pick = p->pending_picks_)) {
+ p->pending_picks_ = pick->next;
pick->connected_subchannel = selected->connected_subchannel;
if (pick->user_data != nullptr) {
*pick->user_data = selected->user_data;
@@ -468,10 +519,9 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[RR %p] Fulfilling pending pick. Target <-- subchannel %p "
- "(subchannel_list %p, index %lu)",
- (void*)p, (void*)selected->subchannel,
- (void*)p->subchannel_list,
- static_cast<unsigned long>(next_ready_index));
+ "(subchannel_list %p, index %" PRIuPTR ")",
+ p, selected->subchannel, p->subchannel_list_,
+ next_ready_index);
}
GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
}
@@ -482,40 +532,34 @@ static void rr_connectivity_changed_locked(void* arg, grpc_error* error) {
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_IDLE:; // fallthrough
}
- // Update state counters and new overall state.
- update_state_counters_locked(sd);
+ // Update state counters.
+ UpdateStateCountersLocked(sd);
// Only update connectivity based on the selected subchannel list.
- if (sd->subchannel_list == p->subchannel_list) {
- update_lb_connectivity_status_locked(sd, GRPC_ERROR_REF(error));
+ if (sd->subchannel_list == p->subchannel_list_) {
+ p->UpdateConnectivityStatusLocked(sd, GRPC_ERROR_REF(error));
}
// Renew notification.
grpc_lb_subchannel_data_start_connectivity_watch(sd);
}
-static grpc_connectivity_state rr_check_connectivity_locked(
- grpc_lb_policy* pol, grpc_error** error) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- return grpc_connectivity_state_get(&p->state_tracker, error);
+grpc_connectivity_state RoundRobin::CheckConnectivityLocked(
+ grpc_error** error) {
+ return grpc_connectivity_state_get(&state_tracker_, error);
}
-static void rr_notify_on_state_change_locked(grpc_lb_policy* pol,
- grpc_connectivity_state* current,
- grpc_closure* notify) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- grpc_connectivity_state_notify_on_state_change(&p->state_tracker, current,
+void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
+ grpc_closure* notify) {
+ grpc_connectivity_state_notify_on_state_change(&state_tracker_, current,
notify);
}
-static void rr_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
+void RoundRobin::PingOneLocked(grpc_closure* on_initiate,
grpc_closure* on_ack) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(pol);
- const size_t next_ready_index = get_next_ready_subchannel_index_locked(p);
- if (next_ready_index < p->subchannel_list->num_subchannels) {
+ const size_t next_ready_index = GetNextReadySubchannelIndexLocked();
+ if (next_ready_index < subchannel_list_->num_subchannels) {
grpc_lb_subchannel_data* selected =
- &p->subchannel_list->subchannels[next_ready_index];
- grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> target =
- selected->connected_subchannel;
- target->Ping(on_initiate, on_ack);
+ &subchannel_list_->subchannels[next_ready_index];
+ selected->connected_subchannel->Ping(on_initiate, on_ack);
} else {
GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Round Robin not connected"));
@@ -524,45 +568,41 @@ static void rr_ping_one_locked(grpc_lb_policy* pol, grpc_closure* on_initiate,
}
}
-static void rr_update_locked(grpc_lb_policy* policy,
- const grpc_lb_policy_args* args) {
- round_robin_lb_policy* p = reinterpret_cast<round_robin_lb_policy*>(policy);
- const grpc_arg* arg =
- grpc_channel_args_find(args->args, GRPC_ARG_LB_ADDRESSES);
+void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
+ const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", p);
+ gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
// If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
// Otherwise, keep using the current subchannel list (ignore this update).
- if (p->subchannel_list == nullptr) {
+ if (subchannel_list_ == nullptr) {
grpc_connectivity_state_set(
- &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Missing update in args"),
"rr_update_missing");
}
return;
}
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_lb_addresses* addresses = (grpc_lb_addresses*)arg->value.pointer.p;
if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] received update with %" PRIuPTR " addresses", p,
- addresses->num_addresses);
+ gpr_log(GPR_DEBUG, "[RR %p] received update with %" PRIuPTR " addresses",
+ this, addresses->num_addresses);
}
grpc_lb_subchannel_list* subchannel_list = grpc_lb_subchannel_list_create(
- &p->base, &grpc_lb_round_robin_trace, addresses, args,
- rr_connectivity_changed_locked);
+ this, &grpc_lb_round_robin_trace, addresses, combiner(),
+ client_channel_factory(), args, &RoundRobin::OnConnectivityChangedLocked);
if (subchannel_list->num_subchannels == 0) {
grpc_connectivity_state_set(
- &p->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
+ &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
"rr_update_empty");
- if (p->subchannel_list != nullptr) {
- grpc_lb_subchannel_list_shutdown_and_unref(p->subchannel_list,
+ if (subchannel_list_ != nullptr) {
+ grpc_lb_subchannel_list_shutdown_and_unref(subchannel_list_,
"sl_shutdown_empty_update");
}
- p->subchannel_list = subchannel_list; // empty list
+ subchannel_list_ = subchannel_list; // empty list
return;
}
- if (p->started_picking) {
+ if (started_picking_) {
for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
const grpc_connectivity_state subchannel_state =
grpc_subchannel_check_connectivity(
@@ -587,87 +627,61 @@ static void rr_update_locked(grpc_lb_policy* policy,
++subchannel_list->num_transient_failures;
}
}
- if (p->latest_pending_subchannel_list != nullptr) {
+ if (latest_pending_subchannel_list_ != nullptr) {
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_DEBUG,
"[RR %p] Shutting down latest pending subchannel list %p, "
"about to be replaced by newer latest %p",
- (void*)p, (void*)p->latest_pending_subchannel_list,
- (void*)subchannel_list);
+ this, latest_pending_subchannel_list_, subchannel_list);
}
grpc_lb_subchannel_list_shutdown_and_unref(
- p->latest_pending_subchannel_list, "sl_outdated");
+ latest_pending_subchannel_list_, "sl_outdated");
}
- p->latest_pending_subchannel_list = subchannel_list;
+ latest_pending_subchannel_list_ = subchannel_list;
for (size_t i = 0; i < subchannel_list->num_subchannels; ++i) {
/* Watch every new subchannel. A subchannel list becomes active the
* moment one of its subchannels is READY. At that moment, we swap
* p->subchannel_list for sd->subchannel_list, provided the subchannel
* list is still valid (ie, isn't shutting down) */
- grpc_lb_subchannel_list_ref_for_connectivity_watch(subchannel_list,
- "connectivity_watch");
+ SubchannelListRefForConnectivityWatch(subchannel_list,
+ "connectivity_watch");
grpc_lb_subchannel_data_start_connectivity_watch(
&subchannel_list->subchannels[i]);
}
} else {
// The policy isn't picking yet. Save the update for later, disposing of
// previous version if any.
- if (p->subchannel_list != nullptr) {
+ if (subchannel_list_ != nullptr) {
grpc_lb_subchannel_list_shutdown_and_unref(
- p->subchannel_list, "rr_update_before_started_picking");
+ subchannel_list_, "rr_update_before_started_picking");
}
- p->subchannel_list = subchannel_list;
+ subchannel_list_ = subchannel_list;
}
}
-static const grpc_lb_policy_vtable round_robin_lb_policy_vtable = {
- rr_destroy,
- rr_shutdown_locked,
- rr_pick_locked,
- rr_cancel_pick_locked,
- rr_cancel_picks_locked,
- rr_ping_one_locked,
- rr_exit_idle_locked,
- rr_check_connectivity_locked,
- rr_notify_on_state_change_locked,
- rr_update_locked};
-
-static void round_robin_factory_ref(grpc_lb_policy_factory* factory) {}
-
-static void round_robin_factory_unref(grpc_lb_policy_factory* factory) {}
-
-static grpc_lb_policy* round_robin_create(grpc_lb_policy_factory* factory,
- grpc_lb_policy_args* args) {
- GPR_ASSERT(args->client_channel_factory != nullptr);
- round_robin_lb_policy* p =
- static_cast<round_robin_lb_policy*>(gpr_zalloc(sizeof(*p)));
- grpc_lb_policy_init(&p->base, &round_robin_lb_policy_vtable, args->combiner);
- grpc_subchannel_index_ref();
- grpc_connectivity_state_init(&p->state_tracker, GRPC_CHANNEL_IDLE,
- "round_robin");
- rr_update_locked(&p->base, args);
- if (grpc_lb_round_robin_trace.enabled()) {
- gpr_log(GPR_DEBUG, "[RR %p] Created with %lu subchannels", (void*)p,
- static_cast<unsigned long>(p->subchannel_list->num_subchannels));
- }
- return &p->base;
-}
+//
+// factory
+//
-static const grpc_lb_policy_factory_vtable round_robin_factory_vtable = {
- round_robin_factory_ref, round_robin_factory_unref, round_robin_create,
- "round_robin"};
+class RoundRobinFactory : public LoadBalancingPolicyFactory {
+ public:
+ OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+ const LoadBalancingPolicy::Args& args) const override {
+ return OrphanablePtr<LoadBalancingPolicy>(New<RoundRobin>(args));
+ }
-static grpc_lb_policy_factory round_robin_lb_policy_factory = {
- &round_robin_factory_vtable};
+ const char* name() const override { return "round_robin"; }
+};
-static grpc_lb_policy_factory* round_robin_lb_factory_create() {
- return &round_robin_lb_policy_factory;
-}
+} // namespace
-/* Plugin registration */
+} // namespace grpc_core
void grpc_lb_policy_round_robin_init() {
- grpc_register_lb_policy(round_robin_lb_factory_create());
+ grpc_core::LoadBalancingPolicyRegistry::Builder::
+ RegisterLoadBalancingPolicyFactory(
+ grpc_core::UniquePtr<grpc_core::LoadBalancingPolicyFactory>(
+ grpc_core::New<grpc_core::RoundRobinFactory>()));
}
void grpc_lb_policy_round_robin_shutdown() {}
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
index e35c5e8db3..79cb64c6c6 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
@@ -67,7 +69,7 @@ void grpc_lb_subchannel_data_start_connectivity_watch(
}
sd->connectivity_notification_pending = true;
grpc_subchannel_notify_on_state_change(
- sd->subchannel, sd->subchannel_list->policy->interested_parties,
+ sd->subchannel, sd->subchannel_list->policy->interested_parties(),
&sd->pending_connectivity_state_unsafe,
&sd->connectivity_changed_closure);
}
@@ -88,9 +90,10 @@ void grpc_lb_subchannel_data_stop_connectivity_watch(
}
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
- grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
- const grpc_lb_addresses* addresses, const grpc_lb_policy_args* args,
- grpc_iomgr_cb_func connectivity_changed_cb) {
+ grpc_core::LoadBalancingPolicy* p, grpc_core::TraceFlag* tracer,
+ const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ grpc_client_channel_factory* client_channel_factory,
+ const grpc_channel_args& args, grpc_iomgr_cb_func connectivity_changed_cb) {
grpc_lb_subchannel_list* subchannel_list =
static_cast<grpc_lb_subchannel_list*>(
gpr_zalloc(sizeof(*subchannel_list)));
@@ -118,12 +121,11 @@ grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
grpc_arg addr_arg =
grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
- args->args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg,
- 1);
+ &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1);
gpr_free(addr_arg.value.string);
sc_args.args = new_args;
grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel(
- args->client_channel_factory, &sc_args);
+ client_channel_factory, &sc_args);
grpc_channel_args_destroy(new_args);
if (subchannel == nullptr) {
// Subchannel could not be created.
@@ -154,7 +156,7 @@ grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
sd->subchannel = subchannel;
GRPC_CLOSURE_INIT(&sd->connectivity_changed_closure,
connectivity_changed_cb, sd,
- grpc_combiner_scheduler(args->combiner));
+ grpc_combiner_scheduler(combiner));
// We assume that the current state is IDLE. If not, we'll get a
// callback telling us that.
sd->prev_connectivity_state = GRPC_CHANNEL_IDLE;
@@ -212,18 +214,6 @@ void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
}
}
-void grpc_lb_subchannel_list_ref_for_connectivity_watch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- GRPC_LB_POLICY_REF(subchannel_list->policy, reason);
- grpc_lb_subchannel_list_ref(subchannel_list, reason);
-}
-
-void grpc_lb_subchannel_list_unref_for_connectivity_watch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason) {
- GRPC_LB_POLICY_UNREF(subchannel_list->policy, reason);
- grpc_lb_subchannel_list_unref(subchannel_list, reason);
-}
-
static void subchannel_data_cancel_connectivity_watch(
grpc_lb_subchannel_data* sd, const char* reason) {
if (sd->subchannel_list->tracer->enabled()) {
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index 91537f3afe..6889d596ac 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_SUBCHANNEL_LIST_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/debug/trace.h"
@@ -82,7 +84,7 @@ void grpc_lb_subchannel_data_stop_connectivity_watch(
struct grpc_lb_subchannel_list {
/** backpointer to owning policy */
- grpc_lb_policy* policy;
+ grpc_core::LoadBalancingPolicy* policy;
grpc_core::TraceFlag* tracer;
@@ -115,9 +117,10 @@ struct grpc_lb_subchannel_list {
};
grpc_lb_subchannel_list* grpc_lb_subchannel_list_create(
- grpc_lb_policy* p, grpc_core::TraceFlag* tracer,
- const grpc_lb_addresses* addresses, const grpc_lb_policy_args* args,
- grpc_iomgr_cb_func connectivity_changed_cb);
+ grpc_core::LoadBalancingPolicy* p, grpc_core::TraceFlag* tracer,
+ const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ grpc_client_channel_factory* client_channel_factory,
+ const grpc_channel_args& args, grpc_iomgr_cb_func connectivity_changed_cb);
void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
const char* reason);
@@ -125,13 +128,6 @@ void grpc_lb_subchannel_list_ref(grpc_lb_subchannel_list* subchannel_list,
void grpc_lb_subchannel_list_unref(grpc_lb_subchannel_list* subchannel_list,
const char* reason);
-/// Takes and releases refs needed for a connectivity notification.
-/// This includes a ref to subchannel_list and a weak ref to the LB policy.
-void grpc_lb_subchannel_list_ref_for_connectivity_watch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
-void grpc_lb_subchannel_list_unref_for_connectivity_watch(
- grpc_lb_subchannel_list* subchannel_list, const char* reason);
-
/// Mark subchannel_list as discarded. Unsubscribes all its subchannels. The
/// connectivity state notification callback will ultimately unref it.
void grpc_lb_subchannel_list_shutdown_and_unref(
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc
index f2a800b221..80646a10cc 100644
--- a/src/core/ext/filters/client_channel/lb_policy_factory.cc
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
@@ -151,17 +153,3 @@ grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
return nullptr;
return static_cast<grpc_lb_addresses*>(lb_addresses_arg->value.pointer.p);
}
-
-void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory) {
- factory->vtable->ref(factory);
-}
-
-void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory) {
- factory->vtable->unref(factory);
-}
-
-grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy(
- grpc_lb_policy_factory* factory, grpc_lb_policy_args* args) {
- if (factory == nullptr) return nullptr;
- return factory->vtable->create_lb_policy(factory, args);
-}
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h
index 9da231b657..b8bbd32072 100644
--- a/src/core/ext/filters/client_channel/lb_policy_factory.h
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/resolve_address.h"
@@ -26,21 +28,20 @@
#include "src/core/ext/filters/client_channel/lb_policy.h"
#include "src/core/ext/filters/client_channel/uri_parser.h"
+//
+// representation of an LB address
+//
+
// Channel arg key for grpc_lb_addresses.
#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
-typedef struct grpc_lb_policy_factory grpc_lb_policy_factory;
-typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable;
-
-struct grpc_lb_policy_factory {
- const grpc_lb_policy_factory_vtable* vtable;
-};
-
/** A resolved address alongside any LB related information associated with it.
* \a user_data, if not NULL, contains opaque data meant to be consumed by the
* gRPC LB policy. Note that no all LB policies support \a user_data as input.
* Those who don't will simply ignore it and will correspondingly return NULL in
* their namesake pick() output argument. */
+// TODO(roth): Once we figure out a better way of handling user_data in
+// LB policies, convert these structs to C++ classes.
typedef struct grpc_lb_address {
grpc_resolved_address address;
bool is_balancer;
@@ -101,30 +102,27 @@ grpc_arg grpc_lb_addresses_create_channel_arg(
grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
const grpc_channel_args* channel_args);
-/** Arguments passed to LB policies. */
-struct grpc_lb_policy_args {
- grpc_client_channel_factory* client_channel_factory;
- grpc_channel_args* args;
- grpc_combiner* combiner;
-};
+//
+// LB policy factory
+//
-struct grpc_lb_policy_factory_vtable {
- void (*ref)(grpc_lb_policy_factory* factory);
- void (*unref)(grpc_lb_policy_factory* factory);
+namespace grpc_core {
- /** Implementation of grpc_lb_policy_factory_create_lb_policy */
- grpc_lb_policy* (*create_lb_policy)(grpc_lb_policy_factory* factory,
- grpc_lb_policy_args* args);
+class LoadBalancingPolicyFactory {
+ public:
+ /// Returns a new LB policy instance.
+ virtual OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+ const LoadBalancingPolicy::Args& args) const GRPC_ABSTRACT;
- /** Name for the LB policy this factory implements */
- const char* name;
-};
+ /// Returns the LB policy name that this factory provides.
+ /// Caller does NOT take ownership of result.
+ virtual const char* name() const GRPC_ABSTRACT;
-void grpc_lb_policy_factory_ref(grpc_lb_policy_factory* factory);
-void grpc_lb_policy_factory_unref(grpc_lb_policy_factory* factory);
+ virtual ~LoadBalancingPolicyFactory() {}
+
+ GRPC_ABSTRACT_BASE_CLASS
+};
-/** Create a lb_policy instance. */
-grpc_lb_policy* grpc_lb_policy_factory_create_lb_policy(
- grpc_lb_policy_factory* factory, grpc_lb_policy_args* args);
+} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_FACTORY_H */
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc
index 8414504e8f..d651b1120d 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.cc
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc
@@ -16,55 +16,82 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include <string.h>
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
-#define MAX_POLICIES 10
+namespace grpc_core {
-static grpc_lb_policy_factory* g_all_of_the_lb_policies[MAX_POLICIES];
-static int g_number_of_lb_policies = 0;
+namespace {
-void grpc_lb_policy_registry_init(void) { g_number_of_lb_policies = 0; }
+class RegistryState {
+ public:
+ RegistryState() {}
-void grpc_lb_policy_registry_shutdown(void) {
- int i;
- for (i = 0; i < g_number_of_lb_policies; i++) {
- grpc_lb_policy_factory_unref(g_all_of_the_lb_policies[i]);
+ void RegisterLoadBalancingPolicyFactory(
+ UniquePtr<LoadBalancingPolicyFactory> factory) {
+ for (size_t i = 0; i < factories_.size(); ++i) {
+ GPR_ASSERT(strcmp(factories_[i]->name(), factory->name()) != 0);
+ }
+ factories_.push_back(std::move(factory));
}
-}
-void grpc_register_lb_policy(grpc_lb_policy_factory* factory) {
- int i;
- for (i = 0; i < g_number_of_lb_policies; i++) {
- GPR_ASSERT(0 != gpr_stricmp(factory->vtable->name,
- g_all_of_the_lb_policies[i]->vtable->name));
+ LoadBalancingPolicyFactory* GetLoadBalancingPolicyFactory(
+ const char* name) const {
+ for (size_t i = 0; i < factories_.size(); ++i) {
+ if (strcmp(name, factories_[i]->name()) == 0) {
+ return factories_[i].get();
+ }
+ }
+ return nullptr;
}
- GPR_ASSERT(g_number_of_lb_policies != MAX_POLICIES);
- grpc_lb_policy_factory_ref(factory);
- g_all_of_the_lb_policies[g_number_of_lb_policies++] = factory;
-}
-static grpc_lb_policy_factory* lookup_factory(const char* name) {
- int i;
+ private:
+ InlinedVector<UniquePtr<LoadBalancingPolicyFactory>, 10> factories_;
+};
- if (name == nullptr) return nullptr;
+RegistryState* g_state = nullptr;
- for (i = 0; i < g_number_of_lb_policies; i++) {
- if (0 == gpr_stricmp(name, g_all_of_the_lb_policies[i]->vtable->name)) {
- return g_all_of_the_lb_policies[i];
- }
- }
+} // namespace
- return nullptr;
+//
+// LoadBalancingPolicyRegistry::Builder
+//
+
+void LoadBalancingPolicyRegistry::Builder::InitRegistry() {
+ if (g_state == nullptr) g_state = New<RegistryState>();
+}
+
+void LoadBalancingPolicyRegistry::Builder::ShutdownRegistry() {
+ Delete(g_state);
+ g_state = nullptr;
}
-grpc_lb_policy* grpc_lb_policy_create(const char* name,
- grpc_lb_policy_args* args) {
- grpc_lb_policy_factory* factory = lookup_factory(name);
- grpc_lb_policy* lb_policy =
- grpc_lb_policy_factory_create_lb_policy(factory, args);
- return lb_policy;
+void LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory(
+ UniquePtr<LoadBalancingPolicyFactory> factory) {
+ InitRegistry();
+ g_state->RegisterLoadBalancingPolicyFactory(std::move(factory));
}
+
+//
+// LoadBalancingPolicyRegistry
+//
+
+OrphanablePtr<LoadBalancingPolicy>
+LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
+ const char* name, const LoadBalancingPolicy::Args& args) {
+ GPR_ASSERT(g_state != nullptr);
+ // Find factory.
+ LoadBalancingPolicyFactory* factory =
+ g_state->GetLoadBalancingPolicyFactory(name);
+ if (factory == nullptr) return nullptr; // Specified name not found.
+ // Create policy via factory.
+ return factory->CreateLoadBalancingPolicy(args);
+}
+
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h
index 5aff79376b..2283d848bd 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.h
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.h
@@ -19,22 +19,37 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/iomgr/exec_ctx.h"
-/** Initialize the registry and set \a default_factory as the factory to be
- * returned when no name is provided in a lookup */
-void grpc_lb_policy_registry_init(void);
-void grpc_lb_policy_registry_shutdown(void);
+namespace grpc_core {
-/** Register a LB policy factory. */
-void grpc_register_lb_policy(grpc_lb_policy_factory* factory);
+class LoadBalancingPolicyRegistry {
+ public:
+ /// Methods used to create and populate the LoadBalancingPolicyRegistry.
+ /// NOT THREAD SAFE -- to be used only during global gRPC
+ /// initialization and shutdown.
+ class Builder {
+ public:
+ /// Global initialization and shutdown hooks.
+ static void InitRegistry();
+ static void ShutdownRegistry();
-/** Create a \a grpc_lb_policy instance.
- *
- * If \a name is NULL, the default factory from \a grpc_lb_policy_registry_init
- * will be returned. */
-grpc_lb_policy* grpc_lb_policy_create(const char* name,
- grpc_lb_policy_args* args);
+ /// Registers an LB policy factory. The factory will be used to create an
+ /// LB policy whose name matches that of the factory.
+ static void RegisterLoadBalancingPolicyFactory(
+ UniquePtr<LoadBalancingPolicyFactory> factory);
+ };
+
+ /// Creates an LB policy of the type specified by \a name.
+ static OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
+ const char* name, const LoadBalancingPolicy::Args& args);
+};
+
+} // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_REGISTRY_H */
diff --git a/src/core/ext/filters/client_channel/method_params.cc b/src/core/ext/filters/client_channel/method_params.cc
new file mode 100644
index 0000000000..374b87e170
--- /dev/null
+++ b/src/core/ext/filters/client_channel/method_params.cc
@@ -0,0 +1,178 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/method_params.h"
+#include "src/core/ext/filters/client_channel/status_util.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/memory.h"
+
+// As per the retry design, we do not allow more than 5 retry attempts.
+#define MAX_MAX_RETRY_ATTEMPTS 5
+
+namespace grpc_core {
+namespace internal {
+
+namespace {
+
+bool ParseWaitForReady(
+ grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
+ if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
+ return false;
+ }
+ *wait_for_ready = field->type == GRPC_JSON_TRUE
+ ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
+ : ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
+ return true;
+}
+
+// Parses a JSON field of the form generated for a google.proto.Duration
+// proto message, as per:
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+bool ParseDuration(grpc_json* field, grpc_millis* duration) {
+ if (field->type != GRPC_JSON_STRING) return false;
+ size_t len = strlen(field->value);
+ if (field->value[len - 1] != 's') return false;
+ UniquePtr<char> buf(gpr_strdup(field->value));
+ *(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
+ char* decimal_point = strchr(buf.get(), '.');
+ int nanos = 0;
+ if (decimal_point != nullptr) {
+ *decimal_point = '\0';
+ nanos = gpr_parse_nonnegative_int(decimal_point + 1);
+ if (nanos == -1) {
+ return false;
+ }
+ int num_digits = static_cast<int>(strlen(decimal_point + 1));
+ if (num_digits > 9) { // We don't accept greater precision than nanos.
+ return false;
+ }
+ for (int i = 0; i < (9 - num_digits); ++i) {
+ nanos *= 10;
+ }
+ }
+ int seconds =
+ decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
+ if (seconds == -1) return false;
+ *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
+ return true;
+}
+
+UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
+ grpc_json* field) {
+ auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
+ if (field->type != GRPC_JSON_OBJECT) return nullptr;
+ for (grpc_json* sub_field = field->child; sub_field != nullptr;
+ sub_field = sub_field->next) {
+ if (sub_field->key == nullptr) return nullptr;
+ if (strcmp(sub_field->key, "maxAttempts") == 0) {
+ if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
+ retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
+ if (retry_policy->max_attempts <= 1) return nullptr;
+ if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
+ gpr_log(GPR_ERROR,
+ "service config: clamped retryPolicy.maxAttempts at %d",
+ MAX_MAX_RETRY_ATTEMPTS);
+ retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
+ }
+ } else if (strcmp(sub_field->key, "initialBackoff") == 0) {
+ if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
+ return nullptr;
+ }
+ if (retry_policy->initial_backoff == 0) return nullptr;
+ } else if (strcmp(sub_field->key, "maxBackoff") == 0) {
+ if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
+ return nullptr;
+ }
+ if (retry_policy->max_backoff == 0) return nullptr;
+ } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
+ if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
+ if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
+ 1) {
+ return nullptr;
+ }
+ if (retry_policy->backoff_multiplier <= 0) return nullptr;
+ } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
+ if (!retry_policy->retryable_status_codes.Empty()) {
+ return nullptr; // Duplicate.
+ }
+ if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
+ for (grpc_json* element = sub_field->child; element != nullptr;
+ element = element->next) {
+ if (element->type != GRPC_JSON_STRING) return nullptr;
+ grpc_status_code status;
+ if (!grpc_status_code_from_string(element->value, &status)) {
+ return nullptr;
+ }
+ retry_policy->retryable_status_codes.Add(status);
+ }
+ if (retry_policy->retryable_status_codes.Empty()) return nullptr;
+ }
+ }
+ // Make sure required fields are set.
+ if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
+ retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
+ retry_policy->retryable_status_codes.Empty()) {
+ return nullptr;
+ }
+ return retry_policy;
+}
+
+} // namespace
+
+RefCountedPtr<ClientChannelMethodParams>
+ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
+ RefCountedPtr<ClientChannelMethodParams> method_params =
+ MakeRefCounted<ClientChannelMethodParams>();
+ for (grpc_json* field = json->child; field != nullptr; field = field->next) {
+ if (field->key == nullptr) continue;
+ if (strcmp(field->key, "waitForReady") == 0) {
+ if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
+ return nullptr; // Duplicate.
+ }
+ if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
+ return nullptr;
+ }
+ } else if (strcmp(field->key, "timeout") == 0) {
+ if (method_params->timeout_ > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
+ } else if (strcmp(field->key, "retryPolicy") == 0) {
+ if (method_params->retry_policy_ != nullptr) {
+ return nullptr; // Duplicate.
+ }
+ method_params->retry_policy_ = ParseRetryPolicy(field);
+ if (method_params->retry_policy_ == nullptr) return nullptr;
+ }
+ }
+ return method_params;
+}
+
+} // namespace internal
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/method_params.h b/src/core/ext/filters/client_channel/method_params.h
new file mode 100644
index 0000000000..48ece29867
--- /dev/null
+++ b/src/core/ext/filters/client_channel/method_params.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/status_util.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
+#include "src/core/lib/json/json.h"
+
+namespace grpc_core {
+namespace internal {
+
+class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
+ public:
+ enum WaitForReady {
+ WAIT_FOR_READY_UNSET = 0,
+ WAIT_FOR_READY_FALSE,
+ WAIT_FOR_READY_TRUE
+ };
+
+ struct RetryPolicy {
+ int max_attempts = 0;
+ grpc_millis initial_backoff = 0;
+ grpc_millis max_backoff = 0;
+ float backoff_multiplier = 0;
+ StatusCodeSet retryable_status_codes;
+ };
+
+ /// Creates a method_parameters object from \a json.
+ /// Intended for use with ServiceConfig::CreateMethodConfigTable().
+ static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
+ const grpc_json* json);
+
+ grpc_millis timeout() const { return timeout_; }
+ WaitForReady wait_for_ready() const { return wait_for_ready_; }
+ const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T, typename... Args>
+ friend T* grpc_core::New(Args&&... args);
+
+ ClientChannelMethodParams() {}
+ virtual ~ClientChannelMethodParams() {}
+
+ grpc_millis timeout_ = 0;
+ WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
+ UniquePtr<RetryPolicy> retry_policy_;
+};
+
+} // namespace internal
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H */
diff --git a/src/core/ext/filters/client_channel/parse_address.cc b/src/core/ext/filters/client_channel/parse_address.cc
index 473c7542df..e78dc99e0b 100644
--- a/src/core/ext/filters/client_channel/parse_address.cc
+++ b/src/core/ext/filters/client_channel/parse_address.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
diff --git a/src/core/ext/filters/client_channel/parse_address.h b/src/core/ext/filters/client_channel/parse_address.h
index ca0a0d18f0..9a88b66edc 100644
--- a/src/core/ext/filters/client_channel/parse_address.h
+++ b/src/core/ext/filters/client_channel/parse_address.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PARSE_ADDRESS_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PARSE_ADDRESS_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include "src/core/ext/filters/client_channel/uri_parser.h"
diff --git a/src/core/ext/filters/client_channel/proxy_mapper.cc b/src/core/ext/filters/client_channel/proxy_mapper.cc
index be85cfcced..c4da06778d 100644
--- a/src/core/ext/filters/client_channel/proxy_mapper.cc
+++ b/src/core/ext/filters/client_channel/proxy_mapper.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/proxy_mapper.h"
void grpc_proxy_mapper_init(const grpc_proxy_mapper_vtable* vtable,
diff --git a/src/core/ext/filters/client_channel/proxy_mapper.h b/src/core/ext/filters/client_channel/proxy_mapper.h
index ce3e65ee46..634b0ed7bf 100644
--- a/src/core/ext/filters/client_channel/proxy_mapper.h
+++ b/src/core/ext/filters/client_channel/proxy_mapper.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/impl/codegen/grpc_types.h>
diff --git a/src/core/ext/filters/client_channel/proxy_mapper_registry.cc b/src/core/ext/filters/client_channel/proxy_mapper_registry.cc
index b42597e363..a02a5f5e2c 100644
--- a/src/core/ext/filters/client_channel/proxy_mapper_registry.cc
+++ b/src/core/ext/filters/client_channel/proxy_mapper_registry.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include <string.h>
diff --git a/src/core/ext/filters/client_channel/proxy_mapper_registry.h b/src/core/ext/filters/client_channel/proxy_mapper_registry.h
index 2ad6c04e1d..326b582b99 100644
--- a/src/core/ext/filters/client_channel/proxy_mapper_registry.h
+++ b/src/core/ext/filters/client_channel/proxy_mapper_registry.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_PROXY_MAPPER_REGISTRY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/proxy_mapper.h"
void grpc_proxy_mapper_registry_init();
diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc
index 860c2eea1e..cd11eeb9e4 100644
--- a/src/core/ext/filters/client_channel/resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/lib/iomgr/combiner.h"
diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h
index 62fcb49a41..1685a6c803 100644
--- a/src/core/ext/filters/client_channel/resolver.h
+++ b/src/core/ext/filters/client_channel/resolver.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/gprpp/abstract.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 0442b1e496..aa93e5d8de 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -17,6 +17,7 @@
*/
#include <grpc/support/port_platform.h>
+
#if GRPC_ARES == 1 && !defined(GRPC_UV)
#include <limits.h>
@@ -294,7 +295,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
size_t num_args_to_add = 0;
new_args[num_args_to_add++] =
grpc_lb_addresses_create_channel_arg(r->lb_addresses_);
- grpc_service_config* service_config = nullptr;
+ grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config;
char* service_config_string = nullptr;
if (r->service_config_json_ != nullptr) {
service_config_string = ChooseServiceConfig(r->service_config_json_);
@@ -305,10 +306,11 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
new_args[num_args_to_add++] = grpc_channel_arg_string_create(
(char*)GRPC_ARG_SERVICE_CONFIG, service_config_string);
- service_config = grpc_service_config_create(service_config_string);
+ service_config =
+ grpc_core::ServiceConfig::Create(service_config_string);
if (service_config != nullptr) {
const char* lb_policy_name =
- grpc_service_config_get_lb_policy_name(service_config);
+ service_config->GetLoadBalancingPolicyName();
if (lb_policy_name != nullptr) {
args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME;
new_args[num_args_to_add++] = grpc_channel_arg_string_create(
@@ -321,7 +323,6 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
result = grpc_channel_args_copy_and_add_and_remove(
r->channel_args_, args_to_remove, num_args_to_remove, new_args,
num_args_to_add);
- if (service_config != nullptr) grpc_service_config_destroy(service_config);
gpr_free(service_config_string);
grpc_lb_addresses_destroy(r->lb_addresses_);
// Reset backoff state so that we start from the beginning when the
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
index ba7dad63cf..0bc13e35f4 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_EV_DRIVER_H
+#include <grpc/support/port_platform.h>
+
#include <ares.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset_set.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
index 10bc8f6074..b604f2bf14 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
@@ -16,6 +16,7 @@
*
*/
#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET)
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 82b5545601..71b06eb87e 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -17,6 +17,7 @@
*/
#include <grpc/support/port_platform.h>
+
#if GRPC_ARES == 1 && !defined(GRPC_UV)
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index 86d870e0a6..bda9cd1729 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
index a184cf2d57..5096e480bc 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
@@ -17,6 +17,7 @@
*/
#include <grpc/support/port_platform.h>
+
#if GRPC_ARES != 1 || defined(GRPC_UV)
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
index b01e608c3f..4d8958f519 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -17,6 +17,8 @@
// This is similar to the sockaddr resolver, except that it supports a
// bunch of query args that are useful for dependency injection in tests.
+#include <grpc/support/port_platform.h>
+
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
@@ -24,7 +26,6 @@
#include <string.h>
#include <grpc/support/alloc.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
index d42811d913..858f35851d 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
@@ -17,6 +17,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FAKE_FAKE_RESOLVER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FAKE_FAKE_RESOLVER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/uri_parser.h"
#include "src/core/lib/channel/channel_args.h"
diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
index 966b9fd3f2..f74ac5aebe 100644
--- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
@@ -16,13 +16,14 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grpc/support/alloc.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
diff --git a/src/core/ext/filters/client_channel/resolver_factory.h b/src/core/ext/filters/client_channel/resolver_factory.h
index f9b9501236..ee3cfeeb9b 100644
--- a/src/core/ext/filters/client_channel/resolver_factory.h
+++ b/src/core/ext/filters/client_channel/resolver_factory.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FACTORY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_FACTORY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/resolver.h"
diff --git a/src/core/ext/filters/client_channel/resolver_registry.cc b/src/core/ext/filters/client_channel/resolver_registry.cc
index 036e81d0ae..91c0267f95 100644
--- a/src/core/ext/filters/client_channel/resolver_registry.cc
+++ b/src/core/ext/filters/client_channel/resolver_registry.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include <string.h>
diff --git a/src/core/ext/filters/client_channel/resolver_registry.h b/src/core/ext/filters/client_channel/resolver_registry.h
index 260336de83..d6ec6811bd 100644
--- a/src/core/ext/filters/client_channel/resolver_registry.h
+++ b/src/core/ext/filters/client_channel/resolver_registry.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_REGISTRY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/resolver_factory.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include "src/core/lib/gprpp/memory.h"
diff --git a/src/core/ext/filters/client_channel/retry_throttle.cc b/src/core/ext/filters/client_channel/retry_throttle.cc
index a98e27860a..45de6667c8 100644
--- a/src/core/ext/filters/client_channel/retry_throttle.cc
+++ b/src/core/ext/filters/client_channel/retry_throttle.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/retry_throttle.h"
#include <limits.h>
@@ -38,7 +40,7 @@ struct grpc_server_retry_throttle_data {
int milli_token_ratio;
gpr_atm milli_tokens;
// A pointer to the replacement for this grpc_server_retry_throttle_data
- // entry. If non-NULL, then this entry is stale and must not be used.
+ // entry. If non-nullptr, then this entry is stale and must not be used.
// We hold a reference to the replacement.
gpr_atm replacement;
};
@@ -56,6 +58,7 @@ static void get_replacement_throttle_data_if_needed(
bool grpc_server_retry_throttle_data_record_failure(
grpc_server_retry_throttle_data* throttle_data) {
+ if (throttle_data == nullptr) return true;
// First, check if we are stale and need to be replaced.
get_replacement_throttle_data_if_needed(&throttle_data);
// We decrement milli_tokens by 1000 (1 token) for each failure.
@@ -70,6 +73,7 @@ bool grpc_server_retry_throttle_data_record_failure(
void grpc_server_retry_throttle_data_record_success(
grpc_server_retry_throttle_data* throttle_data) {
+ if (throttle_data == nullptr) return;
// First, check if we are stale and need to be replaced.
get_replacement_throttle_data_if_needed(&throttle_data);
// We increment milli_tokens by milli_token_ratio for each success.
diff --git a/src/core/ext/filters/client_channel/retry_throttle.h b/src/core/ext/filters/client_channel/retry_throttle.h
index bf99297e98..0505fc27f2 100644
--- a/src/core/ext/filters/client_channel/retry_throttle.h
+++ b/src/core/ext/filters/client_channel/retry_throttle.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RETRY_THROTTLE_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RETRY_THROTTLE_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
/// Tracks retry throttling data for an individual server name.
diff --git a/src/core/ext/filters/client_channel/status_util.cc b/src/core/ext/filters/client_channel/status_util.cc
new file mode 100644
index 0000000000..11f732ab44
--- /dev/null
+++ b/src/core/ext/filters/client_channel/status_util.cc
@@ -0,0 +1,100 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/status_util.h"
+
+#include "src/core/lib/gpr/useful.h"
+
+typedef struct {
+ const char* str;
+ grpc_status_code status;
+} status_string_entry;
+
+static const status_string_entry g_status_string_entries[] = {
+ {"OK", GRPC_STATUS_OK},
+ {"CANCELLED", GRPC_STATUS_CANCELLED},
+ {"UNKNOWN", GRPC_STATUS_UNKNOWN},
+ {"INVALID_ARGUMENT", GRPC_STATUS_INVALID_ARGUMENT},
+ {"DEADLINE_EXCEEDED", GRPC_STATUS_DEADLINE_EXCEEDED},
+ {"NOT_FOUND", GRPC_STATUS_NOT_FOUND},
+ {"ALREADY_EXISTS", GRPC_STATUS_ALREADY_EXISTS},
+ {"PERMISSION_DENIED", GRPC_STATUS_PERMISSION_DENIED},
+ {"UNAUTHENTICATED", GRPC_STATUS_UNAUTHENTICATED},
+ {"RESOURCE_EXHAUSTED", GRPC_STATUS_RESOURCE_EXHAUSTED},
+ {"FAILED_PRECONDITION", GRPC_STATUS_FAILED_PRECONDITION},
+ {"ABORTED", GRPC_STATUS_ABORTED},
+ {"OUT_OF_RANGE", GRPC_STATUS_OUT_OF_RANGE},
+ {"UNIMPLEMENTED", GRPC_STATUS_UNIMPLEMENTED},
+ {"INTERNAL", GRPC_STATUS_INTERNAL},
+ {"UNAVAILABLE", GRPC_STATUS_UNAVAILABLE},
+ {"DATA_LOSS", GRPC_STATUS_DATA_LOSS},
+};
+
+bool grpc_status_code_from_string(const char* status_str,
+ grpc_status_code* status) {
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(g_status_string_entries); ++i) {
+ if (strcmp(status_str, g_status_string_entries[i].str) == 0) {
+ *status = g_status_string_entries[i].status;
+ return true;
+ }
+ }
+ return false;
+}
+
+const char* grpc_status_code_to_string(grpc_status_code status) {
+ switch (status) {
+ case GRPC_STATUS_OK:
+ return "OK";
+ case GRPC_STATUS_CANCELLED:
+ return "CANCELLED";
+ case GRPC_STATUS_UNKNOWN:
+ return "UNKNOWN";
+ case GRPC_STATUS_INVALID_ARGUMENT:
+ return "INVALID_ARGUMENT";
+ case GRPC_STATUS_DEADLINE_EXCEEDED:
+ return "DEADLINE_EXCEEDED";
+ case GRPC_STATUS_NOT_FOUND:
+ return "NOT_FOUND";
+ case GRPC_STATUS_ALREADY_EXISTS:
+ return "ALREADY_EXISTS";
+ case GRPC_STATUS_PERMISSION_DENIED:
+ return "PERMISSION_DENIED";
+ case GRPC_STATUS_UNAUTHENTICATED:
+ return "UNAUTHENTICATED";
+ case GRPC_STATUS_RESOURCE_EXHAUSTED:
+ return "RESOURCE_EXHAUSTED";
+ case GRPC_STATUS_FAILED_PRECONDITION:
+ return "FAILED_PRECONDITION";
+ case GRPC_STATUS_ABORTED:
+ return "ABORTED";
+ case GRPC_STATUS_OUT_OF_RANGE:
+ return "OUT_OF_RANGE";
+ case GRPC_STATUS_UNIMPLEMENTED:
+ return "UNIMPLEMENTED";
+ case GRPC_STATUS_INTERNAL:
+ return "INTERNAL";
+ case GRPC_STATUS_UNAVAILABLE:
+ return "UNAVAILABLE";
+ case GRPC_STATUS_DATA_LOSS:
+ return "DATA_LOSS";
+ default:
+ return "UNKNOWN";
+ }
+}
diff --git a/src/core/ext/filters/client_channel/status_util.h b/src/core/ext/filters/client_channel/status_util.h
new file mode 100644
index 0000000000..e018709730
--- /dev/null
+++ b/src/core/ext/filters/client_channel/status_util.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_STATUS_UTIL_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_STATUS_UTIL_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/status.h>
+
+#include <stdbool.h>
+#include <string.h>
+
+/// If \a status_str is a valid status string, sets \a status to the
+/// corresponding status value and returns true.
+bool grpc_status_code_from_string(const char* status_str,
+ grpc_status_code* status);
+
+/// Returns the string form of \a status, or "UNKNOWN" if invalid.
+const char* grpc_status_code_to_string(grpc_status_code status);
+
+namespace grpc_core {
+namespace internal {
+
+/// A set of grpc_status_code values.
+class StatusCodeSet {
+ public:
+ bool Empty() const { return status_code_mask_ == 0; }
+
+ void Add(grpc_status_code status) { status_code_mask_ |= (1 << status); }
+
+ bool Contains(grpc_status_code status) const {
+ return status_code_mask_ & (1 << status);
+ }
+
+ private:
+ int status_code_mask_ = 0; // A bitfield of status codes in the set.
+};
+
+} // namespace internal
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_STATUS_UTIL_H */
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index db04f346ec..68cd9260ba 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/subchannel.h"
#include <inttypes.h>
@@ -662,7 +664,6 @@ static void on_subchannel_connected(void* arg, grpc_error* error) {
static void subchannel_call_destroy(void* call, grpc_error* error) {
GPR_TIMER_SCOPE("grpc_subchannel_call_unref.destroy", 0);
grpc_subchannel_call* c = static_cast<grpc_subchannel_call*>(call);
- GPR_ASSERT(c->schedule_closure_after_destroy != nullptr);
grpc_core::ConnectedSubchannel* connection = c->connection;
grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr,
c->schedule_closure_after_destroy);
@@ -676,9 +677,10 @@ void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call* call,
call->schedule_closure_after_destroy = closure;
}
-void grpc_subchannel_call_ref(
+grpc_subchannel_call* grpc_subchannel_call_ref(
grpc_subchannel_call* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
+ return c;
}
void grpc_subchannel_call_unref(
@@ -708,6 +710,13 @@ const grpc_subchannel_key* grpc_subchannel_get_key(
return subchannel->key;
}
+void* grpc_connected_subchannel_call_get_parent_data(
+ grpc_subchannel_call* subchannel_call) {
+ grpc_channel_stack* chanstk = subchannel_call->connection->channel_stack();
+ return (char*)subchannel_call + sizeof(grpc_subchannel_call) +
+ chanstk->call_stack_size;
+}
+
grpc_call_stack* grpc_subchannel_call_get_call_stack(
grpc_subchannel_call* subchannel_call) {
return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
@@ -733,9 +742,9 @@ void grpc_get_subchannel_address_arg(const grpc_channel_args* args,
const char* grpc_get_subchannel_address_uri_arg(const grpc_channel_args* args) {
const grpc_arg* addr_arg =
grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
- GPR_ASSERT(addr_arg != nullptr); // Should have been set by LB policy.
- GPR_ASSERT(addr_arg->type == GRPC_ARG_STRING);
- return addr_arg->value.string;
+ const char* addr_str = grpc_channel_arg_get_string(addr_arg);
+ GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy.
+ return addr_str;
}
grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) {
@@ -779,8 +788,8 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args,
grpc_subchannel_call** call) {
*call = static_cast<grpc_subchannel_call*>(gpr_arena_alloc(
- args.arena,
- sizeof(grpc_subchannel_call) + channel_stack_->call_stack_size));
+ args.arena, sizeof(grpc_subchannel_call) +
+ channel_stack_->call_stack_size + args.parent_data_size));
grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call);
RefCountedPtr<ConnectedSubchannel> connection =
Ref(DEBUG_LOCATION, "subchannel_call");
diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
index d2b45ae9c8..e23aec12df 100644
--- a/src/core/ext/filters/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/connector.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/arena.h"
@@ -79,6 +81,7 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
gpr_arena* arena;
grpc_call_context_element* context;
grpc_call_combiner* call_combiner;
+ size_t parent_data_size;
};
explicit ConnectedSubchannel(grpc_channel_stack* channel_stack);
@@ -107,11 +110,17 @@ grpc_subchannel* grpc_subchannel_weak_ref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_weak_unref(
grpc_subchannel* channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
-void grpc_subchannel_call_ref(
+grpc_subchannel_call* grpc_subchannel_call_ref(
grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
void grpc_subchannel_call_unref(
grpc_subchannel_call* call GRPC_SUBCHANNEL_REF_EXTRA_ARGS);
+/** Returns a pointer to the parent data associated with \a subchannel_call.
+ The data will be of the size specified in \a parent_data_size
+ field of the args passed to \a grpc_connected_subchannel_create_call(). */
+void* grpc_connected_subchannel_call_get_parent_data(
+ grpc_subchannel_call* subchannel_call);
+
/** poll the current connectivity state of a channel */
grpc_connectivity_state grpc_subchannel_check_connectivity(
grpc_subchannel* channel, grpc_error** error);
diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc
index d1dc5ee970..cb02b1a748 100644
--- a/src/core/ext/filters/client_channel/subchannel_index.cc
+++ b/src/core/ext/filters/client_channel/subchannel_index.cc
@@ -16,6 +16,8 @@
//
//
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include <stdbool.h>
diff --git a/src/core/ext/filters/client_channel/subchannel_index.h b/src/core/ext/filters/client_channel/subchannel_index.h
index bd160a3b13..a7dae9d47d 100644
--- a/src/core/ext/filters/client_channel/subchannel_index.h
+++ b/src/core/ext/filters/client_channel/subchannel_index.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SUBCHANNEL_INDEX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/subchannel.h"
/** \file Provides an index of active subchannels so that they can be
diff --git a/src/core/ext/filters/client_channel/uri_parser.cc b/src/core/ext/filters/client_channel/uri_parser.cc
index cd07a6fbf5..0572034a9c 100644
--- a/src/core/ext/filters/client_channel/uri_parser.cc
+++ b/src/core/ext/filters/client_channel/uri_parser.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/uri_parser.h"
#include <string.h>
@@ -23,7 +25,6 @@
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"
diff --git a/src/core/ext/filters/client_channel/uri_parser.h b/src/core/ext/filters/client_channel/uri_parser.h
index 24ff06c0b5..1966da932b 100644
--- a/src/core/ext/filters/client_channel/uri_parser.h
+++ b/src/core/ext/filters/client_channel/uri_parser.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_URI_PARSER_H
#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_URI_PARSER_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/filters/deadline/deadline_filter.cc b/src/core/ext/filters/deadline/deadline_filter.cc
index 76c1204090..dda3b61108 100644
--- a/src/core/ext/filters/deadline/deadline_filter.cc
+++ b/src/core/ext/filters/deadline/deadline_filter.cc
@@ -14,6 +14,8 @@
// limitations under the License.
//
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/deadline/deadline_filter.h"
#include <stdbool.h>
diff --git a/src/core/ext/filters/deadline/deadline_filter.h b/src/core/ext/filters/deadline/deadline_filter.h
index 4de817ef54..13207cbd6f 100644
--- a/src/core/ext/filters/deadline/deadline_filter.h
+++ b/src/core/ext/filters/deadline/deadline_filter.h
@@ -17,6 +17,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_DEADLINE_DEADLINE_FILTER_H
#define GRPC_CORE_EXT_FILTERS_DEADLINE_DEADLINE_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/timer.h"
diff --git a/src/core/ext/filters/http/client/http_client_filter.cc b/src/core/ext/filters/http/client/http_client_filter.cc
index 80643f8584..58aefd17c7 100644
--- a/src/core/ext/filters/http/client/http_client_filter.cc
+++ b/src/core/ext/filters/http/client/http_client_filter.cc
@@ -15,11 +15,13 @@
*
*/
-#include "src/core/ext/filters/http/client/http_client_filter.h"
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <string.h>
+#include "src/core/ext/filters/http/client/http_client_filter.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/slice/b64.h"
diff --git a/src/core/ext/filters/http/client/http_client_filter.h b/src/core/ext/filters/http/client/http_client_filter.h
index ec8177c436..b7cef33f5c 100644
--- a/src/core/ext/filters/http/client/http_client_filter.h
+++ b/src/core/ext/filters/http/client/http_client_filter.h
@@ -18,6 +18,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H
#define GRPC_CORE_EXT_FILTERS_HTTP_CLIENT_HTTP_CLIENT_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
/* Processes metadata on the client side for HTTP2 transports */
diff --git a/src/core/ext/filters/http/http_filters_plugin.cc b/src/core/ext/filters/http/http_filters_plugin.cc
index 56fe1e5c24..f03fa0141d 100644
--- a/src/core/ext/filters/http/http_filters_plugin.cc
+++ b/src/core/ext/filters/http/http_filters_plugin.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include "src/core/ext/filters/http/client/http_client_filter.h"
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.cc b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
index 73220a0ea1..efe0085c5b 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.cc
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <assert.h>
#include <string.h>
diff --git a/src/core/ext/filters/http/message_compress/message_compress_filter.h b/src/core/ext/filters/http/message_compress/message_compress_filter.h
index 62207911c7..e163e3cf98 100644
--- a/src/core/ext/filters/http/message_compress/message_compress_filter.h
+++ b/src/core/ext/filters/http/message_compress/message_compress_filter.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_COMPRESS_FILTER_H
#define GRPC_CORE_EXT_FILTERS_HTTP_MESSAGE_COMPRESS_MESSAGE_COMPRESS_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/compression_types.h>
#include "src/core/lib/channel/channel_stack.h"
diff --git a/src/core/ext/filters/http/server/http_server_filter.cc b/src/core/ext/filters/http/server/http_server_filter.cc
index 63bc2bd59f..57ec8dce34 100644
--- a/src/core/ext/filters/http/server/http_server_filter.cc
+++ b/src/core/ext/filters/http/server/http_server_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include <grpc/support/alloc.h>
@@ -52,7 +54,6 @@ struct call_data {
grpc_closure* recv_message_ready;
grpc_closure* on_complete;
grpc_byte_stream** pp_recv_message;
- grpc_slice_buffer read_slice_buffer;
grpc_slice_buffer_stream read_stream;
/** Receive closures are chained: we inject this closure as the on_done_recv
@@ -224,13 +225,15 @@ static grpc_error* server_filter_incoming_metadata(grpc_call_element* elem,
/* decode payload from query and add to the slice buffer to be returned */
const int k_url_safe = 1;
+ grpc_slice_buffer read_slice_buffer;
+ grpc_slice_buffer_init(&read_slice_buffer);
grpc_slice_buffer_add(
- &calld->read_slice_buffer,
+ &read_slice_buffer,
grpc_base64_decode_with_len(
reinterpret_cast<const char*> GRPC_SLICE_START_PTR(query_slice),
GRPC_SLICE_LENGTH(query_slice), k_url_safe));
- grpc_slice_buffer_stream_init(&calld->read_stream,
- &calld->read_slice_buffer, 0);
+ grpc_slice_buffer_stream_init(&calld->read_stream, &read_slice_buffer, 0);
+ grpc_slice_buffer_destroy_internal(&read_slice_buffer);
calld->seen_path_with_query = true;
grpc_slice_unref_internal(query_slice);
} else {
@@ -393,7 +396,6 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&calld->hs_recv_message_ready, hs_recv_message_ready, elem,
grpc_schedule_on_exec_ctx);
- grpc_slice_buffer_init(&calld->read_slice_buffer);
return GRPC_ERROR_NONE;
}
@@ -402,7 +404,9 @@ static void destroy_call_elem(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* ignored) {
call_data* calld = static_cast<call_data*>(elem->call_data);
- grpc_slice_buffer_destroy_internal(&calld->read_slice_buffer);
+ if (calld->seen_path_with_query && !calld->payload_bin_delivered) {
+ grpc_byte_stream_destroy(&calld->read_stream.base);
+ }
}
/* Constructor for channel_data */
diff --git a/src/core/ext/filters/http/server/http_server_filter.h b/src/core/ext/filters/http/server/http_server_filter.h
index c0f678a329..4eb130b1fd 100644
--- a/src/core/ext/filters/http/server/http_server_filter.h
+++ b/src/core/ext/filters/http/server/http_server_filter.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_HTTP_SERVER_HTTP_SERVER_FILTER_H
#define GRPC_CORE_EXT_FILTERS_HTTP_SERVER_HTTP_SERVER_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
/* Processes metadata on the client side for HTTP2 transports */
diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
index 79b144a6eb..0d349e2a89 100644
--- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
+++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/load_reporting.h>
diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_filter.h b/src/core/ext/filters/load_reporting/server_load_reporting_filter.h
index 1baee5e7cd..b459a8ec5f 100644
--- a/src/core/ext/filters/load_reporting/server_load_reporting_filter.h
+++ b/src/core/ext/filters/load_reporting/server_load_reporting_filter.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_FILTER_H
#define GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h"
#include "src/core/lib/channel/channel_stack.h"
diff --git a/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h b/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h
index 4b694d336d..c20aaa744f 100644
--- a/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h
+++ b/src/core/ext/filters/load_reporting/server_load_reporting_plugin.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_PLUGIN_H
#define GRPC_CORE_EXT_FILTERS_LOAD_REPORTING_SERVER_LOAD_REPORTING_PLUGIN_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/channel/channel_stack.h"
diff --git a/src/core/ext/filters/max_age/max_age_filter.cc b/src/core/ext/filters/max_age/max_age_filter.cc
index abb9d69036..1fe8288bd0 100644
--- a/src/core/ext/filters/max_age/max_age_filter.cc
+++ b/src/core/ext/filters/max_age/max_age_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/max_age/max_age_filter.h"
#include <limits.h>
@@ -368,6 +370,9 @@ static void channel_connectivity_changed(void* arg, grpc_error* error) {
max_idle_timer, and prevent max_idle_timer from being started in the
future. */
increase_call_count(chand);
+ if (gpr_atm_acq_load(&chand->idle_state) == MAX_IDLE_STATE_SEEN_EXIT_IDLE) {
+ grpc_timer_cancel(&chand->max_idle_timer);
+ }
}
}
diff --git a/src/core/ext/filters/max_age/max_age_filter.h b/src/core/ext/filters/max_age/max_age_filter.h
index 68fb4a4ca5..989322244f 100644
--- a/src/core/ext/filters/max_age/max_age_filter.h
+++ b/src/core/ext/filters/max_age/max_age_filter.h
@@ -17,6 +17,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_MAX_AGE_MAX_AGE_FILTER_H
#define GRPC_CORE_EXT_FILTERS_MAX_AGE_MAX_AGE_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_max_age_filter;
diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc
index 49d9ae60ae..b1b14dde02 100644
--- a/src/core/ext/filters/message_size/message_size_filter.cc
+++ b/src/core/ext/filters/message_size/message_size_filter.cc
@@ -14,6 +14,8 @@
// limitations under the License.
//
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/message_size/message_size_filter.h"
#include <limits.h>
@@ -27,6 +29,8 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/lib/transport/service_config.h"
@@ -35,27 +39,29 @@ typedef struct {
int max_recv_size;
} message_size_limits;
-typedef struct {
- gpr_refcount refs;
- message_size_limits limits;
-} refcounted_message_size_limits;
+namespace grpc_core {
+namespace {
-static void* refcounted_message_size_limits_ref(void* value) {
- refcounted_message_size_limits* limits =
- static_cast<refcounted_message_size_limits*>(value);
- gpr_ref(&limits->refs);
- return value;
-}
+class MessageSizeLimits : public RefCounted<MessageSizeLimits> {
+ public:
+ static RefCountedPtr<MessageSizeLimits> CreateFromJson(const grpc_json* json);
+
+ const message_size_limits& limits() const { return limits_; }
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T, typename... Args>
+ friend T* grpc_core::New(Args&&... args);
-static void refcounted_message_size_limits_unref(void* value) {
- refcounted_message_size_limits* limits =
- static_cast<refcounted_message_size_limits*>(value);
- if (gpr_unref(&limits->refs)) {
- gpr_free(value);
+ MessageSizeLimits(int max_send_size, int max_recv_size) {
+ limits_.max_send_size = max_send_size;
+ limits_.max_recv_size = max_recv_size;
}
-}
-static void* refcounted_message_size_limits_create_from_json(
+ message_size_limits limits_;
+};
+
+RefCountedPtr<MessageSizeLimits> MessageSizeLimits::CreateFromJson(
const grpc_json* json) {
int max_request_message_bytes = -1;
int max_response_message_bytes = -1;
@@ -77,16 +83,15 @@ static void* refcounted_message_size_limits_create_from_json(
if (max_response_message_bytes == -1) return nullptr;
}
}
- refcounted_message_size_limits* value =
- static_cast<refcounted_message_size_limits*>(
- gpr_malloc(sizeof(refcounted_message_size_limits)));
- gpr_ref_init(&value->refs, 1);
- value->limits.max_send_size = max_request_message_bytes;
- value->limits.max_recv_size = max_response_message_bytes;
- return value;
+ return MakeRefCounted<MessageSizeLimits>(max_request_message_bytes,
+ max_response_message_bytes);
}
+} // namespace
+} // namespace grpc_core
+
namespace {
+
struct call_data {
grpc_call_combiner* call_combiner;
message_size_limits limits;
@@ -103,8 +108,11 @@ struct call_data {
struct channel_data {
message_size_limits limits;
// Maps path names to refcounted_message_size_limits structs.
- grpc_slice_hash_table* method_limit_table;
+ grpc_core::RefCountedPtr<grpc_core::SliceHashTable<
+ grpc_core::RefCountedPtr<grpc_core::MessageSizeLimits>>>
+ method_limit_table;
};
+
} // namespace
// Callback invoked when we receive a message. Here we check the max
@@ -183,20 +191,19 @@ static grpc_error* init_call_elem(grpc_call_element* elem,
// size to the receive limit.
calld->limits = chand->limits;
if (chand->method_limit_table != nullptr) {
- refcounted_message_size_limits* limits =
- static_cast<refcounted_message_size_limits*>(
- grpc_method_config_table_get(chand->method_limit_table,
- args->path));
+ grpc_core::RefCountedPtr<grpc_core::MessageSizeLimits> limits =
+ grpc_core::ServiceConfig::MethodConfigTableLookup(
+ *chand->method_limit_table, args->path);
if (limits != nullptr) {
- if (limits->limits.max_send_size >= 0 &&
- (limits->limits.max_send_size < calld->limits.max_send_size ||
+ if (limits->limits().max_send_size >= 0 &&
+ (limits->limits().max_send_size < calld->limits.max_send_size ||
calld->limits.max_send_size < 0)) {
- calld->limits.max_send_size = limits->limits.max_send_size;
+ calld->limits.max_send_size = limits->limits().max_send_size;
}
- if (limits->limits.max_recv_size >= 0 &&
- (limits->limits.max_recv_size < calld->limits.max_recv_size ||
+ if (limits->limits().max_recv_size >= 0 &&
+ (limits->limits().max_recv_size < calld->limits.max_recv_size ||
calld->limits.max_recv_size < 0)) {
- calld->limits.max_recv_size = limits->limits.max_recv_size;
+ calld->limits.max_recv_size = limits->limits().max_recv_size;
}
}
}
@@ -249,17 +256,13 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
// Get method config table from channel args.
const grpc_arg* channel_arg =
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
- if (channel_arg != nullptr) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
- grpc_service_config* service_config =
- grpc_service_config_create(channel_arg->value.string);
+ const char* service_config_str = grpc_channel_arg_get_string(channel_arg);
+ if (service_config_str != nullptr) {
+ grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
+ grpc_core::ServiceConfig::Create(service_config_str);
if (service_config != nullptr) {
- chand->method_limit_table =
- grpc_service_config_create_method_config_table(
- service_config, refcounted_message_size_limits_create_from_json,
- refcounted_message_size_limits_ref,
- refcounted_message_size_limits_unref);
- grpc_service_config_destroy(service_config);
+ chand->method_limit_table = service_config->CreateMethodConfigTable(
+ grpc_core::MessageSizeLimits::CreateFromJson);
}
}
return GRPC_ERROR_NONE;
@@ -268,7 +271,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
// Destructor for channel_data.
static void destroy_channel_elem(grpc_channel_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- grpc_slice_hash_table_unref(chand->method_limit_table);
+ chand->method_limit_table.reset();
}
const grpc_channel_filter grpc_message_size_filter = {
diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h
index d3667f7003..f66636e583 100644
--- a/src/core/ext/filters/message_size/message_size_filter.h
+++ b/src/core/ext/filters/message_size/message_size_filter.h
@@ -17,6 +17,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H
#define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_message_size_filter;
diff --git a/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc b/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
index 3092ed2056..bed1004c57 100644
--- a/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
+++ b/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc
@@ -14,6 +14,8 @@
// limitations under the License.
//
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h"
#include <string.h>
diff --git a/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h b/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h
index 9dae4f0734..94d20f0c4a 100644
--- a/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h
+++ b/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h
@@ -17,6 +17,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_CRONET_COMPRESSION_FILTER_H
#define GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_CRONET_COMPRESSION_FILTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_workaround_cronet_compression_filter;
diff --git a/src/core/ext/filters/workarounds/workaround_utils.cc b/src/core/ext/filters/workarounds/workaround_utils.cc
index 850ed75ec9..4dabe896d3 100644
--- a/src/core/ext/filters/workarounds/workaround_utils.cc
+++ b/src/core/ext/filters/workarounds/workaround_utils.cc
@@ -14,6 +14,8 @@
// limitations under the License.
//
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/workarounds/workaround_utils.h"
#include <grpc/support/alloc.h>
diff --git a/src/core/ext/filters/workarounds/workaround_utils.h b/src/core/ext/filters/workarounds/workaround_utils.h
index d6ef5e84fa..f172ccc078 100644
--- a/src/core/ext/filters/workarounds/workaround_utils.h
+++ b/src/core/ext/filters/workarounds/workaround_utils.h
@@ -17,6 +17,8 @@
#ifndef GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_UTILS_H
#define GRPC_CORE_EXT_FILTERS_WORKAROUNDS_WORKAROUND_UTILS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/workaround_list.h>
#include "src/core/lib/transport/metadata.h"
diff --git a/src/core/ext/transport/chttp2/alpn/alpn.cc b/src/core/ext/transport/chttp2/alpn/alpn.cc
index 5c4bfd03fa..1fdab76dbf 100644
--- a/src/core/ext/transport/chttp2/alpn/alpn.cc
+++ b/src/core/ext/transport/chttp2/alpn/alpn.cc
@@ -16,8 +16,10 @@
*
*/
-#include "src/core/ext/transport/chttp2/alpn/alpn.h"
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
+#include "src/core/ext/transport/chttp2/alpn/alpn.h"
#include "src/core/lib/gpr/useful.h"
diff --git a/src/core/ext/transport/chttp2/alpn/alpn.h b/src/core/ext/transport/chttp2/alpn/alpn.h
index fd7513c665..0042eafd95 100644
--- a/src/core/ext/transport/chttp2/alpn/alpn.h
+++ b/src/core/ext/transport/chttp2/alpn/alpn.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_ALPN_ALPN_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_ALPN_ALPN_H
+#include <grpc/support/port_platform.h>
+
#include <string.h>
/* Retuns 1 if the version is supported, 0 otherwise. */
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc
index 7eb9ebc27e..e7522ffba8 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include <grpc/grpc.h>
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.h b/src/core/ext/transport/chttp2/client/chttp2_connector.h
index e258892cfc..04da441309 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.h
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_CLIENT_CHTTP2_CONNECTOR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/filters/client_channel/connector.h"
grpc_connector* grpc_chttp2_connector_create();
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc
index ef1d3fb53b..60800365b8 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <string.h>
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
index 0cdea5a94e..479f0da572 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
@@ -16,10 +16,11 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/grpc_posix.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
index 8c4025ed13..a82009ff69 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <string.h>
@@ -28,10 +30,11 @@
#include "src/core/ext/filters/client_channel/uri_parser.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/lb_targets_info.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
+#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/lib/slice/slice_hash_table.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
@@ -63,9 +66,7 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
// To which address are we connecting? By default, use the server URI.
const grpc_arg* server_uri_arg =
grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
- GPR_ASSERT(server_uri_arg != nullptr);
- GPR_ASSERT(server_uri_arg->type == GRPC_ARG_STRING);
- const char* server_uri_str = server_uri_arg->value.string;
+ const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
GPR_ASSERT(server_uri_str != nullptr);
grpc_uri* server_uri =
grpc_uri_parse(server_uri_str, true /* supress errors */);
@@ -73,11 +74,11 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
const char* server_uri_path;
server_uri_path =
server_uri->path[0] == '/' ? server_uri->path + 1 : server_uri->path;
- const grpc_slice_hash_table* targets_info =
- grpc_lb_targets_info_find_in_args(args->args);
- char* target_name_to_check = nullptr;
- if (targets_info != nullptr) { // LB channel
- // Find the balancer name for the target.
+ const grpc_core::TargetAuthorityTable* target_authority_table =
+ grpc_core::FindTargetAuthorityTableInArgs(args->args);
+ grpc_core::UniquePtr<char> authority;
+ if (target_authority_table != nullptr) {
+ // Find the authority for the target.
const char* target_uri_str =
grpc_get_subchannel_address_uri_arg(args->args);
grpc_uri* target_uri =
@@ -86,37 +87,33 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
if (target_uri->path[0] != '\0') { // "path" may be empty
const grpc_slice key = grpc_slice_from_static_string(
target_uri->path[0] == '/' ? target_uri->path + 1 : target_uri->path);
- const char* value = static_cast<const char*>(
- grpc_slice_hash_table_get(targets_info, key));
- if (value != nullptr) target_name_to_check = gpr_strdup(value);
+ const grpc_core::UniquePtr<char>* value =
+ target_authority_table->Get(key);
+ if (value != nullptr) authority.reset(gpr_strdup(value->get()));
grpc_slice_unref_internal(key);
}
- if (target_name_to_check == nullptr) {
- // If the target name to check hasn't already been set, fall back to using
- // SERVER_URI
- target_name_to_check = gpr_strdup(server_uri_path);
- }
grpc_uri_destroy(target_uri);
- } else { // regular channel: the secure name is the original server URI.
- target_name_to_check = gpr_strdup(server_uri_path);
+ }
+ // If the authority hasn't already been set (either because no target
+ // authority table was present or because the target was not present
+ // in the table), fall back to using the original server URI.
+ if (authority == nullptr) {
+ authority.reset(gpr_strdup(server_uri_path));
}
grpc_uri_destroy(server_uri);
- GPR_ASSERT(target_name_to_check != nullptr);
grpc_channel_security_connector* subchannel_security_connector = nullptr;
// Create the security connector using the credentials and target name.
grpc_channel_args* new_args_from_connector = nullptr;
const grpc_security_status security_status =
grpc_channel_credentials_create_security_connector(
- channel_credentials, target_name_to_check, args->args,
+ channel_credentials, authority.get(), args->args,
&subchannel_security_connector, &new_args_from_connector);
if (security_status != GRPC_SECURITY_OK) {
gpr_log(GPR_ERROR,
"Failed to create secure subchannel for secure name '%s'",
- target_name_to_check);
- gpr_free(target_name_to_check);
+ authority.get());
return nullptr;
}
- gpr_free(target_name_to_check);
grpc_arg new_security_connector_arg =
grpc_security_connector_to_arg(&subchannel_security_connector->base);
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc
index 90b2ee1af9..687cc483f6 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.cc
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/server/chttp2_server.h"
#include <grpc/grpc.h>
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h
index 7de859da42..7b41972160 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.h
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc
index 52c42d056c..822236dd2d 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/support/log.h>
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
index dafd4af6ce..371e463814 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
@@ -16,10 +16,11 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/grpc_posix.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
index 723af97ff0..6689a17da6 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <string.h>
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.cc b/src/core/ext/transport/chttp2/transport/bin_decoder.cc
index 91980e6974..f0f32da028 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.cc
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.cc
@@ -16,9 +16,11 @@
*
*/
-#include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
@@ -75,6 +77,32 @@ static bool input_is_valid(uint8_t* input_ptr, size_t length) {
#define COMPOSE_OUTPUT_BYTE_2(input_ptr) \
(uint8_t)((decode_table[input_ptr[2]] << 6) | decode_table[input_ptr[3]])
+// By RFC 4648, if the length of the encoded string without padding is 4n+r,
+// the length of decoded string is: 1) 3n if r = 0, 2) 3n + 1 if r = 2, 3, or
+// 3) invalid if r = 1.
+size_t grpc_chttp2_base64_infer_length_after_decode(const grpc_slice& slice) {
+ size_t len = GRPC_SLICE_LENGTH(slice);
+ const uint8_t* bytes = GRPC_SLICE_START_PTR(slice);
+ while (len > 0 && bytes[len - 1] == '=') {
+ len--;
+ }
+ if (GRPC_SLICE_LENGTH(slice) - len > 2) {
+ gpr_log(GPR_ERROR,
+ "Base64 decoding failed. Input has more than 2 paddings.");
+ return 0;
+ }
+ size_t tuples = len / 4;
+ size_t tail_case = len % 4;
+ if (tail_case == 1) {
+ gpr_log(GPR_ERROR,
+ "Base64 decoding failed. Input has a length of %zu (without"
+ " padding), which is invalid.\n",
+ len);
+ return 0;
+ }
+ return tuples * 3 + tail_xtra[tail_case];
+}
+
bool grpc_base64_decode_partial(struct grpc_base64_decode_context* ctx) {
size_t input_tail;
diff --git a/src/core/ext/transport/chttp2/transport/bin_decoder.h b/src/core/ext/transport/chttp2/transport/bin_decoder.h
index 9cb75ccd81..8a4d4a7179 100644
--- a/src/core/ext/transport/chttp2/transport/bin_decoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_decoder.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <stdbool.h>
@@ -48,4 +50,7 @@ grpc_slice grpc_chttp2_base64_decode(grpc_slice input);
grpc_slice grpc_chttp2_base64_decode_with_length(grpc_slice input,
size_t output_length);
+/* Infer the length of decoded data from encoded data. */
+size_t grpc_chttp2_base64_infer_length_after_decode(const grpc_slice& slice);
+
#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_DECODER_H */
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.cc b/src/core/ext/transport/chttp2/transport/bin_encoder.cc
index e3b8adbe73..bad29e3421 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include <string.h>
diff --git a/src/core/ext/transport/chttp2/transport/bin_encoder.h b/src/core/ext/transport/chttp2/transport/bin_encoder.h
index 93ad0dfdea..1b7bb1574a 100644
--- a/src/core/ext/transport/chttp2/transport/bin_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/bin_encoder.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_BIN_ENCODER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
/* base64 encode a slice. Returns a new slice, does not take ownership of the
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
index a69908116a..531ea73e9e 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/env.h"
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index ad8da94cb3..df3fb8c68c 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -16,10 +16,10 @@
*
*/
-#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
-
#include <grpc/support/port_platform.h>
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+
#include <inttypes.h>
#include <limits.h>
#include <math.h>
@@ -1456,8 +1456,10 @@ static void perform_stream_op_locked(void* stream_op,
}
}
if (op_payload->send_initial_metadata.peer_string != nullptr) {
- gpr_atm_rel_store(op_payload->send_initial_metadata.peer_string,
- (gpr_atm)gpr_strdup(t->peer_string));
+ char* old_peer_string = (char*)gpr_atm_full_xchg(
+ op_payload->send_initial_metadata.peer_string,
+ (gpr_atm)gpr_strdup(t->peer_string));
+ gpr_free(old_peer_string);
}
}
@@ -1473,6 +1475,7 @@ static void perform_stream_op_locked(void* stream_op,
// streaming call might send another message before getting a
// recv_message failure, breaking out of its loop, and then
// starting recv_trailing_metadata.
+ grpc_byte_stream_destroy(op->payload->send_message.send_message);
grpc_chttp2_complete_closure_step(
t, s, &s->fetching_send_message_finished,
t->is_client && s->received_trailing_metadata
@@ -1570,8 +1573,10 @@ static void perform_stream_op_locked(void* stream_op,
s->trailing_metadata_available =
op_payload->recv_initial_metadata.trailing_metadata_available;
if (op_payload->recv_initial_metadata.peer_string != nullptr) {
- gpr_atm_rel_store(op_payload->recv_initial_metadata.peer_string,
- (gpr_atm)gpr_strdup(t->peer_string));
+ char* old_peer_string = (char*)gpr_atm_full_xchg(
+ op_payload->recv_initial_metadata.peer_string,
+ (gpr_atm)gpr_strdup(t->peer_string));
+ gpr_free(old_peer_string);
}
grpc_chttp2_maybe_complete_recv_initial_metadata(t, s);
}
@@ -2092,7 +2097,10 @@ void grpc_chttp2_fail_pending_writes(grpc_chttp2_transport* t,
GRPC_ERROR_REF(error),
"send_trailing_metadata_finished");
- s->fetching_send_message = nullptr;
+ if (s->fetching_send_message != nullptr) {
+ grpc_byte_stream_destroy(s->fetching_send_message);
+ s->fetching_send_message = nullptr;
+ }
grpc_chttp2_complete_closure_step(t, s, &s->fetching_send_message_finished,
GRPC_ERROR_REF(error),
"fetching_send_message_finished");
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
index 34519ceec9..9d55b3f4b0 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/transport/transport.h"
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.cc b/src/core/ext/transport/chttp2/transport/flow_control.cc
index 45b6f97b05..e89c363200 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.cc
+++ b/src/core/ext/transport/chttp2/transport/flow_control.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/flow_control.h"
#include <inttypes.h>
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h
index b58027790d..120fefc8b7 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.h
+++ b/src/core/ext/transport/chttp2/transport/flow_control.h
@@ -20,6 +20,7 @@
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FLOW_CONTROL_H
#include <grpc/support/port_platform.h>
+
#include <stdint.h>
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame.h b/src/core/ext/transport/chttp2/transport/frame.h
index dba4c004ec..083c0076e7 100644
--- a/src/core/ext/transport/chttp2/transport/frame.h
+++ b/src/core/ext/transport/chttp2/transport/frame.h
@@ -19,9 +19,10 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_H
-#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
+#include <grpc/slice.h>
+
#include "src/core/lib/iomgr/error.h"
/* defined in internal.h */
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.cc b/src/core/ext/transport/chttp2/transport/frame_data.cc
index 721f0a55a1..0d37a494a2 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_data.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/frame_data.h"
#include <string.h>
diff --git a/src/core/ext/transport/chttp2/transport/frame_data.h b/src/core/ext/transport/chttp2/transport/frame_data.h
index 964cc59b1b..3efbbf9f76 100644
--- a/src/core/ext/transport/chttp2/transport/frame_data.h
+++ b/src/core/ext/transport/chttp2/transport/frame_data.h
@@ -21,6 +21,8 @@
/* Parser for GRPC streams embedded in DATA frames */
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.cc b/src/core/ext/transport/chttp2/transport/frame_goaway.cc
index 70931ed22d..2a1dd3c316 100644
--- a/src/core/ext/transport/chttp2/transport/frame_goaway.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/frame_goaway.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_goaway.h b/src/core/ext/transport/chttp2/transport/frame_goaway.h
index 064d39ac59..e17ed8d563 100644
--- a/src/core/ext/transport/chttp2/transport/frame_goaway.h
+++ b/src/core/ext/transport/chttp2/transport/frame_goaway.h
@@ -19,9 +19,10 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_GOAWAY_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_GOAWAY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
-#include <grpc/support/port_platform.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.cc b/src/core/ext/transport/chttp2/transport/frame_ping.cc
index 6229459397..205826b779 100644
--- a/src/core/ext/transport/chttp2/transport/frame_ping.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_ping.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/frame_ping.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_ping.h b/src/core/ext/transport/chttp2/transport/frame_ping.h
index 75bacfb1d4..8718d6a097 100644
--- a/src/core/ext/transport/chttp2/transport/frame_ping.h
+++ b/src/core/ext/transport/chttp2/transport/frame_ping.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_PING_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_PING_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc
index 79528762e0..4bdd4309a4 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/frame_rst_stream.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h
index e76a3ca841..bb2d34f918 100644
--- a/src/core/ext/transport/chttp2/transport/frame_rst_stream.h
+++ b/src/core/ext/transport/chttp2/transport/frame_rst_stream.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_RST_STREAM_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_RST_STREAM_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.cc b/src/core/ext/transport/chttp2/transport/frame_settings.cc
index 737a9382e0..9ea27dcd47 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/frame_settings.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_settings.h b/src/core/ext/transport/chttp2/transport/frame_settings.h
index ce65402815..df19627194 100644
--- a/src/core/ext/transport/chttp2/transport/frame_settings.h
+++ b/src/core/ext/transport/chttp2/transport/frame_settings.h
@@ -19,8 +19,9 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_SETTINGS_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_SETTINGS_H
-#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
+
+#include <grpc/slice.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.cc b/src/core/ext/transport/chttp2/transport/frame_window_update.cc
index 95be5b42d2..4b586dc3e7 100644
--- a/src/core/ext/transport/chttp2/transport/frame_window_update.cc
+++ b/src/core/ext/transport/chttp2/transport/frame_window_update.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/frame_window_update.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/src/core/ext/transport/chttp2/transport/frame_window_update.h b/src/core/ext/transport/chttp2/transport/frame_window_update.h
index a32f1a9d11..30667c77e1 100644
--- a/src/core/ext/transport/chttp2/transport/frame_window_update.h
+++ b/src/core/ext/transport/chttp2/transport/frame_window_update.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FRAME_WINDOW_UPDATE_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
index 4855455130..e4f3c1b81e 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include <assert.h>
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index a26514cab0..b370932131 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -19,9 +19,10 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_ENCODER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
-#include <grpc/support/port_platform.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.cc b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
index 26a38e3f87..fc96a8b3e4 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
@@ -25,7 +27,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
diff --git a/src/core/ext/transport/chttp2/transport/hpack_parser.h b/src/core/ext/transport/chttp2/transport/hpack_parser.h
index 060bc5ce9d..b3b8018b98 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_parser.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_parser.h
@@ -19,9 +19,10 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_PARSER_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
-#include <grpc/support/port_platform.h>
#include "src/core/ext/transport/chttp2/transport/frame.h"
#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.cc b/src/core/ext/transport/chttp2/transport/hpack_table.cc
index d7cabbde04..f050f502f5 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.cc
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/hpack_table.h"
#include <assert.h>
diff --git a/src/core/ext/transport/chttp2/transport/hpack_table.h b/src/core/ext/transport/chttp2/transport/hpack_table.h
index 189ad1c697..98026a4ba4 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_table.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_table.h
@@ -19,8 +19,9 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_TABLE_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HPACK_TABLE_H
-#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
+
+#include <grpc/slice.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/transport/metadata.h"
diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.cc b/src/core/ext/transport/chttp2/transport/http2_settings.cc
index 745b1656f9..294ee8e4aa 100644
--- a/src/core/ext/transport/chttp2/transport/http2_settings.cc
+++ b/src/core/ext/transport/chttp2/transport/http2_settings.cc
@@ -18,6 +18,8 @@
* Automatically generated by tools/codegen/core/gen_settings_ids.py
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/http2_settings.h"
#include "src/core/lib/gpr/useful.h"
diff --git a/src/core/ext/transport/chttp2/transport/http2_settings.h b/src/core/ext/transport/chttp2/transport/http2_settings.h
index fd15b6977b..07ce0621b2 100644
--- a/src/core/ext/transport/chttp2/transport/http2_settings.h
+++ b/src/core/ext/transport/chttp2/transport/http2_settings.h
@@ -21,6 +21,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_HTTP2_SETTINGS_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <stdint.h>
diff --git a/src/core/ext/transport/chttp2/transport/huffsyms.cc b/src/core/ext/transport/chttp2/transport/huffsyms.cc
index f28d8cc30a..813e4c91b1 100644
--- a/src/core/ext/transport/chttp2/transport/huffsyms.cc
+++ b/src/core/ext/transport/chttp2/transport/huffsyms.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/huffsyms.h"
/* Constants pulled from the HPACK spec, and converted to C using the vim
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc
index 18d89f06d8..4d7dfd900f 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.cc
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include <string.h>
@@ -67,6 +69,5 @@ void grpc_chttp2_incoming_metadata_buffer_set_deadline(
void grpc_chttp2_incoming_metadata_buffer_publish(
grpc_chttp2_incoming_metadata_buffer* buffer, grpc_metadata_batch* batch) {
- *batch = buffer->batch;
- grpc_metadata_batch_init(&buffer->batch);
+ grpc_metadata_batch_move(&buffer->batch, batch);
}
diff --git a/src/core/ext/transport/chttp2/transport/incoming_metadata.h b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
index b84cd484c4..d029cf00d4 100644
--- a/src/core/ext/transport/chttp2/transport/incoming_metadata.h
+++ b/src/core/ext/transport/chttp2/transport/incoming_metadata.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INCOMING_METADATA_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INCOMING_METADATA_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/transport.h"
typedef struct {
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 6b6c0b28e2..b9431cd311 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H
#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_INTERNAL_H
+#include <grpc/support/port_platform.h>
+
#include <assert.h>
#include <stdbool.h>
diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc
index 9357fedb5c..988380b76c 100644
--- a/src/core/ext/transport/chttp2/transport/parsing.cc
+++ b/src/core/ext/transport/chttp2/transport/parsing.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include <string.h>
diff --git a/src/core/ext/transport/chttp2/transport/stream_lists.cc b/src/core/ext/transport/chttp2/transport/stream_lists.cc
index 3aad8c5823..5d3ec4b53b 100644
--- a/src/core/ext/transport/chttp2/transport/stream_lists.cc
+++ b/src/core/ext/transport/chttp2/transport/stream_lists.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/src/core/ext/transport/chttp2/transport/stream_map.cc b/src/core/ext/transport/chttp2/transport/stream_map.cc
index a40eaffd5f..f300e2356c 100644
--- a/src/core/ext/transport/chttp2/transport/stream_map.cc
+++ b/src/core/ext/transport/chttp2/transport/stream_map.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/stream_map.h"
#include <string.h>
diff --git a/src/core/ext/transport/chttp2/transport/varint.cc b/src/core/ext/transport/chttp2/transport/varint.cc
index 621a8100c7..d4b01788b9 100644
--- a/src/core/ext/transport/chttp2/transport/varint.cc
+++ b/src/core/ext/transport/chttp2/transport/varint.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/varint.h"
uint32_t grpc_chttp2_hpack_varint_length(uint32_t tail_value) {
diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc
index 42cba9ae60..7471d88aa1 100644
--- a/src/core/ext/transport/chttp2/transport/writing.cc
+++ b/src/core/ext/transport/chttp2/transport/writing.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include <limits.h>
diff --git a/src/core/ext/transport/cronet/transport/cronet_api_dummy.cc b/src/core/ext/transport/cronet/transport/cronet_api_dummy.cc
index 578cbb8ac6..1a6bded6af 100644
--- a/src/core/ext/transport/cronet/transport/cronet_api_dummy.cc
+++ b/src/core/ext/transport/cronet/transport/cronet_api_dummy.cc
@@ -19,6 +19,8 @@
/* This file has empty implementation of all the functions exposed by the cronet
library, so we can build it in all environments */
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/support/log.h>
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.cc b/src/core/ext/transport/cronet/transport/cronet_transport.cc
index 8904c122a7..ff1c1aad62 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.cc
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.cc
@@ -16,14 +16,17 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
-#include <grpc/impl/codegen/port_platform.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/ext/transport/chttp2/transport/bin_decoder.h"
+#include "src/core/ext/transport/chttp2/transport/bin_encoder.h"
#include "src/core/ext/transport/chttp2/transport/incoming_metadata.h"
#include "src/core/ext/transport/cronet/transport/cronet_transport.h"
#include "src/core/lib/gpr/host_port.h"
@@ -393,6 +396,29 @@ static void execute_from_storage(stream_obj* s) {
gpr_mu_unlock(&s->mu);
}
+static void convert_cronet_array_to_metadata(
+ const bidirectional_stream_header_array* header_array,
+ grpc_chttp2_incoming_metadata_buffer* mds) {
+ for (size_t i = 0; i < header_array->count; i++) {
+ CRONET_LOG(GPR_DEBUG, "header key=%s, value=%s",
+ header_array->headers[i].key, header_array->headers[i].value);
+ grpc_slice key = grpc_slice_intern(
+ grpc_slice_from_static_string(header_array->headers[i].key));
+ grpc_slice value;
+ if (grpc_is_binary_header(key)) {
+ value = grpc_slice_from_static_string(header_array->headers[i].value);
+ value = grpc_slice_intern(grpc_chttp2_base64_decode_with_length(
+ value, grpc_chttp2_base64_infer_length_after_decode(value)));
+ } else {
+ value = grpc_slice_intern(
+ grpc_slice_from_static_string(header_array->headers[i].value));
+ }
+ GRPC_LOG_IF_ERROR("convert_cronet_array_to_metadata",
+ grpc_chttp2_incoming_metadata_buffer_add(
+ mds, grpc_mdelem_from_slices(key, value)));
+ }
+}
+
/*
Cronet callback
*/
@@ -517,16 +543,7 @@ static void on_response_headers_received(
sizeof(s->state.rs.initial_metadata));
grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata,
s->arena);
- for (size_t i = 0; i < headers->count; i++) {
- GRPC_LOG_IF_ERROR("on_response_headers_received",
- grpc_chttp2_incoming_metadata_buffer_add(
- &s->state.rs.initial_metadata,
- grpc_mdelem_from_slices(
- grpc_slice_intern(grpc_slice_from_static_string(
- headers->headers[i].key)),
- grpc_slice_intern(grpc_slice_from_static_string(
- headers->headers[i].value)))));
- }
+ convert_cronet_array_to_metadata(headers, &s->state.rs.initial_metadata);
s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
if (!(s->state.state_op_done[OP_CANCEL_ERROR] ||
s->state.state_callback_received[OP_FAILED])) {
@@ -621,18 +638,11 @@ static void on_response_trailers_received(
s->state.rs.trailing_metadata_valid = false;
grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata,
s->arena);
- for (size_t i = 0; i < trailers->count; i++) {
- CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key,
- trailers->headers[i].value);
- GRPC_LOG_IF_ERROR("on_response_trailers_received",
- grpc_chttp2_incoming_metadata_buffer_add(
- &s->state.rs.trailing_metadata,
- grpc_mdelem_from_slices(
- grpc_slice_intern(grpc_slice_from_static_string(
- trailers->headers[i].key)),
- grpc_slice_intern(grpc_slice_from_static_string(
- trailers->headers[i].value)))));
+ convert_cronet_array_to_metadata(trailers, &s->state.rs.trailing_metadata);
+ if (trailers->count > 0) {
s->state.rs.trailing_metadata_valid = true;
+ }
+ for (size_t i = 0; i < trailers->count; i++) {
if (0 == strcmp(trailers->headers[i].key, "grpc-status") &&
0 != strcmp(trailers->headers[i].value, "0")) {
s->state.fail_state = true;
@@ -721,7 +731,14 @@ static void convert_metadata_to_cronet_headers(
grpc_mdelem mdelem = curr->md;
curr = curr->next;
char* key = grpc_slice_to_c_string(GRPC_MDKEY(mdelem));
- char* value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem));
+ char* value;
+ if (grpc_is_binary_header(GRPC_MDKEY(mdelem))) {
+ grpc_slice wire_value = grpc_chttp2_base64_encode(GRPC_MDVALUE(mdelem));
+ value = grpc_slice_to_c_string(wire_value);
+ grpc_slice_unref(wire_value);
+ } else {
+ value = grpc_slice_to_c_string(GRPC_MDVALUE(mdelem));
+ }
if (grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_SCHEME) ||
grpc_slice_eq(GRPC_MDKEY(mdelem), GRPC_MDSTR_AUTHORITY)) {
/* Cronet populates these fields on its own */
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.h b/src/core/ext/transport/cronet/transport/cronet_transport.h
index d9ff913326..fb7e149f10 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.h
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_CRONET_TRANSPORT_CRONET_TRANSPORT_H
#define GRPC_CORE_EXT_TRANSPORT_CRONET_TRANSPORT_CRONET_TRANSPORT_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/transport.h"
grpc_transport* grpc_create_cronet_transport(void* engine, const char* target,
diff --git a/src/core/ext/transport/inproc/inproc_plugin.cc b/src/core/ext/transport/inproc/inproc_plugin.cc
index 83a7d8d52f..8e251fa2d8 100644
--- a/src/core/ext/transport/inproc/inproc_plugin.cc
+++ b/src/core/ext/transport/inproc/inproc_plugin.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc
index 2022eaffe5..5f898bbf25 100644
--- a/src/core/ext/transport/inproc/inproc_transport.cc
+++ b/src/core/ext/transport/inproc/inproc_transport.cc
@@ -16,12 +16,14 @@
*
*/
-#include "src/core/ext/transport/inproc/inproc_transport.h"
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
#include <string.h>
+#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/api_trace.h"
@@ -480,6 +482,8 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) {
s->recv_message_op = nullptr;
}
if (s->send_message_op) {
+ grpc_byte_stream_destroy(
+ s->send_message_op->payload->send_message.send_message);
complete_if_batch_end_locked(
s, error, s->send_message_op,
"fail_helper scheduling send-message-on-complete");
@@ -506,6 +510,14 @@ static void fail_helper_locked(inproc_stream* s, grpc_error* error) {
GRPC_ERROR_UNREF(error);
}
+// TODO(vjpai): It should not be necessary to drain the incoming byte
+// stream and create a new one; instead, we should simply pass the byte
+// stream from the sender directly to the receiver as-is.
+//
+// Note that fixing this will also avoid the assumption in this code
+// that the incoming byte stream's next() call will always return
+// synchronously. That assumption is true today but may not always be
+// true in the future.
static void message_transfer_locked(inproc_stream* sender,
inproc_stream* receiver) {
size_t remaining =
@@ -532,6 +544,8 @@ static void message_transfer_locked(inproc_stream* sender,
remaining -= GRPC_SLICE_LENGTH(message_slice);
grpc_slice_buffer_add(&receiver->recv_message, message_slice);
} while (remaining > 0);
+ grpc_byte_stream_destroy(
+ sender->send_message_op->payload->send_message.send_message);
grpc_slice_buffer_stream_init(&receiver->recv_stream, &receiver->recv_message,
0);
@@ -592,6 +606,8 @@ static void op_state_machine(void* arg, grpc_error* error) {
(s->trailing_md_sent || other->recv_trailing_md_op)) {
// A server send will never be matched if the client is waiting
// for trailing metadata already
+ grpc_byte_stream_destroy(
+ s->send_message_op->payload->send_message.send_message);
complete_if_batch_end_locked(
s, GRPC_ERROR_NONE, s->send_message_op,
"op_state_machine scheduling send-message-on-complete");
@@ -728,6 +744,8 @@ static void op_state_machine(void* arg, grpc_error* error) {
if ((s->trailing_md_sent || s->t->is_client) && s->send_message_op) {
// Nothing further will try to receive from this stream, so finish off
// any outstanding send_message op
+ grpc_byte_stream_destroy(
+ s->send_message_op->payload->send_message.send_message);
complete_if_batch_end_locked(
s, new_err, s->send_message_op,
"op_state_machine scheduling send-message-on-complete");
@@ -785,6 +803,8 @@ static void op_state_machine(void* arg, grpc_error* error) {
s->send_message_op) {
// Nothing further will try to receive from this stream, so finish off
// any outstanding send_message op
+ grpc_byte_stream_destroy(
+ s->send_message_op->payload->send_message.send_message);
complete_if_batch_end_locked(
s, new_err, s->send_message_op,
"op_state_machine scheduling send-message-on-complete");
diff --git a/src/core/ext/transport/inproc/inproc_transport.h b/src/core/ext/transport/inproc/inproc_transport.h
index 7c0453e7ce..049d1402af 100644
--- a/src/core/ext/transport/inproc/inproc_transport.h
+++ b/src/core/ext/transport/inproc/inproc_transport.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_EXT_TRANSPORT_INPROC_INPROC_TRANSPORT_H
#define GRPC_CORE_EXT_TRANSPORT_INPROC_INPROC_TRANSPORT_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/transport_impl.h"
grpc_channel* grpc_inproc_channel_create(grpc_server* server,
diff --git a/src/core/lib/avl/avl.cc b/src/core/lib/avl/avl.cc
index c674d9be28..ec106ddb1d 100644
--- a/src/core/lib/avl/avl.cc
+++ b/src/core/lib/avl/avl.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/avl/avl.h"
#include <assert.h>
diff --git a/src/core/lib/avl/avl.h b/src/core/lib/avl/avl.h
index df5d2e89ec..15a9d56947 100644
--- a/src/core/lib/avl/avl.h
+++ b/src/core/lib/avl/avl.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_AVL_AVL_H
#define GRPC_CORE_LIB_AVL_AVL_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/sync.h>
/** internal node of an AVL tree */
diff --git a/src/core/lib/backoff/backoff.cc b/src/core/lib/backoff/backoff.cc
index 4b74afc244..e536abde0a 100644
--- a/src/core/lib/backoff/backoff.cc
+++ b/src/core/lib/backoff/backoff.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/backoff/backoff.h"
#include <algorithm>
diff --git a/src/core/lib/backoff/backoff.h b/src/core/lib/backoff/backoff.h
index de30e5268b..e769d150ef 100644
--- a/src/core/lib/backoff/backoff.h
+++ b/src/core/lib/backoff/backoff.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_BACKOFF_BACKOFF_H
#define GRPC_CORE_LIB_BACKOFF_BACKOFF_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/exec_ctx.h"
namespace grpc_core {
diff --git a/src/core/lib/channel/channel_args.cc b/src/core/lib/channel/channel_args.cc
index 98fdfa6b9a..66a86c2286 100644
--- a/src/core/lib/channel/channel_args.cc
+++ b/src/core/lib/channel/channel_args.cc
@@ -354,6 +354,15 @@ int grpc_channel_arg_get_integer(const grpc_arg* arg,
return arg->value.integer;
}
+char* grpc_channel_arg_get_string(const grpc_arg* arg) {
+ if (arg == nullptr) return nullptr;
+ if (arg->type != GRPC_ARG_STRING) {
+ gpr_log(GPR_ERROR, "%s ignored: it must be an string", arg->key);
+ return nullptr;
+ }
+ return arg->value.string;
+}
+
bool grpc_channel_arg_get_bool(const grpc_arg* arg, bool default_value) {
if (arg == nullptr) return default_value;
if (arg->type != GRPC_ARG_INTEGER) {
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 73e9122e75..c0d6a17356 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H
#define GRPC_CORE_LIB_CHANNEL_CHANNEL_ARGS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/socket_mutator.h"
@@ -109,6 +111,11 @@ typedef struct grpc_integer_options {
int grpc_channel_arg_get_integer(const grpc_arg* arg,
const grpc_integer_options options);
+/** Returns the value of \a arg if \a arg is of type GRPC_ARG_STRING.
+ Otherwise, emits a warning log, and returns nullptr.
+ If arg is nullptr, returns nullptr, and does not emit a warning. */
+char* grpc_channel_arg_get_string(const grpc_arg* arg);
+
bool grpc_channel_arg_get_bool(const grpc_arg* arg, bool default_value);
// Helpers for creating channel args.
diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc
index 737d828e4b..a9459b150d 100644
--- a/src/core/lib/channel/channel_stack.cc
+++ b/src/core/lib/channel/channel_stack.cc
@@ -16,9 +16,11 @@
*
*/
-#include "src/core/lib/channel/channel_stack.h"
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include "src/core/lib/channel/channel_stack.h"
#include <stdlib.h>
#include <string.h>
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index b9f9748001..4bf8218664 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -33,6 +33,8 @@
Call stacks are created by channel stacks and represent the per-call data
for that stack. */
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include <grpc/grpc.h>
diff --git a/src/core/lib/channel/channel_stack_builder.cc b/src/core/lib/channel/channel_stack_builder.cc
index cae862ec0e..8a72449034 100644
--- a/src/core/lib/channel/channel_stack_builder.cc
+++ b/src/core/lib/channel/channel_stack_builder.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack_builder.h"
#include <string.h>
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index d00ddc698c..c9a170bc88 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H
#define GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include "src/core/lib/channel/channel_args.h"
diff --git a/src/core/lib/channel/connected_channel.cc b/src/core/lib/channel/connected_channel.cc
index a16e89ce00..ddd3029402 100644
--- a/src/core/lib/channel/connected_channel.cc
+++ b/src/core/lib/channel/connected_channel.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/connected_channel.h"
#include <stdarg.h>
diff --git a/src/core/lib/channel/connected_channel.h b/src/core/lib/channel/connected_channel.h
index 91de8022db..faa1c73a21 100644
--- a/src/core/lib/channel/connected_channel.h
+++ b/src/core/lib/channel/connected_channel.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H
#define GRPC_CORE_LIB_CHANNEL_CONNECTED_CHANNEL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack_builder.h"
extern const grpc_channel_filter grpc_connected_filter;
diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc
index 518e880c15..9b1af8d6cb 100644
--- a/src/core/lib/channel/handshaker.cc
+++ b/src/core/lib/channel/handshaker.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h
index 68e5463123..dfecd81004 100644
--- a/src/core/lib/channel/handshaker.h
+++ b/src/core/lib/channel/handshaker.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H
#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/iomgr/closure.h"
diff --git a/src/core/lib/channel/handshaker_factory.cc b/src/core/lib/channel/handshaker_factory.cc
index 2380d98300..4fd43635b6 100644
--- a/src/core/lib/channel/handshaker_factory.cc
+++ b/src/core/lib/channel/handshaker_factory.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/handshaker_factory.h"
#include <grpc/support/log.h>
diff --git a/src/core/lib/channel/handshaker_factory.h b/src/core/lib/channel/handshaker_factory.h
index 8a7c0157e8..9e36443958 100644
--- a/src/core/lib/channel/handshaker_factory.h
+++ b/src/core/lib/channel/handshaker_factory.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H
#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_FACTORY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/channel/handshaker.h"
diff --git a/src/core/lib/channel/handshaker_registry.cc b/src/core/lib/channel/handshaker_registry.cc
index 5464cc42f4..eec3e1b352 100644
--- a/src/core/lib/channel/handshaker_registry.cc
+++ b/src/core/lib/channel/handshaker_registry.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/handshaker_registry.h"
#include <string.h>
diff --git a/src/core/lib/channel/handshaker_registry.h b/src/core/lib/channel/handshaker_registry.h
index 0b05531b7e..b42d61ff43 100644
--- a/src/core/lib/channel/handshaker_registry.h
+++ b/src/core/lib/channel/handshaker_registry.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H
#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_REGISTRY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/lib/channel/handshaker_factory.h"
diff --git a/src/core/lib/compression/algorithm_metadata.h b/src/core/lib/compression/algorithm_metadata.h
index 7db771ea74..1be79e59c0 100644
--- a/src/core/lib/compression/algorithm_metadata.h
+++ b/src/core/lib/compression/algorithm_metadata.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H
#define GRPC_CORE_LIB_COMPRESSION_ALGORITHM_METADATA_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/compression.h>
#include "src/core/lib/compression/compression_internal.h"
#include "src/core/lib/transport/metadata.h"
diff --git a/src/core/lib/compression/compression.cc b/src/core/lib/compression/compression.cc
index 69d70ea941..48717541a7 100644
--- a/src/core/lib/compression/compression.cc
+++ b/src/core/lib/compression/compression.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/core/lib/compression/compression_internal.cc b/src/core/lib/compression/compression_internal.cc
index 36829c8adf..538514caf3 100644
--- a/src/core/lib/compression/compression_internal.cc
+++ b/src/core/lib/compression/compression_internal.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/core/lib/compression/compression_internal.h b/src/core/lib/compression/compression_internal.h
index 72f01dd1b7..da007368b0 100644
--- a/src/core/lib/compression/compression_internal.h
+++ b/src/core/lib/compression/compression_internal.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_COMPRESSION_COMPRESSION_INTERNAL_H
#define GRPC_CORE_LIB_COMPRESSION_COMPRESSION_INTERNAL_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/compression_types.h>
#ifdef __cplusplus
diff --git a/src/core/lib/compression/message_compress.cc b/src/core/lib/compression/message_compress.cc
index 2e44551935..e06454f871 100644
--- a/src/core/lib/compression/message_compress.cc
+++ b/src/core/lib/compression/message_compress.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/compression/message_compress.h"
#include <string.h>
diff --git a/src/core/lib/compression/message_compress.h b/src/core/lib/compression/message_compress.h
index ed9e5bfa39..91654e47e3 100644
--- a/src/core/lib/compression/message_compress.h
+++ b/src/core/lib/compression/message_compress.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H
#define GRPC_CORE_LIB_COMPRESSION_MESSAGE_COMPRESS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice_buffer.h>
#include "src/core/lib/compression/compression_internal.h"
diff --git a/src/core/lib/compression/stream_compression.cc b/src/core/lib/compression/stream_compression.cc
index b4b3e524d0..46cb3daf4c 100644
--- a/src/core/lib/compression/stream_compression.cc
+++ b/src/core/lib/compression/stream_compression.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
#include "src/core/lib/compression/stream_compression.h"
diff --git a/src/core/lib/compression/stream_compression.h b/src/core/lib/compression/stream_compression.h
index 8322835c4f..c80f2f8692 100644
--- a/src/core/lib/compression/stream_compression.h
+++ b/src/core/lib/compression/stream_compression.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_COMPRESSION_STREAM_COMPRESSION_H
#define GRPC_CORE_LIB_COMPRESSION_STREAM_COMPRESSION_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/slice_buffer.h>
diff --git a/src/core/lib/compression/stream_compression_gzip.cc b/src/core/lib/compression/stream_compression_gzip.cc
index 48fe99b69f..682f712843 100644
--- a/src/core/lib/compression/stream_compression_gzip.cc
+++ b/src/core/lib/compression/stream_compression_gzip.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
diff --git a/src/core/lib/compression/stream_compression_gzip.h b/src/core/lib/compression/stream_compression_gzip.h
index 7cf49a0de9..740f09734a 100644
--- a/src/core/lib/compression/stream_compression_gzip.h
+++ b/src/core/lib/compression/stream_compression_gzip.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_COMPRESSION_STREAM_COMPRESSION_GZIP_H
#define GRPC_CORE_LIB_COMPRESSION_STREAM_COMPRESSION_GZIP_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/compression/stream_compression.h"
extern const grpc_stream_compression_vtable grpc_stream_compression_gzip_vtable;
diff --git a/src/core/lib/compression/stream_compression_identity.cc b/src/core/lib/compression/stream_compression_identity.cc
index 933d24b3a1..52a6236621 100644
--- a/src/core/lib/compression/stream_compression_identity.cc
+++ b/src/core/lib/compression/stream_compression_identity.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
diff --git a/src/core/lib/compression/stream_compression_identity.h b/src/core/lib/compression/stream_compression_identity.h
index 41926e949e..cc77b63ecd 100644
--- a/src/core/lib/compression/stream_compression_identity.h
+++ b/src/core/lib/compression/stream_compression_identity.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_COMPRESSION_STREAM_COMPRESSION_IDENTITY_H
#define GRPC_CORE_LIB_COMPRESSION_STREAM_COMPRESSION_IDENTITY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/compression/stream_compression.h"
extern const grpc_stream_compression_vtable
diff --git a/src/core/lib/debug/stats.cc b/src/core/lib/debug/stats.cc
index 09a86287e4..d8ddf03ac1 100644
--- a/src/core/lib/debug/stats.cc
+++ b/src/core/lib/debug/stats.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/stats.h"
#include <inttypes.h>
diff --git a/src/core/lib/debug/stats.h b/src/core/lib/debug/stats.h
index 02eed5e844..749665262a 100644
--- a/src/core/lib/debug/stats.h
+++ b/src/core/lib/debug/stats.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_DEBUG_STATS_H
#define GRPC_CORE_LIB_DEBUG_STATS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
#include "src/core/lib/debug/stats_data.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/debug/stats_data.cc b/src/core/lib/debug/stats_data.cc
index e2d3a6d073..309ece94bb 100644
--- a/src/core/lib/debug/stats_data.cc
+++ b/src/core/lib/debug/stats_data.cc
@@ -18,8 +18,10 @@
* Automatically generated by tools/codegen/core/gen_stats_data.py
*/
-#include "src/core/lib/debug/stats_data.h"
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/stats.h"
+#include "src/core/lib/debug/stats_data.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/debug/stats_data.h b/src/core/lib/debug/stats_data.h
index 4504be33e7..da1266ad73 100644
--- a/src/core/lib/debug/stats_data.h
+++ b/src/core/lib/debug/stats_data.h
@@ -21,6 +21,8 @@
#ifndef GRPC_CORE_LIB_DEBUG_STATS_DATA_H
#define GRPC_CORE_LIB_DEBUG_STATS_DATA_H
+#include <grpc/support/port_platform.h>
+
#include <inttypes.h>
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc
index c0cefd0639..b0e0f2ba7c 100644
--- a/src/core/lib/debug/trace.cc
+++ b/src/core/lib/debug/trace.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/trace.h"
#include <string.h>
diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h
index 69ddd80222..bfec92c529 100644
--- a/src/core/lib/debug/trace.h
+++ b/src/core/lib/debug/trace.h
@@ -19,8 +19,9 @@
#ifndef GRPC_CORE_LIB_DEBUG_TRACE_H
#define GRPC_CORE_LIB_DEBUG_TRACE_H
-#include <grpc/support/atm.h>
#include <grpc/support/port_platform.h>
+
+#include <grpc/support/atm.h>
#include <stdbool.h>
void grpc_tracer_init(const char* env_var_name);
diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc
index e0d25963ed..611e4cceee 100644
--- a/src/core/lib/gpr/alloc.cc
+++ b/src/core/lib/gpr/alloc.cc
@@ -16,10 +16,11 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include <stdlib.h>
#include <string.h>
#include "src/core/lib/profiling/timers.h"
diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc
index 2d514df68b..b02c5b9fb6 100644
--- a/src/core/lib/gpr/arena.cc
+++ b/src/core/lib/gpr/arena.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/arena.h"
#include <string.h>
@@ -24,6 +26,49 @@
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
+// Uncomment this to use a simple arena that simply allocates the
+// requested amount of memory for each call to gpr_arena_alloc(). This
+// effectively eliminates the efficiency gain of using an arena, but it
+// may be useful for debugging purposes.
+//#define SIMPLE_ARENA_FOR_DEBUGGING
+
+#ifdef SIMPLE_ARENA_FOR_DEBUGGING
+
+#include <grpc/support/sync.h>
+
+struct gpr_arena {
+ gpr_mu mu;
+ void** ptrs;
+ size_t num_ptrs;
+};
+
+gpr_arena* gpr_arena_create(size_t ignored_initial_size) {
+ gpr_arena* arena = (gpr_arena*)gpr_zalloc(sizeof(*arena));
+ gpr_mu_init(&arena->mu);
+ return arena;
+}
+
+size_t gpr_arena_destroy(gpr_arena* arena) {
+ gpr_mu_destroy(&arena->mu);
+ for (size_t i = 0; i < arena->num_ptrs; ++i) {
+ gpr_free(arena->ptrs[i]);
+ }
+ gpr_free(arena->ptrs);
+ gpr_free(arena);
+ return 1; // Value doesn't matter, since it won't be used.
+}
+
+void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
+ gpr_mu_lock(&arena->mu);
+ arena->ptrs =
+ (void**)gpr_realloc(arena->ptrs, sizeof(void*) * (arena->num_ptrs + 1));
+ void* retval = arena->ptrs[arena->num_ptrs++] = gpr_zalloc(size);
+ gpr_mu_unlock(&arena->mu);
+ return retval;
+}
+
+#else // SIMPLE_ARENA_FOR_DEBUGGING
+
// TODO(roth): We currently assume that all callers need alignment of 16
// bytes, which may be wrong in some cases. As part of converting the
// arena API to C++, we should consider replacing gpr_arena_alloc() with a
@@ -103,3 +148,5 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
return ptr + start - z->size_begin;
}
+
+#endif // SIMPLE_ARENA_FOR_DEBUGGING
diff --git a/src/core/lib/gpr/arena.h b/src/core/lib/gpr/arena.h
index 339771c0e3..6d2a073dd5 100644
--- a/src/core/lib/gpr/arena.h
+++ b/src/core/lib/gpr/arena.h
@@ -25,6 +25,8 @@
#ifndef GRPC_CORE_LIB_GPR_ARENA_H
#define GRPC_CORE_LIB_GPR_ARENA_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
typedef struct gpr_arena gpr_arena;
diff --git a/src/core/lib/gpr/atm.cc b/src/core/lib/gpr/atm.cc
index 3d0b430348..649d400d38 100644
--- a/src/core/lib/gpr/atm.cc
+++ b/src/core/lib/gpr/atm.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
#include "src/core/lib/gpr/useful.h"
diff --git a/src/core/lib/gpr/cpu_linux.cc b/src/core/lib/gpr/cpu_linux.cc
index 4782f9f742..fda28916f8 100644
--- a/src/core/lib/gpr/cpu_linux.cc
+++ b/src/core/lib/gpr/cpu_linux.cc
@@ -45,7 +45,7 @@ static void init_num_cpus() {
#endif
/* This must be signed. sysconf returns -1 when the number cannot be
determined */
- ncpus = static_cast<int>(sysconf(_SC_NPROCESSORS_ONLN));
+ ncpus = static_cast<int>(sysconf(_SC_NPROCESSORS_CONF));
if (ncpus < 1) {
gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1");
ncpus = 1;
diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h
index b31e20b7d2..aec8a3166b 100644
--- a/src/core/lib/gpr/env.h
+++ b/src/core/lib/gpr/env.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_ENV_H
#define GRPC_CORE_LIB_GPR_ENV_H
+#include <grpc/support/port_platform.h>
+
#include <stdio.h>
/* Env utility functions */
diff --git a/src/core/lib/gpr/fork.cc b/src/core/lib/gpr/fork.cc
index 4651d22595..812522b058 100644
--- a/src/core/lib/gpr/fork.cc
+++ b/src/core/lib/gpr/fork.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/fork.h"
#include <string.h>
diff --git a/src/core/lib/gpr/host_port.cc b/src/core/lib/gpr/host_port.cc
index 5a03a16296..a34e01cb51 100644
--- a/src/core/lib/gpr/host_port.cc
+++ b/src/core/lib/gpr/host_port.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/host_port.h"
#include <string.h>
diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc
index 410096c0f7..72787ab724 100644
--- a/src/core/lib/gpr/log.cc
+++ b/src/core/lib/gpr/log.cc
@@ -16,10 +16,11 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
diff --git a/src/core/lib/gpr/mpscq.cc b/src/core/lib/gpr/mpscq.cc
index 34fc050a11..076a6bb033 100644
--- a/src/core/lib/gpr/mpscq.cc
+++ b/src/core/lib/gpr/mpscq.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/mpscq.h"
#include <grpc/support/log.h>
@@ -71,6 +73,7 @@ gpr_mpscq_node* gpr_mpscq_pop_and_check_end(gpr_mpscq* q, bool* empty) {
gpr_mpscq_push(q, &q->stub);
next = (gpr_mpscq_node*)gpr_atm_acq_load(&tail->next);
if (next != nullptr) {
+ *empty = false;
q->tail = next;
return tail;
}
diff --git a/src/core/lib/gpr/mpscq.h b/src/core/lib/gpr/mpscq.h
index 4409c5c9f5..6b67880d1b 100644
--- a/src/core/lib/gpr/mpscq.h
+++ b/src/core/lib/gpr/mpscq.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_MPSCQ_H
#define GRPC_CORE_LIB_GPR_MPSCQ_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
#include <grpc/support/sync.h>
#include <stdbool.h>
diff --git a/src/core/lib/gpr/murmur_hash.cc b/src/core/lib/gpr/murmur_hash.cc
index 01a7290c67..cf25abf40d 100644
--- a/src/core/lib/gpr/murmur_hash.cc
+++ b/src/core/lib/gpr/murmur_hash.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/murmur_hash.h"
#include <string.h>
diff --git a/src/core/lib/gpr/spinlock.h b/src/core/lib/gpr/spinlock.h
index f03be1d791..9f35530a86 100644
--- a/src/core/lib/gpr/spinlock.h
+++ b/src/core/lib/gpr/spinlock.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_SPINLOCK_H
#define GRPC_CORE_LIB_GPR_SPINLOCK_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
/* Simple spinlock. No backoff strategy, gpr_spinlock_lock is almost always
diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc
index 5a16377e49..ef2a6900b4 100644
--- a/src/core/lib/gpr/string.cc
+++ b/src/core/lib/gpr/string.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/string.h"
#include <ctype.h>
@@ -26,7 +28,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/useful.h"
diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h
index ef3a8c6086..2e8a4898d9 100644
--- a/src/core/lib/gpr/string.h
+++ b/src/core/lib/gpr/string.h
@@ -19,11 +19,11 @@
#ifndef GRPC_CORE_LIB_GPR_STRING_H
#define GRPC_CORE_LIB_GPR_STRING_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <stddef.h>
-#include <grpc/support/port_platform.h>
-
/* String utility functions */
/* Flags for gpr_dump function. */
diff --git a/src/core/lib/gpr/sync.cc b/src/core/lib/gpr/sync.cc
index 347ffcd00e..2f18fc5ecb 100644
--- a/src/core/lib/gpr/sync.cc
+++ b/src/core/lib/gpr/sync.cc
@@ -18,6 +18,8 @@
/* Generic implementation of synchronization primitives. */
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
diff --git a/src/core/lib/gpr/thd.cc b/src/core/lib/gpr/thd.cc
index ca62615d65..b5341c41b4 100644
--- a/src/core/lib/gpr/thd.cc
+++ b/src/core/lib/gpr/thd.cc
@@ -16,11 +16,13 @@
*
*/
-/* Posix implementation for gpr threads. */
+/* Platform-independent features for gpr threads. */
-#include <string.h>
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/gpr/thd.h"
-#include <grpc/support/thd.h>
+#include <string.h>
enum { GPR_THD_JOINABLE = 1 };
diff --git a/include/grpc/support/thd.h b/src/core/lib/gpr/thd.h
index e9444e88c9..920b336708 100644
--- a/include/grpc/support/thd.h
+++ b/src/core/lib/gpr/thd.h
@@ -16,24 +16,18 @@
*
*/
-#ifndef GRPC_SUPPORT_THD_H
-#define GRPC_SUPPORT_THD_H
-/** Thread interface for GPR.
+#ifndef GRPC_CORE_LIB_GPR_THD_H
+#define GRPC_CORE_LIB_GPR_THD_H
+/** Internal thread interface for GPR.
Types
- gpr_thd_id a thread identifier.
- (Currently no calls take a thread identifier.
- It exists for future extensibility.)
gpr_thd_options options used when creating a thread
*/
#include <grpc/support/port_platform.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef uintptr_t gpr_thd_id;
+#include <grpc/support/thd_id.h>
+#include <grpc/support/time.h>
/** Thread creation options. */
typedef struct {
@@ -46,34 +40,33 @@ typedef struct {
that support thread naming.
If options==NULL, default options are used.
The thread is immediately runnable, and exits when (*thd_body)() returns. */
-GPRAPI int gpr_thd_new(gpr_thd_id* t, const char* thd_name,
- void (*thd_body)(void* arg), void* arg,
- const gpr_thd_options* options);
+int gpr_thd_new(gpr_thd_id* t, const char* thd_name,
+ void (*thd_body)(void* arg), void* arg,
+ const gpr_thd_options* options);
/** Return a gpr_thd_options struct with all fields set to defaults. */
-GPRAPI gpr_thd_options gpr_thd_options_default(void);
+gpr_thd_options gpr_thd_options_default(void);
/** Set the thread to become detached on startup - this is the default. */
-GPRAPI void gpr_thd_options_set_detached(gpr_thd_options* options);
+void gpr_thd_options_set_detached(gpr_thd_options* options);
/** Set the thread to become joinable - mutually exclusive with detached. */
-GPRAPI void gpr_thd_options_set_joinable(gpr_thd_options* options);
+void gpr_thd_options_set_joinable(gpr_thd_options* options);
/** Returns non-zero if the option detached is set. */
-GPRAPI int gpr_thd_options_is_detached(const gpr_thd_options* options);
+int gpr_thd_options_is_detached(const gpr_thd_options* options);
/** Returns non-zero if the option joinable is set. */
-GPRAPI int gpr_thd_options_is_joinable(const gpr_thd_options* options);
-
-/** Returns the identifier of the current thread. */
-GPRAPI gpr_thd_id gpr_thd_currentid(void);
+int gpr_thd_options_is_joinable(const gpr_thd_options* options);
/** Blocks until the specified thread properly terminates.
Calling this on a detached thread has unpredictable results. */
-GPRAPI void gpr_thd_join(gpr_thd_id t);
+void gpr_thd_join(gpr_thd_id t);
+
+/* Internal interfaces between modules within the gpr support library. */
+void gpr_thd_init();
-#ifdef __cplusplus
-}
-#endif
+/* Wait for all outstanding threads to finish, up to deadline */
+int gpr_await_threads(gpr_timespec deadline);
-#endif /* GRPC_SUPPORT_THD_H */
+#endif /* GRPC_CORE_LIB_GPR_THD_H */
diff --git a/src/core/lib/gpr/thd_posix.cc b/src/core/lib/gpr/thd_posix.cc
index e8730b9c66..fcd174bfba 100644
--- a/src/core/lib/gpr/thd_posix.cc
+++ b/src/core/lib/gpr/thd_posix.cc
@@ -22,10 +22,12 @@
#ifdef GPR_POSIX_SYNC
+#include "src/core/lib/gpr/thd.h"
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/core/lib/gpr/thd_windows.cc b/src/core/lib/gpr/thd_windows.cc
index f920770f32..b467bd2662 100644
--- a/src/core/lib/gpr/thd_windows.cc
+++ b/src/core/lib/gpr/thd_windows.cc
@@ -22,9 +22,11 @@
#ifdef GPR_WINDOWS
+#include "src/core/lib/gpr/thd.h"
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
#include <string.h>
#if defined(_MSC_VER)
diff --git a/src/core/lib/gpr/time.cc b/src/core/lib/gpr/time.cc
index 39ebeb4339..64c1c98f56 100644
--- a/src/core/lib/gpr/time.cc
+++ b/src/core/lib/gpr/time.cc
@@ -18,6 +18,8 @@
/* Generic implementation of time calls. */
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <limits.h>
diff --git a/src/core/lib/gpr/time_posix.cc b/src/core/lib/gpr/time_posix.cc
index 09171c9c48..28836bfa54 100644
--- a/src/core/lib/gpr/time_posix.cc
+++ b/src/core/lib/gpr/time_posix.cc
@@ -17,6 +17,7 @@
*/
#include <grpc/support/port_platform.h>
+
#include "src/core/lib/gpr/time_precise.h"
#ifdef GPR_POSIX_TIME
diff --git a/src/core/lib/gpr/time_precise.cc b/src/core/lib/gpr/time_precise.cc
index 3c7aaabc40..1b34fd7eb1 100644
--- a/src/core/lib/gpr/time_precise.cc
+++ b/src/core/lib/gpr/time_precise.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <stdio.h>
diff --git a/src/core/lib/gpr/time_precise.h b/src/core/lib/gpr/time_precise.h
index acc4ee3d1b..a63ea9dc68 100644
--- a/src/core/lib/gpr/time_precise.h
+++ b/src/core/lib/gpr/time_precise.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_TIME_PRECISE_H
#define GRPC_CORE_LIB_GPR_TIME_PRECISE_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/time.h>
void gpr_precise_clock_init(void);
diff --git a/src/core/lib/gpr/tls_gcc.h b/src/core/lib/gpr/tls_gcc.h
index 14c59eca55..72b360b021 100644
--- a/src/core/lib/gpr/tls_gcc.h
+++ b/src/core/lib/gpr/tls_gcc.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_TLS_GCC_H
#define GRPC_CORE_LIB_GPR_TLS_GCC_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/support/log.h>
diff --git a/src/core/lib/gpr/tls_msvc.h b/src/core/lib/gpr/tls_msvc.h
index a6cc4174be..f4b3f0f50f 100644
--- a/src/core/lib/gpr/tls_msvc.h
+++ b/src/core/lib/gpr/tls_msvc.h
@@ -20,6 +20,8 @@
#define GRPC_CORE_LIB_GPR_TLS_MSVC_H
/** Thread local storage based on ms visual c compiler primitives.
+#include <grpc/support/port_platform.h>
+
#include tls.h to use this - and see that file for documentation */
struct gpr_msvc_thread_local {
diff --git a/src/core/lib/gpr/tls_pthread.h b/src/core/lib/gpr/tls_pthread.h
index 9202653dcb..a15f2f3389 100644
--- a/src/core/lib/gpr/tls_pthread.h
+++ b/src/core/lib/gpr/tls_pthread.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_TLS_PTHREAD_H
#define GRPC_CORE_LIB_GPR_TLS_PTHREAD_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h> /* for GPR_ASSERT */
#include <pthread.h>
diff --git a/src/core/lib/gpr/tmpfile.h b/src/core/lib/gpr/tmpfile.h
index f47ec7aa63..3ce3ff5e5d 100644
--- a/src/core/lib/gpr/tmpfile.h
+++ b/src/core/lib/gpr/tmpfile.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPR_TMPFILE_H
#define GRPC_CORE_LIB_GPR_TMPFILE_H
+#include <grpc/support/port_platform.h>
+
#include <stdio.h>
/* Creates a temporary file from a prefix.
diff --git a/src/core/lib/gprpp/atomic_with_atm.h b/src/core/lib/gprpp/atomic_with_atm.h
index 6abf0bc38d..3d0021bb1c 100644
--- a/src/core/lib/gprpp/atomic_with_atm.h
+++ b/src/core/lib/gprpp/atomic_with_atm.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H
#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_ATM_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
namespace grpc_core {
diff --git a/src/core/lib/gprpp/atomic_with_std.h b/src/core/lib/gprpp/atomic_with_std.h
index 83322b81c1..a4ad16e5cf 100644
--- a/src/core/lib/gprpp/atomic_with_std.h
+++ b/src/core/lib/gprpp/atomic_with_std.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H
#define GRPC_CORE_LIB_GPRPP_ATOMIC_WITH_STD_H
+#include <grpc/support/port_platform.h>
+
#include <atomic>
namespace grpc_core {
diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h
index 2ced3d74b8..ca95aecddc 100644
--- a/src/core/lib/gprpp/inlined_vector.h
+++ b/src/core/lib/gprpp/inlined_vector.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPRPP_INLINED_VECTOR_H
#define GRPC_CORE_LIB_GPRPP_INLINED_VECTOR_H
+#include <grpc/support/port_platform.h>
+
#include <cassert>
#include "src/core/lib/gprpp/memory.h"
diff --git a/src/core/lib/gprpp/manual_constructor.h b/src/core/lib/gprpp/manual_constructor.h
index cee38abc1b..a177048605 100644
--- a/src/core/lib/gprpp/manual_constructor.h
+++ b/src/core/lib/gprpp/manual_constructor.h
@@ -21,6 +21,8 @@
// manually construct a region of memory with some type
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include <stdlib.h>
#include <new>
diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h
index 17f42f5983..f84e20eeea 100644
--- a/src/core/lib/gprpp/memory.h
+++ b/src/core/lib/gprpp/memory.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPRPP_MEMORY_H
#define GRPC_CORE_LIB_GPRPP_MEMORY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <limits>
@@ -27,10 +29,15 @@
namespace grpc_core {
+// The alignment of memory returned by gpr_malloc().
+constexpr size_t kAllignmentForDefaultAllocationInBytes = 8;
+
// Alternative to new, since we cannot use it (for fear of libstdc++)
template <typename T, typename... Args>
inline T* New(Args&&... args) {
- void* p = gpr_malloc(sizeof(T));
+ void* p = alignof(T) > kAllignmentForDefaultAllocationInBytes
+ ? gpr_malloc_aligned(sizeof(T), alignof(T))
+ : gpr_malloc(sizeof(T));
return new (p) T(std::forward<Args>(args)...);
}
@@ -38,7 +45,11 @@ inline T* New(Args&&... args) {
template <typename T>
inline void Delete(T* p) {
p->~T();
- gpr_free(p);
+ if (alignof(T) > kAllignmentForDefaultAllocationInBytes) {
+ gpr_free_aligned(p);
+ } else {
+ gpr_free(p);
+ }
}
template <typename T>
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index 78d1b01ff8..a5bc8d8efc 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -19,9 +19,12 @@
#ifndef GRPC_CORE_LIB_GPRPP_ORPHANABLE_H
#define GRPC_CORE_LIB_GPRPP_ORPHANABLE_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include <cinttypes>
#include <memory>
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index ab589fc01a..46bfaf7fb8 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -19,9 +19,13 @@
#ifndef GRPC_CORE_LIB_GPRPP_REF_COUNTED_H
#define GRPC_CORE_LIB_GPRPP_REF_COUNTED_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include <cinttypes>
+
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/debug_location.h"
diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index f82ba50da3..388e2ec410 100644
--- a/src/core/lib/gprpp/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H
#define GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H
+#include <grpc/support/port_platform.h>
+
#include <utility>
#include "src/core/lib/gprpp/memory.h"
@@ -31,6 +33,7 @@ template <typename T>
class RefCountedPtr {
public:
RefCountedPtr() {}
+ RefCountedPtr(std::nullptr_t) {}
// If value is non-null, we take ownership of a ref to it.
explicit RefCountedPtr(T* value) { value_ = value; }
diff --git a/src/core/lib/http/format_request.cc b/src/core/lib/http/format_request.cc
index 6581bef7cd..1712344648 100644
--- a/src/core/lib/http/format_request.cc
+++ b/src/core/lib/http/format_request.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/http/format_request.h"
#include <stdarg.h>
diff --git a/src/core/lib/http/format_request.h b/src/core/lib/http/format_request.h
index c1919651f9..bcc332fe6e 100644
--- a/src/core/lib/http/format_request.h
+++ b/src/core/lib/http/format_request.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H
#define GRPC_CORE_LIB_HTTP_FORMAT_REQUEST_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include "src/core/lib/http/httpcli.h"
diff --git a/src/core/lib/http/httpcli.cc b/src/core/lib/http/httpcli.cc
index 2cdca48487..12060074c5 100644
--- a/src/core/lib/http/httpcli.cc
+++ b/src/core/lib/http/httpcli.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/http/httpcli.h"
#include <string.h>
diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h
index 72d20cc7a3..b0735081f2 100644
--- a/src/core/lib/http/httpcli.h
+++ b/src/core/lib/http/httpcli.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_HTTP_HTTPCLI_H
#define GRPC_CORE_LIB_HTTP_HTTPCLI_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include <grpc/support/time.h>
diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc
index d754558060..180912383f 100644
--- a/src/core/lib/http/httpcli_security_connector.cc
+++ b/src/core/lib/http/httpcli_security_connector.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/http/httpcli.h"
#include <string.h>
diff --git a/src/core/lib/http/parser.cc b/src/core/lib/http/parser.cc
index 724b6d1885..a37fdda8ea 100644
--- a/src/core/lib/http/parser.cc
+++ b/src/core/lib/http/parser.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/http/parser.h"
#include <stdbool.h>
diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h
index 5fef448019..1d2e13e831 100644
--- a/src/core/lib/http/parser.h
+++ b/src/core/lib/http/parser.h
@@ -19,8 +19,9 @@
#ifndef GRPC_CORE_LIB_HTTP_PARSER_H
#define GRPC_CORE_LIB_HTTP_PARSER_H
-#include <grpc/slice.h>
#include <grpc/support/port_platform.h>
+
+#include <grpc/slice.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/error.h"
diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc
index 3b11e0266d..24e11b687b 100644
--- a/src/core/lib/iomgr/call_combiner.cc
+++ b/src/core/lib/iomgr/call_combiner.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/call_combiner.h"
#include <inttypes.h>
diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h
index 4814dbf8d2..16829e5707 100644
--- a/src/core/lib/iomgr/call_combiner.h
+++ b/src/core/lib/iomgr/call_combiner.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_CALL_COMBINER_H
#define GRPC_CORE_LIB_IOMGR_CALL_COMBINER_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include <grpc/support/atm.h>
diff --git a/src/core/lib/iomgr/combiner.cc b/src/core/lib/iomgr/combiner.cc
index a7edf17e9b..e66df03182 100644
--- a/src/core/lib/iomgr/combiner.cc
+++ b/src/core/lib/iomgr/combiner.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/combiner.h"
#include <assert.h>
diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h
index c62d21a051..0d63e468df 100644
--- a/src/core/lib/iomgr/combiner.h
+++ b/src/core/lib/iomgr/combiner.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_COMBINER_H
#define GRPC_CORE_LIB_IOMGR_COMBINER_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include <grpc/support/atm.h>
diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc
index 9d4b102822..e22c21e4bd 100644
--- a/src/core/lib/iomgr/endpoint.cc
+++ b/src/core/lib/iomgr/endpoint.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/endpoint.h"
void grpc_endpoint_read(grpc_endpoint* ep, grpc_slice_buffer* slices,
diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h
index cd53099334..15db1649fa 100644
--- a/src/core/lib/iomgr/endpoint.h
+++ b/src/core/lib/iomgr/endpoint.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_H
#define GRPC_CORE_LIB_IOMGR_ENDPOINT_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/time.h>
diff --git a/src/core/lib/iomgr/endpoint_pair.h b/src/core/lib/iomgr/endpoint_pair.h
index 506ffc88b4..08f9e3cabc 100644
--- a/src/core/lib/iomgr/endpoint_pair.h
+++ b/src/core/lib/iomgr/endpoint_pair.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H
#define GRPC_CORE_LIB_IOMGR_ENDPOINT_PAIR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/endpoint.h"
typedef struct {
diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc
index 3ad6b47756..49850ab3a1 100644
--- a/src/core/lib/iomgr/endpoint_pair_posix.cc
+++ b/src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/endpoint_pair_uv.cc b/src/core/lib/iomgr/endpoint_pair_uv.cc
index 128a947d1b..b99d178cb6 100644
--- a/src/core/lib/iomgr/endpoint_pair_uv.cc
+++ b/src/core/lib/iomgr/endpoint_pair_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc
index cc07ac0708..416c9d88a1 100644
--- a/src/core/lib/iomgr/endpoint_pair_windows.cc
+++ b/src/core/lib/iomgr/endpoint_pair_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h
index 8c72a439f6..f8cae4da82 100644
--- a/src/core/lib/iomgr/error.h
+++ b/src/core/lib/iomgr/error.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_ERROR_H
#define GRPC_CORE_LIB_IOMGR_ERROR_H
+#include <grpc/support/port_platform.h>
+
#include <inttypes.h>
#include <stdbool.h>
diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h
index 6cb09c2cdb..7fde347abd 100644
--- a/src/core/lib/iomgr/error_internal.h
+++ b/src/core/lib/iomgr/error_internal.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H
#define GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H
+#include <grpc/support/port_platform.h>
+
#include <inttypes.h>
#include <stdbool.h> // TODO, do we need this?
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index f84f3f8205..3ebaf181c1 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include <grpc/support/log.h>
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.h b/src/core/lib/iomgr/ev_epoll1_linux.h
index 9a1b96bd45..ca0db7250f 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.h
+++ b/src/core/lib/iomgr/ev_epoll1_linux.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EV_EPOLL1_LINUX_H
#define GRPC_CORE_LIB_IOMGR_EV_EPOLL1_LINUX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 8bce34b2fd..d3cbaf9d0a 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include <grpc/support/log.h>
@@ -57,7 +59,7 @@
//#define GRPC_EPOLLEX_CREATE_WORKERS_ON_HEAP 1
#define MAX_EPOLL_EVENTS 100
-#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 1
+#define MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL 16
grpc_core::DebugOnlyTraceFlag grpc_trace_pollable_refcount(false,
"pollable_refcount");
@@ -196,6 +198,7 @@ struct grpc_pollset_worker {
struct grpc_pollset {
gpr_mu mu;
+ gpr_atm worker_count;
pollable* active_pollable;
bool kicked_without_poller;
grpc_closure* shutdown_closure;
@@ -683,6 +686,7 @@ static grpc_error* pollset_kick_all(grpc_pollset* pollset) {
static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) {
gpr_mu_init(&pollset->mu);
+ gpr_atm_no_barrier_store(&pollset->worker_count, 0);
pollset->active_pollable = POLLABLE_REF(g_empty_pollable, "pollset");
pollset->kicked_without_poller = false;
pollset->shutdown_closure = nullptr;
@@ -756,8 +760,20 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
pollable* pollable_obj, bool drain) {
GPR_TIMER_SCOPE("pollable_process_events", 0);
static const char* err_desc = "pollset_process_events";
+ // Use a simple heuristic to determine how many fd events to process
+ // per loop iteration. (events/workers)
+ int handle_count = 1;
+ int worker_count = gpr_atm_no_barrier_load(&pollset->worker_count);
+ GPR_ASSERT(worker_count > 0);
+ handle_count =
+ (pollable_obj->event_count - pollable_obj->event_cursor) / worker_count;
+ if (handle_count == 0) {
+ handle_count = 1;
+ } else if (handle_count > MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL) {
+ handle_count = MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL;
+ }
grpc_error* error = GRPC_ERROR_NONE;
- for (int i = 0; (drain || i < MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL) &&
+ for (int i = 0; (drain || i < handle_count) &&
pollable_obj->event_cursor != pollable_obj->event_count;
i++) {
int n = pollable_obj->event_cursor++;
@@ -799,6 +815,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
static void pollset_destroy(grpc_pollset* pollset) {
POLLABLE_UNREF(pollset->active_pollable, "pollset");
pollset->active_pollable = nullptr;
+ gpr_mu_destroy(&pollset->mu);
}
static grpc_error* pollable_epoll(pollable* p, grpc_millis deadline) {
@@ -881,6 +898,7 @@ static bool begin_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
GPR_TIMER_SCOPE("begin_worker", 0);
bool do_poll =
(pollset->shutdown_closure == nullptr && !pollset->already_shutdown);
+ gpr_atm_no_barrier_fetch_add(&pollset->worker_count, 1);
if (worker_hdl != nullptr) *worker_hdl = worker;
worker->initialized_cv = false;
worker->kicked = false;
@@ -961,6 +979,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker,
if (worker->initialized_cv) {
gpr_cv_destroy(&worker->cv);
}
+ gpr_atm_no_barrier_fetch_add(&pollset->worker_count, -1);
}
#ifndef NDEBUG
diff --git a/src/core/lib/iomgr/ev_epollex_linux.h b/src/core/lib/iomgr/ev_epollex_linux.h
index ffa7fc7f32..e70ba72a7d 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.h
+++ b/src/core/lib/iomgr/ev_epollex_linux.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EV_EPOLLEX_LINUX_H
#define GRPC_CORE_LIB_IOMGR_EV_EPOLLEX_LINUX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 5c99c72aa5..1e30f6637b 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include <grpc/grpc_posix.h>
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.h b/src/core/lib/iomgr/ev_epollsig_linux.h
index 48178d3713..2ba2f0a63b 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.h
+++ b/src/core/lib/iomgr/ev_epollsig_linux.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EV_EPOLLSIG_LINUX_H
#define GRPC_CORE_LIB_IOMGR_EV_EPOLLSIG_LINUX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index e92163322f..e979ff7eb5 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
@@ -33,10 +35,10 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/murmur_hash.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/tls.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/block_annotate.h"
diff --git a/src/core/lib/iomgr/ev_poll_posix.h b/src/core/lib/iomgr/ev_poll_posix.h
index f6bc624d4f..ab3cd9029e 100644
--- a/src/core/lib/iomgr/ev_poll_posix.h
+++ b/src/core/lib/iomgr/ev_poll_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EV_POLL_POSIX_H
#define GRPC_CORE_LIB_IOMGR_EV_POLL_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/ev_posix.h"
const grpc_event_engine_vtable* grpc_init_poll_posix(bool explicit_request);
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 4280794428..39ce459f1e 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 62f1162a23..6a5129a74d 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EV_POSIX_H
#define GRPC_CORE_LIB_IOMGR_EV_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include <poll.h>
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/lib/iomgr/ev_windows.cc b/src/core/lib/iomgr/ev_windows.cc
index 697697d0b0..32c62b7a76 100644
--- a/src/core/lib/iomgr/ev_windows.cc
+++ b/src/core/lib/iomgr/ev_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc
index 5401a94dd3..132fe87870 100644
--- a/src/core/lib/iomgr/exec_ctx.cc
+++ b/src/core/lib/iomgr/exec_ctx.cc
@@ -16,12 +16,14 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/exec_ctx.h"
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/profiling/timers.h"
diff --git a/src/core/lib/iomgr/exec_ctx.h b/src/core/lib/iomgr/exec_ctx.h
index 3d9a157627..de97164f02 100644
--- a/src/core/lib/iomgr/exec_ctx.h
+++ b/src/core/lib/iomgr/exec_ctx.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EXEC_CTX_H
#define GRPC_CORE_LIB_IOMGR_EXEC_CTX_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc
index 7ab987c19e..e7f412a562 100644
--- a/src/core/lib/iomgr/executor.cc
+++ b/src/core/lib/iomgr/executor.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/executor.h"
#include <string.h>
@@ -24,10 +26,10 @@
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/gpr/spinlock.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/tls.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index e16f11aa21..68d540af55 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_EXECUTOR_H
#define GRPC_CORE_LIB_IOMGR_EXECUTOR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/closure.h"
typedef enum {
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
index c581dae1ae..d32fbc4588 100644
--- a/src/core/lib/iomgr/fork_posix.cc
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_FORK
@@ -24,11 +26,10 @@
#include <grpc/fork.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/fork.h"
-#include "src/core/lib/gpr/thd_internal.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/timer_manager.h"
diff --git a/src/core/lib/iomgr/fork_windows.cc b/src/core/lib/iomgr/fork_windows.cc
index f9986f33c7..798f671bdf 100644
--- a/src/core/lib/iomgr/fork_windows.cc
+++ b/src/core/lib/iomgr/fork_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifndef GRPC_POSIX_FORK
diff --git a/src/core/lib/iomgr/gethostname_fallback.cc b/src/core/lib/iomgr/gethostname_fallback.cc
index 81e2c7aeec..65ae818723 100644
--- a/src/core/lib/iomgr/gethostname_fallback.cc
+++ b/src/core/lib/iomgr/gethostname_fallback.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/gethostname_host_name_max.cc b/src/core/lib/iomgr/gethostname_host_name_max.cc
index ae95788a1e..79f5daa8f3 100644
--- a/src/core/lib/iomgr/gethostname_host_name_max.cc
+++ b/src/core/lib/iomgr/gethostname_host_name_max.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/gethostname_sysconf.cc b/src/core/lib/iomgr/gethostname_sysconf.cc
index 3d74e03338..92c5de3338 100644
--- a/src/core/lib/iomgr/gethostname_sysconf.cc
+++ b/src/core/lib/iomgr/gethostname_sysconf.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/gethostname.h"
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/iocp_windows.cc b/src/core/lib/iomgr/iocp_windows.cc
index d730ce4624..5285734719 100644
--- a/src/core/lib/iomgr/iocp_windows.cc
+++ b/src/core/lib/iomgr/iocp_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
@@ -26,9 +28,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/log_windows.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/debug/stats.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/iocp_windows.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/socket_windows.h"
diff --git a/src/core/lib/iomgr/iocp_windows.h b/src/core/lib/iomgr/iocp_windows.h
index 75b0ff4a92..5079ea5d84 100644
--- a/src/core/lib/iomgr/iocp_windows.h
+++ b/src/core/lib/iomgr/iocp_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOCP_WINDOWS_H
#define GRPC_CORE_LIB_IOMGR_IOCP_WINDOWS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc
index 9e407a29a8..70a80e1998 100644
--- a/src/core/lib/iomgr/iomgr.cc
+++ b/src/core/lib/iomgr/iomgr.cc
@@ -28,10 +28,10 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index c7cde7ea59..e6d66e545c 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_H
#define GRPC_CORE_LIB_IOMGR_IOMGR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
/** Initializes the iomgr. */
diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h
index 20b3cb70d0..644219fb4d 100644
--- a/src/core/lib/iomgr/iomgr_internal.h
+++ b/src/core/lib/iomgr/iomgr_internal.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H
#define GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include "src/core/lib/iomgr/iomgr.h"
diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc
index f8f6fe2353..35b8adf01e 100644
--- a/src/core/lib/iomgr/iomgr_posix.cc
+++ b/src/core/lib/iomgr/iomgr_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/iomgr_posix.h b/src/core/lib/iomgr/iomgr_posix.h
index f7a4af6a89..54ec46e1bb 100644
--- a/src/core/lib/iomgr/iomgr_posix.h
+++ b/src/core/lib/iomgr/iomgr_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H
#define GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/iomgr_internal.h"
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_POSIX_H */
diff --git a/src/core/lib/iomgr/iomgr_uv.cc b/src/core/lib/iomgr/iomgr_uv.cc
index 9614c2e664..c11c37ca20 100644
--- a/src/core/lib/iomgr/iomgr_uv.cc
+++ b/src/core/lib/iomgr/iomgr_uv.cc
@@ -16,10 +16,14 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
+#include <grpc/support/thd_id.h>
+
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_uv.h"
diff --git a/src/core/lib/iomgr/iomgr_uv.h b/src/core/lib/iomgr/iomgr_uv.h
index 3b4daaa73b..4d62f00ad6 100644
--- a/src/core/lib/iomgr/iomgr_uv.h
+++ b/src/core/lib/iomgr/iomgr_uv.h
@@ -19,9 +19,11 @@
#ifndef GRPC_CORE_LIB_IOMGR_IOMGR_UV_H
#define GRPC_CORE_LIB_IOMGR_IOMGR_UV_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/iomgr_internal.h"
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
/* The thread ID of the thread on which grpc was initialized. Used to verify
* that all calls into libuv are made on that same thread */
diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc
index 630370166d..8c4888ca97 100644
--- a/src/core/lib/iomgr/iomgr_windows.cc
+++ b/src/core/lib/iomgr/iomgr_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/is_epollexclusive_available.cc b/src/core/lib/iomgr/is_epollexclusive_available.cc
index 542cc41e8f..036b77866f 100644
--- a/src/core/lib/iomgr/is_epollexclusive_available.cc
+++ b/src/core/lib/iomgr/is_epollexclusive_available.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include "src/core/lib/iomgr/is_epollexclusive_available.h"
@@ -37,7 +39,7 @@ bool grpc_is_epollexclusive_available(void) {
int fd = epoll_create1(EPOLL_CLOEXEC);
if (fd < 0) {
if (!logged_why_not) {
- gpr_log(GPR_ERROR,
+ gpr_log(GPR_DEBUG,
"epoll_create1 failed with error: %d. Not using epollex polling "
"engine.",
fd);
@@ -48,7 +50,7 @@ bool grpc_is_epollexclusive_available(void) {
int evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
if (evfd < 0) {
if (!logged_why_not) {
- gpr_log(GPR_ERROR,
+ gpr_log(GPR_DEBUG,
"eventfd failed with error: %d. Not using epollex polling "
"engine.",
fd);
@@ -80,7 +82,7 @@ bool grpc_is_epollexclusive_available(void) {
}
} else {
if (!logged_why_not) {
- gpr_log(GPR_ERROR,
+ gpr_log(GPR_DEBUG,
"epoll_ctl with EPOLLEXCLUSIVE | EPOLLONESHOT succeeded. This is "
"evidence of no EPOLLEXCLUSIVE support. Not using "
"epollex polling engine.");
diff --git a/src/core/lib/iomgr/is_epollexclusive_available.h b/src/core/lib/iomgr/is_epollexclusive_available.h
index 9ae9c5c191..8a44113c3f 100644
--- a/src/core/lib/iomgr/is_epollexclusive_available.h
+++ b/src/core/lib/iomgr/is_epollexclusive_available.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_IS_EPOLLEXCLUSIVE_AVAILABLE_H
#define GRPC_CORE_LIB_IOMGR_IS_EPOLLEXCLUSIVE_AVAILABLE_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#ifdef __cplusplus
diff --git a/src/core/lib/iomgr/load_file.cc b/src/core/lib/iomgr/load_file.cc
index 7f5f642c98..f6431d0f1c 100644
--- a/src/core/lib/iomgr/load_file.cc
+++ b/src/core/lib/iomgr/load_file.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/load_file.h"
#include <errno.h>
diff --git a/src/core/lib/iomgr/load_file.h b/src/core/lib/iomgr/load_file.h
index a7336527ce..1cb2b5de73 100644
--- a/src/core/lib/iomgr/load_file.h
+++ b/src/core/lib/iomgr/load_file.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_LOAD_FILE_H
#define GRPC_CORE_LIB_IOMGR_LOAD_FILE_H
+#include <grpc/support/port_platform.h>
+
#include <stdio.h>
#include <grpc/slice.h>
diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc
index 7b194e3db5..5b6b79fa91 100644
--- a/src/core/lib/iomgr/lockfree_event.cc
+++ b/src/core/lib/iomgr/lockfree_event.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/lockfree_event.h"
#include <grpc/support/log.h>
diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h
index 3bd3fd72f1..83de656f5f 100644
--- a/src/core/lib/iomgr/lockfree_event.h
+++ b/src/core/lib/iomgr/lockfree_event.h
@@ -21,6 +21,8 @@
/* Lock free event notification for file descriptors */
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/atm.h>
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/iomgr/nameser.h b/src/core/lib/iomgr/nameser.h
index daed6de518..22a00cdab8 100644
--- a/src/core/lib/iomgr/nameser.h
+++ b/src/core/lib/iomgr/nameser.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_NAMESER_H
#define GRPC_CORE_LIB_IOMGR_NAMESER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_ARPA_NAMESER
diff --git a/src/core/lib/iomgr/network_status_tracker.cc b/src/core/lib/iomgr/network_status_tracker.cc
index 73f8fbf9fb..d4b7f4a57d 100644
--- a/src/core/lib/iomgr/network_status_tracker.cc
+++ b/src/core/lib/iomgr/network_status_tracker.cc
@@ -16,8 +16,10 @@
*
*/
-#include "src/core/lib/iomgr/network_status_tracker.h"
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/network_status_tracker.h"
void grpc_network_status_shutdown(void) {}
diff --git a/src/core/lib/iomgr/network_status_tracker.h b/src/core/lib/iomgr/network_status_tracker.h
index 32244d9b77..198877f60f 100644
--- a/src/core/lib/iomgr/network_status_tracker.h
+++ b/src/core/lib/iomgr/network_status_tracker.h
@@ -18,6 +18,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H
#define GRPC_CORE_LIB_IOMGR_NETWORK_STATUS_TRACKER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/endpoint.h"
void grpc_network_status_init(void);
diff --git a/src/core/lib/iomgr/polling_entity.cc b/src/core/lib/iomgr/polling_entity.cc
index 126f6f45d6..9f164f65b0 100644
--- a/src/core/lib/iomgr/polling_entity.cc
+++ b/src/core/lib/iomgr/polling_entity.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
diff --git a/src/core/lib/iomgr/polling_entity.h b/src/core/lib/iomgr/polling_entity.h
index 0102d32c11..a95e08524c 100644
--- a/src/core/lib/iomgr/polling_entity.h
+++ b/src/core/lib/iomgr/polling_entity.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H
#define GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_set.h"
diff --git a/src/core/lib/iomgr/pollset.h b/src/core/lib/iomgr/pollset.h
index 6bb3cd3e0c..9cc3e4c7fa 100644
--- a/src/core/lib/iomgr/pollset.h
+++ b/src/core/lib/iomgr/pollset.h
@@ -20,6 +20,7 @@
#define GRPC_CORE_LIB_IOMGR_POLLSET_H
#include <grpc/support/port_platform.h>
+
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
diff --git a/src/core/lib/iomgr/pollset_set.h b/src/core/lib/iomgr/pollset_set.h
index a94d0afe75..18f30aa94e 100644
--- a/src/core/lib/iomgr/pollset_set.h
+++ b/src/core/lib/iomgr/pollset_set.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_H
#define GRPC_CORE_LIB_IOMGR_POLLSET_SET_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/pollset.h"
/* A grpc_pollset_set is a set of pollsets that are interested in an
diff --git a/src/core/lib/iomgr/pollset_set_uv.cc b/src/core/lib/iomgr/pollset_set_uv.cc
index ac5dade8a5..50814c1f0a 100644
--- a/src/core/lib/iomgr/pollset_set_uv.cc
+++ b/src/core/lib/iomgr/pollset_set_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/pollset_set_windows.cc b/src/core/lib/iomgr/pollset_set_windows.cc
index 85edc9dee1..ff3f6a944e 100644
--- a/src/core/lib/iomgr/pollset_set_windows.cc
+++ b/src/core/lib/iomgr/pollset_set_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <stdint.h>
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/pollset_set_windows.h b/src/core/lib/iomgr/pollset_set_windows.h
index 1173f760a0..5ac9d1823b 100644
--- a/src/core/lib/iomgr/pollset_set_windows.h
+++ b/src/core/lib/iomgr/pollset_set_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H
#define GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/pollset_set.h"
#endif /* GRPC_CORE_LIB_IOMGR_POLLSET_SET_WINDOWS_H */
diff --git a/src/core/lib/iomgr/pollset_uv.cc b/src/core/lib/iomgr/pollset_uv.cc
index d9e5ad81be..c6a2f43bf1 100644
--- a/src/core/lib/iomgr/pollset_uv.cc
+++ b/src/core/lib/iomgr/pollset_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/pollset_windows.cc b/src/core/lib/iomgr/pollset_windows.cc
index 6ef949aad7..62ab760875 100644
--- a/src/core/lib/iomgr/pollset_windows.cc
+++ b/src/core/lib/iomgr/pollset_windows.cc
@@ -16,13 +16,15 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/iocp_windows.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/pollset.h"
diff --git a/src/core/lib/iomgr/pollset_windows.h b/src/core/lib/iomgr/pollset_windows.h
index 93fe7d669b..e89758c694 100644
--- a/src/core/lib/iomgr/pollset_windows.h
+++ b/src/core/lib/iomgr/pollset_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_POLLSET_WINDOWS_H
#define GRPC_CORE_LIB_IOMGR_POLLSET_WINDOWS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/port.h"
diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h
index 12fc2ed088..10a7822654 100644
--- a/src/core/lib/iomgr/resolve_address.h
+++ b/src/core/lib/iomgr/resolve_address.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H
#define GRPC_CORE_LIB_IOMGR_RESOLVE_ADDRESS_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/pollset_set.h"
diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index dd5363dc0a..9307f19bcf 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
@@ -29,11 +31,11 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/executor.h"
diff --git a/src/core/lib/iomgr/resolve_address_uv.cc b/src/core/lib/iomgr/resolve_address_uv.cc
index 6eb6fe3af5..4d8ea596f3 100644
--- a/src/core/lib/iomgr/resolve_address_uv.cc
+++ b/src/core/lib/iomgr/resolve_address_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc
index e875d77fd8..4e1dcaabaf 100644
--- a/src/core/lib/iomgr/resolve_address_windows.cc
+++ b/src/core/lib/iomgr/resolve_address_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
@@ -31,11 +33,11 @@
#include <grpc/support/log.h>
#include <grpc/support/log_windows.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/block_annotate.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
diff --git a/src/core/lib/iomgr/resource_quota.cc b/src/core/lib/iomgr/resource_quota.cc
index c4763f3229..8c42dd78cf 100644
--- a/src/core/lib/iomgr/resource_quota.cc
+++ b/src/core/lib/iomgr/resource_quota.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/resource_quota.h"
#include <inttypes.h>
diff --git a/src/core/lib/iomgr/resource_quota.h b/src/core/lib/iomgr/resource_quota.h
index 39e3aabf18..4e1c651278 100644
--- a/src/core/lib/iomgr/resource_quota.h
+++ b/src/core/lib/iomgr/resource_quota.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
#define GRPC_CORE_LIB_IOMGR_RESOURCE_QUOTA_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/lib/iomgr/sockaddr.h b/src/core/lib/iomgr/sockaddr.h
index 206d596ccd..3b30da8a7d 100644
--- a/src/core/lib/iomgr/sockaddr.h
+++ b/src/core/lib/iomgr/sockaddr.h
@@ -23,6 +23,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_H
#define GRPC_CORE_LIB_IOMGR_SOCKADDR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/sockaddr_posix.h b/src/core/lib/iomgr/sockaddr_posix.h
index 22d57ca6bb..83981e0aa5 100644
--- a/src/core/lib/iomgr/sockaddr_posix.h
+++ b/src/core/lib/iomgr/sockaddr_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H
#define GRPC_CORE_LIB_IOMGR_SOCKADDR_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 69be87168e..88f9b2ffd9 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include <errno.h>
@@ -24,7 +26,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/host_port.h"
diff --git a/src/core/lib/iomgr/sockaddr_utils.h b/src/core/lib/iomgr/sockaddr_utils.h
index e3bd51a4ad..ace54a2a80 100644
--- a/src/core/lib/iomgr/sockaddr_utils.h
+++ b/src/core/lib/iomgr/sockaddr_utils.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H
#define GRPC_CORE_LIB_IOMGR_SOCKADDR_UTILS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/resolve_address.h"
/* Returns true if addr is an IPv4-mapped IPv6 address within the
diff --git a/src/core/lib/iomgr/sockaddr_windows.h b/src/core/lib/iomgr/sockaddr_windows.h
index 20e37c9fc4..3a4fcc9e8a 100644
--- a/src/core/lib/iomgr/sockaddr_windows.h
+++ b/src/core/lib/iomgr/sockaddr_windows.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_WINDOWS_H
#define GRPC_CORE_LIB_IOMGR_SOCKADDR_WINDOWS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/socket_factory_posix.cc b/src/core/lib/iomgr/socket_factory_posix.cc
index 3e696c2e10..1d1e36c0e3 100644
--- a/src/core/lib/iomgr/socket_factory_posix.cc
+++ b/src/core/lib/iomgr/socket_factory_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/socket_factory_posix.h b/src/core/lib/iomgr/socket_factory_posix.h
index af57cc5b60..9a52f4ea4e 100644
--- a/src/core/lib/iomgr/socket_factory_posix.h
+++ b/src/core/lib/iomgr/socket_factory_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_FACTORY_POSIX_H
#define GRPC_CORE_LIB_IOMGR_SOCKET_FACTORY_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/resolve_address.h"
diff --git a/src/core/lib/iomgr/socket_mutator.cc b/src/core/lib/iomgr/socket_mutator.cc
index eb219d7cb3..b9b8eaf4ad 100644
--- a/src/core/lib/iomgr/socket_mutator.cc
+++ b/src/core/lib/iomgr/socket_mutator.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/socket_mutator.h"
#include <grpc/impl/codegen/grpc_types.h>
diff --git a/src/core/lib/iomgr/socket_mutator.h b/src/core/lib/iomgr/socket_mutator.h
index f8fd21d15a..6c7781c51d 100644
--- a/src/core/lib/iomgr/socket_mutator.h
+++ b/src/core/lib/iomgr/socket_mutator.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H
#define GRPC_CORE_LIB_IOMGR_SOCKET_MUTATOR_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/sync.h>
diff --git a/src/core/lib/iomgr/socket_utils.h b/src/core/lib/iomgr/socket_utils.h
index 9fd141b6de..e96eb97a7e 100644
--- a/src/core/lib/iomgr/socket_utils.h
+++ b/src/core/lib/iomgr/socket_utils.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_H
#define GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
/* A wrapper for inet_ntop on POSIX systems and InetNtop on Windows systems */
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.cc b/src/core/lib/iomgr/socket_utils_common_posix.cc
index a0cca6195b..4fb6c7ad63 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_common_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
@@ -37,7 +39,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/sync.h>
#include "src/core/lib/gpr/host_port.h"
diff --git a/src/core/lib/iomgr/socket_utils_linux.cc b/src/core/lib/iomgr/socket_utils_linux.cc
index e8bf05c3a8..deb7c55267 100644
--- a/src/core/lib/iomgr/socket_utils_linux.cc
+++ b/src/core/lib/iomgr/socket_utils_linux.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_LINUX_SOCKETUTILS
diff --git a/src/core/lib/iomgr/socket_utils_posix.cc b/src/core/lib/iomgr/socket_utils_posix.cc
index c49cbb203b..c856f641e3 100644
--- a/src/core/lib/iomgr/socket_utils_posix.cc
+++ b/src/core/lib/iomgr/socket_utils_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKETUTILS
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index 77df4205ff..1f50e8d315 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H
#define GRPC_CORE_LIB_IOMGR_SOCKET_UTILS_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/resolve_address.h"
#include <sys/socket.h>
diff --git a/src/core/lib/iomgr/socket_utils_uv.cc b/src/core/lib/iomgr/socket_utils_uv.cc
index 75316d8c24..3f650eef66 100644
--- a/src/core/lib/iomgr/socket_utils_uv.cc
+++ b/src/core/lib/iomgr/socket_utils_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/socket_utils_windows.cc b/src/core/lib/iomgr/socket_utils_windows.cc
index 0482a1783d..5fc3b7617e 100644
--- a/src/core/lib/iomgr/socket_utils_windows.cc
+++ b/src/core/lib/iomgr/socket_utils_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINDOWS_SOCKETUTILS
diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc
index 9bb6a75dd8..2e23409582 100644
--- a/src/core/lib/iomgr/socket_windows.cc
+++ b/src/core/lib/iomgr/socket_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h
index cb28f2b8df..3ff2c307e2 100644
--- a/src/core/lib/iomgr/socket_windows.h
+++ b/src/core/lib/iomgr/socket_windows.h
@@ -20,6 +20,7 @@
#define GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H
#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/sys_epoll_wrapper.h b/src/core/lib/iomgr/sys_epoll_wrapper.h
index 3fa5357156..d21d853665 100644
--- a/src/core/lib/iomgr/sys_epoll_wrapper.h
+++ b/src/core/lib/iomgr/sys_epoll_wrapper.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_SYS_EPOLL_WRAPPER_H
#define GRPC_CORE_LIB_IOMGR_SYS_EPOLL_WRAPPER_H
+#include <grpc/support/port_platform.h>
+
#include <sys/epoll.h>
#ifndef EPOLLEXCLUSIVE
diff --git a/src/core/lib/iomgr/tcp_client.h b/src/core/lib/iomgr/tcp_client.h
index 5f55d30955..a6b99e63c2 100644
--- a/src/core/lib/iomgr/tcp_client.h
+++ b/src/core/lib/iomgr/tcp_client.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H
#define GRPC_CORE_LIB_IOMGR_TCP_CLIENT_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/endpoint.h"
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 33a0b0404d..3fe2989c6b 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/tcp_client_posix.h b/src/core/lib/iomgr/tcp_client_posix.h
index 57e50a67d2..d0168ef133 100644
--- a/src/core/lib/iomgr/tcp_client_posix.h
+++ b/src/core/lib/iomgr/tcp_client_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TCP_CLIENT_POSIX_H
#define GRPC_CORE_LIB_IOMGR_TCP_CLIENT_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/tcp_client.h"
diff --git a/src/core/lib/iomgr/tcp_client_uv.cc b/src/core/lib/iomgr/tcp_client_uv.cc
index 4e9c7cc11d..d29d6c8f41 100644
--- a/src/core/lib/iomgr/tcp_client_uv.cc
+++ b/src/core/lib/iomgr/tcp_client_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc
index d46569d7cc..70c2495350 100644
--- a/src/core/lib/iomgr/tcp_client_windows.cc
+++ b/src/core/lib/iomgr/tcp_client_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include <inttypes.h>
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index 50efd04382..ca0046b83b 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/tcp_posix.h b/src/core/lib/iomgr/tcp_posix.h
index 4529c02beb..af89bd24db 100644
--- a/src/core/lib/iomgr/tcp_posix.h
+++ b/src/core/lib/iomgr/tcp_posix.h
@@ -29,6 +29,8 @@
otherwise specified.
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/ev_posix.h"
diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h
index 038c765c6c..965d97407f 100644
--- a/src/core/lib/iomgr/tcp_server.h
+++ b/src/core/lib/iomgr/tcp_server.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TCP_SERVER_H
#define GRPC_CORE_LIB_IOMGR_TCP_SERVER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/closure.h"
diff --git a/src/core/lib/iomgr/tcp_server_posix.cc b/src/core/lib/iomgr/tcp_server_posix.cc
index fe6108e4ac..a609c09ea7 100644
--- a/src/core/lib/iomgr/tcp_server_posix.cc
+++ b/src/core/lib/iomgr/tcp_server_posix.cc
@@ -21,6 +21,8 @@
#define _GNU_SOURCE
#endif
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix.h b/src/core/lib/iomgr/tcp_server_utils_posix.h
index 6046f257f9..34d68130c9 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix.h
+++ b/src/core/lib/iomgr/tcp_server_utils_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
#define GRPC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
index be2a00a9dc..846f9cccb7 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_common.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc b/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc
index 612c2584bc..308ff0f8a6 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_IFADDRS
diff --git a/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc b/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc
index 2d72b95def..86ee14f285 100644
--- a/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc
+++ b/src/core/lib/iomgr/tcp_server_utils_posix_noifaddrs.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#if defined(GRPC_POSIX_SOCKET) && !defined(GRPC_HAVE_IFADDRS)
diff --git a/src/core/lib/iomgr/tcp_server_uv.cc b/src/core/lib/iomgr/tcp_server_uv.cc
index 1ac49190fb..aa423766c7 100644
--- a/src/core/lib/iomgr/tcp_server_uv.cc
+++ b/src/core/lib/iomgr/tcp_server_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc
index 8a30dfde43..6d19c1c4d7 100644
--- a/src/core/lib/iomgr/tcp_server_windows.cc
+++ b/src/core/lib/iomgr/tcp_server_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/tcp_uv.cc b/src/core/lib/iomgr/tcp_uv.cc
index b384623a5e..6db3217d6e 100644
--- a/src/core/lib/iomgr/tcp_uv.cc
+++ b/src/core/lib/iomgr/tcp_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
diff --git a/src/core/lib/iomgr/tcp_uv.h b/src/core/lib/iomgr/tcp_uv.h
index fd6d19049a..6b1a6f77c2 100644
--- a/src/core/lib/iomgr/tcp_uv.h
+++ b/src/core/lib/iomgr/tcp_uv.h
@@ -29,6 +29,8 @@
otherwise specified.
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/endpoint.h"
diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc
index 6777719785..aab8edc888 100644
--- a/src/core/lib/iomgr/tcp_windows.cc
+++ b/src/core/lib/iomgr/tcp_windows.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/tcp_windows.h b/src/core/lib/iomgr/tcp_windows.h
index 8578a358ea..161a545a2a 100644
--- a/src/core/lib/iomgr/tcp_windows.h
+++ b/src/core/lib/iomgr/tcp_windows.h
@@ -29,6 +29,8 @@
otherwise specified.
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_WINSOCK_SOCKET
diff --git a/src/core/lib/iomgr/time_averaged_stats.cc b/src/core/lib/iomgr/time_averaged_stats.cc
index 3bddec04dd..6369e48db0 100644
--- a/src/core/lib/iomgr/time_averaged_stats.cc
+++ b/src/core/lib/iomgr/time_averaged_stats.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/time_averaged_stats.h"
void grpc_time_averaged_stats_init(grpc_time_averaged_stats* stats,
diff --git a/src/core/lib/iomgr/timer.h b/src/core/lib/iomgr/timer.h
index 82049859c5..67f1b1b3f9 100644
--- a/src/core/lib/iomgr/timer.h
+++ b/src/core/lib/iomgr/timer.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TIMER_H
#define GRPC_CORE_LIB_IOMGR_TIMER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_UV
@@ -27,7 +29,6 @@
#include "src/core/lib/iomgr/timer_generic.h"
#endif /* GRPC_UV */
-#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
diff --git a/src/core/lib/iomgr/timer_generic.cc b/src/core/lib/iomgr/timer_generic.cc
index 697162f7a8..52a571f425 100644
--- a/src/core/lib/iomgr/timer_generic.cc
+++ b/src/core/lib/iomgr/timer_generic.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include <inttypes.h>
diff --git a/src/core/lib/iomgr/timer_generic.h b/src/core/lib/iomgr/timer_generic.h
index 190381e904..97a4513355 100644
--- a/src/core/lib/iomgr/timer_generic.h
+++ b/src/core/lib/iomgr/timer_generic.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TIMER_GENERIC_H
#define GRPC_CORE_LIB_IOMGR_TIMER_GENERIC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/time.h>
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/iomgr/timer_heap.cc b/src/core/lib/iomgr/timer_heap.cc
index c26896ee4a..e5b5abfc97 100644
--- a/src/core/lib/iomgr/timer_heap.cc
+++ b/src/core/lib/iomgr/timer_heap.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_TIMER_USE_GENERIC
diff --git a/src/core/lib/iomgr/timer_heap.h b/src/core/lib/iomgr/timer_heap.h
index 436eef55a6..503365d4cd 100644
--- a/src/core/lib/iomgr/timer_heap.h
+++ b/src/core/lib/iomgr/timer_heap.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H
#define GRPC_CORE_LIB_IOMGR_TIMER_HEAP_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/timer.h"
typedef struct {
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index a528c22264..0210e70015 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -16,16 +16,17 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/timer_manager.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
-#include <grpc/support/thd.h>
#include <inttypes.h>
#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/timer.h"
typedef struct completed_thread {
diff --git a/src/core/lib/iomgr/timer_manager.h b/src/core/lib/iomgr/timer_manager.h
index 0ba502928a..3c4cdda2c8 100644
--- a/src/core/lib/iomgr/timer_manager.h
+++ b/src/core/lib/iomgr/timer_manager.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TIMER_MANAGER_H
#define GRPC_CORE_LIB_IOMGR_TIMER_MANAGER_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
/* Timer Manager tries to keep one thread waiting for the next timeout at all
diff --git a/src/core/lib/iomgr/timer_uv.cc b/src/core/lib/iomgr/timer_uv.cc
index 5d238da089..6f28f553c5 100644
--- a/src/core/lib/iomgr/timer_uv.cc
+++ b/src/core/lib/iomgr/timer_uv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#if GRPC_UV
diff --git a/src/core/lib/iomgr/timer_uv.h b/src/core/lib/iomgr/timer_uv.h
index 214aaa600a..093b2d085d 100644
--- a/src/core/lib/iomgr/timer_uv.h
+++ b/src/core/lib/iomgr/timer_uv.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_TIMER_UV_H
#define GRPC_CORE_LIB_IOMGR_TIMER_UV_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/exec_ctx.h"
struct grpc_timer {
diff --git a/src/core/lib/iomgr/udp_server.cc b/src/core/lib/iomgr/udp_server.cc
index eecb3b09d9..ec65497d79 100644
--- a/src/core/lib/iomgr/udp_server.cc
+++ b/src/core/lib/iomgr/udp_server.cc
@@ -25,6 +25,8 @@
#define SO_RXQ_OVFL 40
#endif
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_SOCKET
diff --git a/src/core/lib/iomgr/udp_server.h b/src/core/lib/iomgr/udp_server.h
index c1aa49f15d..1be4d04dbb 100644
--- a/src/core/lib/iomgr/udp_server.h
+++ b/src/core/lib/iomgr/udp_server.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_UDP_SERVER_H
#define GRPC_CORE_LIB_IOMGR_UDP_SERVER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/resolve_address.h"
diff --git a/src/core/lib/iomgr/unix_sockets_posix.cc b/src/core/lib/iomgr/unix_sockets_posix.cc
index b603916c47..8d252fd331 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.cc
+++ b/src/core/lib/iomgr/unix_sockets_posix.cc
@@ -15,6 +15,8 @@
* limitations under the License.
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_HAVE_UNIX_SOCKET
diff --git a/src/core/lib/iomgr/unix_sockets_posix.h b/src/core/lib/iomgr/unix_sockets_posix.h
index 1c079e6e76..917d0327a9 100644
--- a/src/core/lib/iomgr/unix_sockets_posix.h
+++ b/src/core/lib/iomgr/unix_sockets_posix.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H
#define GRPC_CORE_LIB_IOMGR_UNIX_SOCKETS_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#include <grpc/support/string_util.h>
diff --git a/src/core/lib/iomgr/unix_sockets_posix_noop.cc b/src/core/lib/iomgr/unix_sockets_posix_noop.cc
index fbd9602e1b..dfab3e0acb 100644
--- a/src/core/lib/iomgr/unix_sockets_posix_noop.cc
+++ b/src/core/lib/iomgr/unix_sockets_posix_noop.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#ifndef GRPC_HAVE_UNIX_SOCKET
diff --git a/src/core/lib/iomgr/wakeup_fd_cv.cc b/src/core/lib/iomgr/wakeup_fd_cv.cc
index 59718243e0..ee322105ae 100644
--- a/src/core/lib/iomgr/wakeup_fd_cv.cc
+++ b/src/core/lib/iomgr/wakeup_fd_cv.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_WAKEUP_FD
@@ -28,9 +30,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#define MAX_TABLE_RESIZE 256
diff --git a/src/core/lib/iomgr/wakeup_fd_cv.h b/src/core/lib/iomgr/wakeup_fd_cv.h
index 399620af76..86365f07e1 100644
--- a/src/core/lib/iomgr/wakeup_fd_cv.h
+++ b/src/core/lib/iomgr/wakeup_fd_cv.h
@@ -33,6 +33,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H
#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/sync.h>
#include "src/core/lib/iomgr/ev_posix.h"
diff --git a/src/core/lib/iomgr/wakeup_fd_eventfd.cc b/src/core/lib/iomgr/wakeup_fd_eventfd.cc
index 421ac55b00..dcf7dab71f 100644
--- a/src/core/lib/iomgr/wakeup_fd_eventfd.cc
+++ b/src/core/lib/iomgr/wakeup_fd_eventfd.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_LINUX_EVENTFD
diff --git a/src/core/lib/iomgr/wakeup_fd_nospecial.cc b/src/core/lib/iomgr/wakeup_fd_nospecial.cc
index c2b525a254..64778929f0 100644
--- a/src/core/lib/iomgr/wakeup_fd_nospecial.cc
+++ b/src/core/lib/iomgr/wakeup_fd_nospecial.cc
@@ -21,6 +21,8 @@
* systems without anything better than pipe.
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_NO_SPECIAL_WAKEUP_FD
diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.cc b/src/core/lib/iomgr/wakeup_fd_pipe.cc
index 05d69dc9cc..cb173903a9 100644
--- a/src/core/lib/iomgr/wakeup_fd_pipe.cc
+++ b/src/core/lib/iomgr/wakeup_fd_pipe.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_WAKEUP_FD
diff --git a/src/core/lib/iomgr/wakeup_fd_pipe.h b/src/core/lib/iomgr/wakeup_fd_pipe.h
index 326a0c4e01..1756976305 100644
--- a/src/core/lib/iomgr/wakeup_fd_pipe.h
+++ b/src/core/lib/iomgr/wakeup_fd_pipe.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H
#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_PIPE_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
extern const grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable;
diff --git a/src/core/lib/iomgr/wakeup_fd_posix.cc b/src/core/lib/iomgr/wakeup_fd_posix.cc
index e8de208a25..b5b8b37a9a 100644
--- a/src/core/lib/iomgr/wakeup_fd_posix.cc
+++ b/src/core/lib/iomgr/wakeup_fd_posix.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/port.h"
#ifdef GRPC_POSIX_WAKEUP_FD
diff --git a/src/core/lib/iomgr/wakeup_fd_posix.h b/src/core/lib/iomgr/wakeup_fd_posix.h
index a9584d0d48..670c319593 100644
--- a/src/core/lib/iomgr/wakeup_fd_posix.h
+++ b/src/core/lib/iomgr/wakeup_fd_posix.h
@@ -47,6 +47,8 @@
#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H
#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_POSIX_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/error.h"
void grpc_wakeup_fd_global_init(void);
diff --git a/src/core/lib/json/json.cc b/src/core/lib/json/json.cc
index 2633231224..816241bbf0 100644
--- a/src/core/lib/json/json.cc
+++ b/src/core/lib/json/json.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h
index d88a79271f..c8a87a7b87 100644
--- a/src/core/lib/json/json.h
+++ b/src/core/lib/json/json.h
@@ -19,6 +19,9 @@
#ifndef GRPC_CORE_LIB_JSON_JSON_H
#define GRPC_CORE_LIB_JSON_JSON_H
+
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <stdlib.h>
diff --git a/src/core/lib/json/json_reader.cc b/src/core/lib/json/json_reader.cc
index 6dadea5006..819572e4de 100644
--- a/src/core/lib/json/json_reader.cc
+++ b/src/core/lib/json/json_reader.cc
@@ -16,10 +16,10 @@
*
*/
-#include <string.h>
-
#include <grpc/support/port_platform.h>
+#include <string.h>
+
#include <grpc/support/log.h>
#include "src/core/lib/json/json_reader.h"
diff --git a/src/core/lib/json/json_reader.h b/src/core/lib/json/json_reader.h
index 03185cb2b6..78f7ad9f3a 100644
--- a/src/core/lib/json/json_reader.h
+++ b/src/core/lib/json/json_reader.h
@@ -20,6 +20,7 @@
#define GRPC_CORE_LIB_JSON_JSON_READER_H
#include <grpc/support/port_platform.h>
+
#include "src/core/lib/json/json_common.h"
typedef enum {
diff --git a/src/core/lib/json/json_string.cc b/src/core/lib/json/json_string.cc
index 8200900956..4f9175b9e7 100644
--- a/src/core/lib/json/json_string.cc
+++ b/src/core/lib/json/json_string.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <stdlib.h>
#include <string.h>
diff --git a/src/core/lib/json/json_writer.cc b/src/core/lib/json/json_writer.cc
index 6d442b8716..7bbdccc7a3 100644
--- a/src/core/lib/json/json_writer.cc
+++ b/src/core/lib/json/json_writer.cc
@@ -16,10 +16,10 @@
*
*/
-#include <string.h>
-
#include <grpc/support/port_platform.h>
+#include <string.h>
+
#include "src/core/lib/json/json_writer.h"
static void json_writer_output_char(grpc_json_writer* writer, char c) {
diff --git a/src/core/lib/json/json_writer.h b/src/core/lib/json/json_writer.h
index a4f2d4daeb..ba0bedde7f 100644
--- a/src/core/lib/json/json_writer.h
+++ b/src/core/lib/json/json_writer.h
@@ -31,6 +31,8 @@
#ifndef GRPC_CORE_LIB_JSON_JSON_WRITER_H
#define GRPC_CORE_LIB_JSON_JSON_WRITER_H
+#include <grpc/support/port_platform.h>
+
#include <stdlib.h>
#include "src/core/lib/json/json_common.h"
diff --git a/src/core/lib/profiling/basic_timers.cc b/src/core/lib/profiling/basic_timers.cc
index d1c9fd7dec..ca6705a6b3 100644
--- a/src/core/lib/profiling/basic_timers.cc
+++ b/src/core/lib/profiling/basic_timers.cc
@@ -25,12 +25,12 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <string.h>
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
typedef enum { BEGIN = '{', END = '}', MARK = '.' } marker_type;
diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc
index c7e212bb21..14051a3f00 100644
--- a/src/core/lib/security/context/security_context.cc
+++ b/src/core/lib/security/context/security_context.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include "src/core/lib/channel/channel_args.h"
diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h
index 34f8c2487e..e782e4f28f 100644
--- a/src/core/lib/security/context/security_context.h
+++ b/src/core/lib/security/context/security_context.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H
#define GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials/credentials.h"
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc
index ea2c4e208f..b8f409260f 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.cc
+++ b/src/core/lib/security/credentials/composite/composite_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/composite/composite_credentials.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h
index 11990d38ff..a952ad57f1 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.h
+++ b/src/core/lib/security/credentials/composite/composite_credentials.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc
index 17f7de58be..c43cb440eb 100644
--- a/src/core/lib/security/credentials/credentials.cc
+++ b/src/core/lib/security/credentials/credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
#include <stdio.h>
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 4825b65720..b1421e83c5 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/sync.h>
@@ -27,7 +29,7 @@
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/polling_entity.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
struct grpc_http_response;
diff --git a/src/core/lib/security/credentials/credentials_metadata.cc b/src/core/lib/security/credentials/credentials_metadata.cc
index 250e384155..703de4aaaf 100644
--- a/src/core/lib/security/credentials/credentials_metadata.cc
+++ b/src/core/lib/security/credentials/credentials_metadata.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc
index 3b29db2efa..858ab6b41b 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.cc
+++ b/src/core/lib/security/credentials/fake/fake_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include <string.h>
@@ -30,9 +32,6 @@
/* -- Fake transport security credentials. -- */
-#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
- "grpc.fake_security.expected_targets"
-
static grpc_security_status fake_transport_security_create_security_connector(
grpc_channel_credentials* c, grpc_call_credentials* call_creds,
const char* target, const grpc_channel_args* args,
@@ -87,11 +86,7 @@ const char* grpc_fake_transport_get_expected_targets(
const grpc_channel_args* args) {
const grpc_arg* expected_target_arg =
grpc_channel_args_find(args, GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS);
- if (expected_target_arg != nullptr &&
- expected_target_arg->type == GRPC_ARG_STRING) {
- return expected_target_arg->value.string;
- }
- return nullptr;
+ return grpc_channel_arg_get_string(expected_target_arg);
}
/* -- Metadata-only test credentials. -- */
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h
index 0e9ff155d8..e89e6e24cc 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.h
+++ b/src/core/lib/security/credentials/fake/fake_credentials.h
@@ -19,8 +19,13 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
+#define GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS \
+ "grpc.fake_security.expected_targets"
+
/* -- Fake transport security credentials. -- */
/* Creates a fake transport security credentials object for testing. */
diff --git a/src/core/lib/security/credentials/google_default/credentials_generic.cc b/src/core/lib/security/credentials/google_default/credentials_generic.cc
index 15ae9d6428..10ff0f620f 100644
--- a/src/core/lib/security/credentials/google_default/credentials_generic.cc
+++ b/src/core/lib/security/credentials/google_default/credentials_generic.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index 65455f94b3..70d4c3ea51 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.cc b/src/core/lib/security/credentials/iam/iam_credentials.cc
index 7f19fbc785..5d92fa88c4 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.cc
+++ b/src/core/lib/security/credentials/iam/iam_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/iam/iam_credentials.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.h b/src/core/lib/security/credentials/iam/iam_credentials.h
index 5e3cf65bad..a45710fe0f 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.h
+++ b/src/core/lib/security/credentials/iam/iam_credentials.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
diff --git a/src/core/lib/security/credentials/jwt/json_token.cc b/src/core/lib/security/credentials/jwt/json_token.cc
index f7c9f57808..1c4827df0f 100644
--- a/src/core/lib/security/credentials/jwt/json_token.cc
+++ b/src/core/lib/security/credentials/jwt/json_token.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/jwt/json_token.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/jwt/json_token.h b/src/core/lib/security/credentials/jwt/json_token.h
index 9b774882b7..d0fb4ebd0a 100644
--- a/src/core/lib/security/credentials/jwt/json_token.h
+++ b/src/core/lib/security/credentials/jwt/json_token.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JSON_TOKEN_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <openssl/rsa.h>
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h
index f58a8b67ba..5c3d34aa56 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.h
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc
index f5c1ada6ca..5c47276e32 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/jwt/jwt_verifier.h"
#include <limits.h>
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index b3805e75cd..cdb09870bd 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_JWT_JWT_VERIFIER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/json/json.h"
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
index afae7d8f2f..2129029737 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index e5b8df8eb9..c0dd1546e3 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_OAUTH2_OAUTH2_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/credentials/credentials.h"
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
index ddb86e153b..73946ce039 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/plugin/plugin_credentials.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h
index e1467b0824..caf990efa1 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.h
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
extern grpc_core::TraceFlag grpc_plugin_credentials_trace;
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
index a4fce25f3a..252b25bc0a 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
#include <string.h>
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h
index 0003905857..712d34c733 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.h
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h
@@ -18,6 +18,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_SSL_SSL_CREDENTIALS_H
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_SSL_SSL_CREDENTIALS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/credentials/credentials.h"
typedef struct {
diff --git a/src/core/lib/security/transport/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index bd5da1bbd2..3cc151bec7 100644
--- a/src/core/lib/security/transport/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -16,7 +16,9 @@
*
*/
-#include "src/core/lib/security/transport/security_connector.h"
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/security/security_connector/security_connector.h"
#include <stdbool.h>
#include <string.h>
@@ -37,9 +39,9 @@
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h"
-#include "src/core/lib/security/transport/lb_targets_info.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/security_handshaker.h"
+#include "src/core/lib/security/transport/target_authority_table.h"
#include "src/core/tsi/fake_transport_security.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_adapter.h"
@@ -461,6 +463,15 @@ static bool fake_channel_check_call_host(grpc_channel_security_connector* sc,
grpc_auth_context* auth_context,
grpc_closure* on_call_host_checked,
grpc_error** error) {
+ grpc_fake_channel_security_connector* c =
+ reinterpret_cast<grpc_fake_channel_security_connector*>(sc);
+ if (c->is_lb_channel) {
+ // TODO(dgq): verify that the host (ie, authority header) matches that of
+ // the LB, as opposed to that of the backends.
+ } else {
+ // TODO(dgq): verify that the host (ie, authority header) matches that of
+ // the backend, not the LB's.
+ }
return true;
}
@@ -512,7 +523,7 @@ grpc_channel_security_connector* grpc_fake_channel_security_connector_create(
c->target = gpr_strdup(target);
const char* expected_targets = grpc_fake_transport_get_expected_targets(args);
c->expected_targets = gpr_strdup(expected_targets);
- c->is_lb_channel = (grpc_lb_targets_info_find_in_args(args) != nullptr);
+ c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr;
return &c->base;
}
diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/security_connector/security_connector.h
index 495821d247..130c8ecd3e 100644
--- a/src/core/lib/security/transport/security_connector.h
+++ b/src/core/lib/security/security_connector/security_connector.h
@@ -16,8 +16,10 @@
*
*/
-#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
-#define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H
+#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H
+#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H
+
+#include <grpc/support/port_platform.h>
#include <stdbool.h>
@@ -246,4 +248,4 @@ tsi_peer tsi_shallow_peer_from_ssl_auth_context(
const grpc_auth_context* auth_context);
void tsi_shallow_peer_destruct(tsi_peer* peer);
-#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_CONNECTOR_H */
+#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H */
diff --git a/src/core/lib/security/transport/auth_filters.h b/src/core/lib/security/transport/auth_filters.h
index e999a027ae..af2104cfbc 100644
--- a/src/core/lib/security/transport/auth_filters.h
+++ b/src/core/lib/security/transport/auth_filters.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_AUTH_FILTERS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc_security.h>
#include "src/core/lib/channel/channel_stack.h"
diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc
index d2313807ff..d6ca8ee8f8 100644
--- a/src/core/lib/security/transport/client_auth_filter.cc
+++ b/src/core/lib/security/transport/client_auth_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/transport/auth_filters.h"
#include <string.h>
@@ -29,7 +31,7 @@
#include "src/core/lib/profiling/timers.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/surface/call.h"
diff --git a/src/core/lib/security/transport/lb_targets_info.cc b/src/core/lib/security/transport/lb_targets_info.cc
deleted file mode 100644
index 67a3c7449d..0000000000
--- a/src/core/lib/security/transport/lb_targets_info.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- * Copyright 2017 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/support/log.h>
-
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/security/transport/lb_targets_info.h"
-
-/* Channel arg key for the mapping of LB server addresses to their names for
- * secure naming purposes. */
-#define GRPC_ARG_LB_SECURE_NAMING_MAP "grpc.lb_secure_naming_map"
-
-static void* targets_info_copy(void* p) {
- return grpc_slice_hash_table_ref(static_cast<grpc_slice_hash_table*>(p));
-}
-static void targets_info_destroy(void* p) {
- grpc_slice_hash_table_unref(static_cast<grpc_slice_hash_table*>(p));
-}
-static int targets_info_cmp(void* a, void* b) {
- return grpc_slice_hash_table_cmp(
- static_cast<const grpc_slice_hash_table*>(a),
- static_cast<const grpc_slice_hash_table*>(b));
-}
-static const grpc_arg_pointer_vtable server_to_balancer_names_vtable = {
- targets_info_copy, targets_info_destroy, targets_info_cmp};
-
-grpc_arg grpc_lb_targets_info_create_channel_arg(
- grpc_slice_hash_table* targets_info) {
- return grpc_channel_arg_pointer_create((char*)GRPC_ARG_LB_SECURE_NAMING_MAP,
- targets_info,
- &server_to_balancer_names_vtable);
-}
-
-grpc_slice_hash_table* grpc_lb_targets_info_find_in_args(
- const grpc_channel_args* args) {
- const grpc_arg* targets_info_arg =
- grpc_channel_args_find(args, GRPC_ARG_LB_SECURE_NAMING_MAP);
- if (targets_info_arg != nullptr) {
- GPR_ASSERT(targets_info_arg->type == GRPC_ARG_POINTER);
- return static_cast<grpc_slice_hash_table*>(
- targets_info_arg->value.pointer.p);
- }
- return nullptr;
-}
diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc
index f72f8b6121..31b779e333 100644
--- a/src/core/lib/security/transport/secure_endpoint.cc
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -20,6 +20,8 @@
using that endpoint. Because of various transitive includes in uv.h,
including windows.h on Windows, uv.h must be included before other system
headers. Therefore, sockaddr.h must always be included first */
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/sockaddr.h"
#include <grpc/slice.h>
diff --git a/src/core/lib/security/transport/secure_endpoint.h b/src/core/lib/security/transport/secure_endpoint.h
index b2556a0182..e7e3351678 100644
--- a/src/core/lib/security/transport/secure_endpoint.h
+++ b/src/core/lib/security/transport/secure_endpoint.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURE_ENDPOINT_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURE_ENDPOINT_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include "src/core/lib/iomgr/endpoint.h"
diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc
index b37392ab81..0c97dfa6b3 100644
--- a/src/core/lib/security/transport/security_handshaker.cc
+++ b/src/core/lib/security/transport/security_handshaker.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/transport/security_handshaker.h"
#include <stdbool.h>
diff --git a/src/core/lib/security/transport/security_handshaker.h b/src/core/lib/security/transport/security_handshaker.h
index 6cd6446b5a..ecf59ec5c5 100644
--- a/src/core/lib/security/transport/security_handshaker.h
+++ b/src/core/lib/security/transport/security_handshaker.h
@@ -19,9 +19,11 @@
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_SECURITY_HANDSHAKER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/iomgr/exec_ctx.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
/// Creates a security handshaker using \a handshaker.
grpc_handshaker* grpc_security_handshaker_create(
diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc
index 409aded650..a560a4a02e 100644
--- a/src/core/lib/security/transport/server_auth_filter.cc
+++ b/src/core/lib/security/transport/server_auth_filter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/security/transport/target_authority_table.cc b/src/core/lib/security/transport/target_authority_table.cc
new file mode 100644
index 0000000000..1eeb557f6a
--- /dev/null
+++ b/src/core/lib/security/transport/target_authority_table.cc
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/support/log.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/security/transport/target_authority_table.h"
+
+// Channel arg key for the mapping of target addresses to their authorities.
+#define GRPC_ARG_TARGET_AUTHORITY_TABLE "grpc.target_authority_table"
+
+namespace grpc_core {
+namespace {
+
+void* target_authority_table_copy(void* p) {
+ TargetAuthorityTable* table = static_cast<TargetAuthorityTable*>(p);
+ // TODO(roth): When channel_args are converted to C++, pass the
+ // RefCountedPtr<> directly instead of managing the ref manually.
+ table->Ref().release();
+ return p;
+}
+void target_authority_table_destroy(void* p) {
+ TargetAuthorityTable* table = static_cast<TargetAuthorityTable*>(p);
+ table->Unref();
+}
+int target_authority_table_cmp(void* a, void* b) {
+ return TargetAuthorityTable::Cmp(
+ *static_cast<const TargetAuthorityTable*>(a),
+ *static_cast<const TargetAuthorityTable*>(b));
+}
+const grpc_arg_pointer_vtable target_authority_table_arg_vtable = {
+ target_authority_table_copy, target_authority_table_destroy,
+ target_authority_table_cmp};
+
+} // namespace
+
+grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table) {
+ return grpc_channel_arg_pointer_create((char*)GRPC_ARG_TARGET_AUTHORITY_TABLE,
+ table,
+ &target_authority_table_arg_vtable);
+}
+
+TargetAuthorityTable* FindTargetAuthorityTableInArgs(
+ const grpc_channel_args* args) {
+ const grpc_arg* arg =
+ grpc_channel_args_find(args, GRPC_ARG_TARGET_AUTHORITY_TABLE);
+ if (arg != nullptr) {
+ if (arg->type == GRPC_ARG_POINTER) {
+ return static_cast<TargetAuthorityTable*>(arg->value.pointer.p);
+ } else {
+ gpr_log(GPR_ERROR, "value of " GRPC_ARG_TARGET_AUTHORITY_TABLE
+ " channel arg was not pointer type; ignoring");
+ }
+ }
+ return nullptr;
+}
+
+} // namespace grpc_core
diff --git a/src/core/lib/security/transport/target_authority_table.h b/src/core/lib/security/transport/target_authority_table.h
new file mode 100644
index 0000000000..a2e7dc6ac2
--- /dev/null
+++ b/src/core/lib/security/transport/target_authority_table.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H
+#define GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/slice/slice_hash_table.h"
+
+namespace grpc_core {
+
+/// A hash table mapping target addresses to authorities.
+typedef SliceHashTable<UniquePtr<char>> TargetAuthorityTable;
+
+/// Returns a channel argument containing \a table.
+grpc_arg CreateTargetAuthorityTableChannelArg(TargetAuthorityTable* table);
+
+/// Returns the target authority table from \a args or nullptr.
+TargetAuthorityTable* FindTargetAuthorityTableInArgs(
+ const grpc_channel_args* args);
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SECURITY_TRANSPORT_TARGET_AUTHORITY_TABLE_H */
diff --git a/src/core/lib/security/transport/tsi_error.cc b/src/core/lib/security/transport/tsi_error.cc
index f71696d35d..f78bb8df38 100644
--- a/src/core/lib/security/transport/tsi_error.cc
+++ b/src/core/lib/security/transport/tsi_error.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/transport/tsi_error.h"
grpc_error* grpc_set_tsi_error_result(grpc_error* error, tsi_result result) {
diff --git a/src/core/lib/security/transport/tsi_error.h b/src/core/lib/security/transport/tsi_error.h
index 8fa6c480ac..16e04f70f1 100644
--- a/src/core/lib/security/transport/tsi_error.h
+++ b/src/core/lib/security/transport/tsi_error.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_TRANSPORT_TSI_ERROR_H
#define GRPC_CORE_LIB_SECURITY_TRANSPORT_TSI_ERROR_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/error.h"
#include "src/core/tsi/transport_security_interface.h"
diff --git a/src/core/lib/security/util/json_util.cc b/src/core/lib/security/util/json_util.cc
index fef1a1f51d..75512a19c9 100644
--- a/src/core/lib/security/util/json_util.cc
+++ b/src/core/lib/security/util/json_util.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/security/util/json_util.h"
#include <string.h>
diff --git a/src/core/lib/security/util/json_util.h b/src/core/lib/security/util/json_util.h
index b7e46d4062..89deffcc08 100644
--- a/src/core/lib/security/util/json_util.h
+++ b/src/core/lib/security/util/json_util.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SECURITY_UTIL_JSON_UTIL_H
#define GRPC_CORE_LIB_SECURITY_UTIL_JSON_UTIL_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include "src/core/lib/json/json.h"
diff --git a/src/core/lib/slice/b64.cc b/src/core/lib/slice/b64.cc
index 3e19b7197f..27f2724002 100644
--- a/src/core/lib/slice/b64.cc
+++ b/src/core/lib/slice/b64.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/slice/b64.h"
#include <stdint.h>
diff --git a/src/core/lib/slice/b64.h b/src/core/lib/slice/b64.h
index 17e7306303..4475568c25 100644
--- a/src/core/lib/slice/b64.h
+++ b/src/core/lib/slice/b64.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SLICE_B64_H
#define GRPC_CORE_LIB_SLICE_B64_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
/* Encodes data using base64. It is the caller's responsability to free
diff --git a/src/core/lib/slice/percent_encoding.cc b/src/core/lib/slice/percent_encoding.cc
index 84fb554454..45cd2cc47f 100644
--- a/src/core/lib/slice/percent_encoding.cc
+++ b/src/core/lib/slice/percent_encoding.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/slice/percent_encoding.h"
#include <grpc/support/log.h>
diff --git a/src/core/lib/slice/percent_encoding.h b/src/core/lib/slice/percent_encoding.h
index a1009ff01f..6b13ffc3fe 100644
--- a/src/core/lib/slice/percent_encoding.h
+++ b/src/core/lib/slice/percent_encoding.h
@@ -26,6 +26,8 @@
and another which applies percent encoding only to non-http2 header
bytes (the 'compatible' variant) */
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/slice.h>
diff --git a/src/core/lib/slice/slice.cc b/src/core/lib/slice/slice.cc
index 476d941fbb..585b41cf91 100644
--- a/src/core/lib/slice/slice.cc
+++ b/src/core/lib/slice/slice.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/slice/slice_internal.h"
#include <grpc/slice.h>
diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc
index 0416c9d371..e418ab10ef 100644
--- a/src/core/lib/slice/slice_buffer.cc
+++ b/src/core/lib/slice/slice_buffer.cc
@@ -16,9 +16,10 @@
*
*/
-#include <grpc/slice_buffer.h>
#include <grpc/support/port_platform.h>
+#include <grpc/slice_buffer.h>
+
#include <string.h>
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/slice/slice_hash_table.cc b/src/core/lib/slice/slice_hash_table.cc
deleted file mode 100644
index 2342e90485..0000000000
--- a/src/core/lib/slice/slice_hash_table.cc
+++ /dev/null
@@ -1,145 +0,0 @@
-//
-// Copyright 2016 gRPC authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#include "src/core/lib/slice/slice_hash_table.h"
-
-#include <stdbool.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-
-#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/transport/metadata.h"
-
-struct grpc_slice_hash_table {
- gpr_refcount refs;
- void (*destroy_value)(void* value);
- int (*value_cmp)(void* a, void* b);
- size_t size;
- size_t max_num_probes;
- grpc_slice_hash_table_entry* entries;
-};
-
-static bool is_empty(grpc_slice_hash_table_entry* entry) {
- return entry->value == nullptr;
-}
-
-static void grpc_slice_hash_table_add(grpc_slice_hash_table* table,
- grpc_slice key, void* value) {
- GPR_ASSERT(value != nullptr);
- const size_t hash = grpc_slice_hash(key);
- for (size_t offset = 0; offset < table->size; ++offset) {
- const size_t idx = (hash + offset) % table->size;
- if (is_empty(&table->entries[idx])) {
- table->entries[idx].key = key;
- table->entries[idx].value = value;
- // Keep track of the maximum number of probes needed, since this
- // provides an upper bound for lookups.
- if (offset > table->max_num_probes) table->max_num_probes = offset;
- return;
- }
- }
- GPR_ASSERT(false); // Table should never be full.
-}
-
-grpc_slice_hash_table* grpc_slice_hash_table_create(
- size_t num_entries, grpc_slice_hash_table_entry* entries,
- void (*destroy_value)(void* value), int (*value_cmp)(void* a, void* b)) {
- grpc_slice_hash_table* table =
- static_cast<grpc_slice_hash_table*>(gpr_zalloc(sizeof(*table)));
- gpr_ref_init(&table->refs, 1);
- table->destroy_value = destroy_value;
- table->value_cmp = value_cmp;
- // Keep load factor low to improve performance of lookups.
- table->size = num_entries * 2;
- const size_t entry_size = sizeof(grpc_slice_hash_table_entry) * table->size;
- table->entries =
- static_cast<grpc_slice_hash_table_entry*>(gpr_zalloc(entry_size));
- for (size_t i = 0; i < num_entries; ++i) {
- grpc_slice_hash_table_entry* entry = &entries[i];
- grpc_slice_hash_table_add(table, entry->key, entry->value);
- }
- return table;
-}
-
-grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table) {
- if (table != nullptr) gpr_ref(&table->refs);
- return table;
-}
-
-void grpc_slice_hash_table_unref(grpc_slice_hash_table* table) {
- if (table != nullptr && gpr_unref(&table->refs)) {
- for (size_t i = 0; i < table->size; ++i) {
- grpc_slice_hash_table_entry* entry = &table->entries[i];
- if (!is_empty(entry)) {
- grpc_slice_unref_internal(entry->key);
- table->destroy_value(entry->value);
- }
- }
- gpr_free(table->entries);
- gpr_free(table);
- }
-}
-
-void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
- const grpc_slice key) {
- const size_t hash = grpc_slice_hash(key);
- // We cap the number of probes at the max number recorded when
- // populating the table.
- for (size_t offset = 0; offset <= table->max_num_probes; ++offset) {
- const size_t idx = (hash + offset) % table->size;
- if (is_empty(&table->entries[idx])) break;
- if (grpc_slice_eq(table->entries[idx].key, key)) {
- return table->entries[idx].value;
- }
- }
- return nullptr; // Not found.
-}
-
-static int pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
-int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* a,
- const grpc_slice_hash_table* b) {
- int (*const value_cmp_fn_a)(void* a, void* b) =
- a->value_cmp != nullptr ? a->value_cmp : pointer_cmp;
- int (*const value_cmp_fn_b)(void* a, void* b) =
- b->value_cmp != nullptr ? b->value_cmp : pointer_cmp;
- // Compare value_fns
- const int value_fns_cmp =
- GPR_ICMP((void*)value_cmp_fn_a, (void*)value_cmp_fn_b);
- if (value_fns_cmp != 0) return value_fns_cmp;
- // Compare sizes
- if (a->size < b->size) return -1;
- if (a->size > b->size) return 1;
- // Compare rows.
- for (size_t i = 0; i < a->size; ++i) {
- if (is_empty(&a->entries[i])) {
- if (!is_empty(&b->entries[i])) {
- return -1; // a empty but b non-empty
- }
- continue; // both empty, no need to check key or value
- } else if (is_empty(&b->entries[i])) {
- return 1; // a non-empty but b empty
- }
- // neither entry is empty
- const int key_cmp = grpc_slice_cmp(a->entries[i].key, b->entries[i].key);
- if (key_cmp != 0) return key_cmp;
- const int value_cmp =
- value_cmp_fn_a(a->entries[i].value, b->entries[i].value);
- if (value_cmp != 0) return value_cmp;
- }
- return 0;
-}
diff --git a/src/core/lib/slice/slice_hash_table.h b/src/core/lib/slice/slice_hash_table.h
index db69da662a..fbe9cc58e8 100644
--- a/src/core/lib/slice/slice_hash_table.h
+++ b/src/core/lib/slice/slice_hash_table.h
@@ -17,52 +17,185 @@
#ifndef GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H
#define GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H
-#include "src/core/lib/transport/metadata.h"
+#include <grpc/support/port_platform.h>
-/** Hash table implementation.
- *
- * This implementation uses open addressing
- * (https://en.wikipedia.org/wiki/Open_addressing) with linear
- * probing (https://en.wikipedia.org/wiki/Linear_probing).
- *
- * The keys are \a grpc_slice objects. The values are arbitrary pointers
- * with a common destroy function.
- *
- * Hash tables are intentionally immutable, to avoid the need for locking.
- */
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/slice/slice_internal.h"
+
+/// Hash table implementation.
+///
+/// This implementation uses open addressing
+/// (https://en.wikipedia.org/wiki/Open_addressing) with linear
+/// probing (https://en.wikipedia.org/wiki/Linear_probing).
+///
+/// The keys are \a grpc_slice objects. The values can be any type.
+///
+/// Hash tables are intentionally immutable, to avoid the need for locking.
+
+namespace grpc_core {
+
+template <typename T>
+class SliceHashTable : public RefCounted<SliceHashTable<T>> {
+ public:
+ struct Entry {
+ grpc_slice key;
+ T value;
+ bool is_set;
+ };
+
+ // Function for comparing values.
+ // TODO(roth): Eliminate this and the Cmp() method from this API once
+ // grpc_channel_args is redesigned to require that keys are unique.
+ typedef int (*ValueCmp)(const T&, const T&);
+
+ /// Creates a new hash table containing \a entries, which is an array
+ /// of length \a num_entries. Takes ownership of all keys and values in \a
+ /// entries. If not null, \a value_cmp will be used to compare values in
+ /// the context of \a Cmp(). If null, raw pointer (\a GPR_ICMP) comparison
+ /// will be used.
+ static RefCountedPtr<SliceHashTable> Create(size_t num_entries,
+ Entry* entries,
+ ValueCmp value_cmp);
+
+ /// Returns the value from the table associated with \a key.
+ /// Returns null if \a key is not found.
+ const T* Get(const grpc_slice& key) const;
+
+ /// Compares \a a vs. \a b.
+ /// A table is considered "smaller" (resp. "greater") if:
+ /// - GPR_ICMP(a->value_cmp, b->value_cmp) < 1 (resp. > 1),
+ /// - else, it contains fewer (resp. more) entries,
+ /// - else, if strcmp(a_key, b_key) < 1 (resp. > 1),
+ /// - else, if value_cmp(a_value, b_value) < 1 (resp. > 1).
+ static int Cmp(const SliceHashTable& a, const SliceHashTable& b);
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T2, typename... Args>
+ friend T2* New(Args&&... args);
+
+ SliceHashTable(size_t num_entries, Entry* entries, ValueCmp value_cmp);
+ virtual ~SliceHashTable();
+
+ void Add(grpc_slice key, T& value);
+
+ // Default value comparison function, if none specified by caller.
+ static int DefaultValueCmp(const T& a, const T& b) { return GPR_ICMP(a, b); }
+
+ const ValueCmp value_cmp_;
+ const size_t size_;
+ size_t max_num_probes_;
+ Entry* entries_;
+};
+
+//
+// implementation -- no user-serviceable parts below
+//
+
+template <typename T>
+RefCountedPtr<SliceHashTable<T>> SliceHashTable<T>::Create(size_t num_entries,
+ Entry* entries,
+ ValueCmp value_cmp) {
+ return MakeRefCounted<SliceHashTable<T>>(num_entries, entries, value_cmp);
+}
+
+template <typename T>
+SliceHashTable<T>::SliceHashTable(size_t num_entries, Entry* entries,
+ ValueCmp value_cmp)
+ : value_cmp_(value_cmp),
+ // Keep load factor low to improve performance of lookups.
+ size_(num_entries * 2),
+ max_num_probes_(0) {
+ entries_ = static_cast<Entry*>(gpr_zalloc(sizeof(Entry) * size_));
+ for (size_t i = 0; i < num_entries; ++i) {
+ Entry* entry = &entries[i];
+ Add(entry->key, entry->value);
+ }
+}
+
+template <typename T>
+SliceHashTable<T>::~SliceHashTable() {
+ for (size_t i = 0; i < size_; ++i) {
+ Entry& entry = entries_[i];
+ if (entry.is_set) {
+ grpc_slice_unref_internal(entry.key);
+ entry.value.~T();
+ }
+ }
+ gpr_free(entries_);
+}
+
+template <typename T>
+void SliceHashTable<T>::Add(grpc_slice key, T& value) {
+ const size_t hash = grpc_slice_hash(key);
+ for (size_t offset = 0; offset < size_; ++offset) {
+ const size_t idx = (hash + offset) % size_;
+ if (!entries_[idx].is_set) {
+ entries_[idx].is_set = true;
+ entries_[idx].key = key;
+ entries_[idx].value = std::move(value);
+ // Keep track of the maximum number of probes needed, since this
+ // provides an upper bound for lookups.
+ if (offset > max_num_probes_) max_num_probes_ = offset;
+ return;
+ }
+ }
+ GPR_ASSERT(false); // Table should never be full.
+}
+
+template <typename T>
+const T* SliceHashTable<T>::Get(const grpc_slice& key) const {
+ const size_t hash = grpc_slice_hash(key);
+ // We cap the number of probes at the max number recorded when
+ // populating the table.
+ for (size_t offset = 0; offset <= max_num_probes_; ++offset) {
+ const size_t idx = (hash + offset) % size_;
+ if (!entries_[idx].is_set) break;
+ if (grpc_slice_eq(entries_[idx].key, key)) {
+ return &entries_[idx].value;
+ }
+ }
+ return nullptr; // Not found.
+}
+
+template <typename T>
+int SliceHashTable<T>::Cmp(const SliceHashTable& a, const SliceHashTable& b) {
+ ValueCmp value_cmp_a =
+ a.value_cmp_ != nullptr ? a.value_cmp_ : DefaultValueCmp;
+ ValueCmp value_cmp_b =
+ b.value_cmp_ != nullptr ? b.value_cmp_ : DefaultValueCmp;
+ // Compare value_fns
+ const int value_fns_cmp = GPR_ICMP((void*)value_cmp_a, (void*)value_cmp_b);
+ if (value_fns_cmp != 0) return value_fns_cmp;
+ // Compare sizes
+ if (a.size_ < b.size_) return -1;
+ if (a.size_ > b.size_) return 1;
+ // Compare rows.
+ for (size_t i = 0; i < a.size_; ++i) {
+ if (!a.entries_[i].is_set) {
+ if (b.entries_[i].is_set) {
+ return -1; // a empty but b non-empty
+ }
+ continue; // both empty, no need to check key or value
+ } else if (!b.entries_[i].is_set) {
+ return 1; // a non-empty but b empty
+ }
+ // neither entry is empty
+ const int key_cmp = grpc_slice_cmp(a.entries_[i].key, b.entries_[i].key);
+ if (key_cmp != 0) return key_cmp;
+ const int value_cmp = value_cmp_a(a.entries_[i].value, b.entries_[i].value);
+ if (value_cmp != 0) return value_cmp;
+ }
+ return 0;
+}
-typedef struct grpc_slice_hash_table grpc_slice_hash_table;
-
-typedef struct grpc_slice_hash_table_entry {
- grpc_slice key;
- void* value; /* Must not be NULL. */
-} grpc_slice_hash_table_entry;
-
-/** Creates a new hash table of containing \a entries, which is an array
- of length \a num_entries. Takes ownership of all keys and values in \a
- entries. Values will be cleaned up via \a destroy_value(). If not NULL, \a
- value_cmp will be used to compare values in the context of \a
- grpc_slice_hash_table_cmp. If NULL, raw pointer (\a GPR_ICMP) comparison
- will be used. */
-grpc_slice_hash_table* grpc_slice_hash_table_create(
- size_t num_entries, grpc_slice_hash_table_entry* entries,
- void (*destroy_value)(void* value), int (*value_cmp)(void* a, void* b));
-
-grpc_slice_hash_table* grpc_slice_hash_table_ref(grpc_slice_hash_table* table);
-void grpc_slice_hash_table_unref(grpc_slice_hash_table* table);
-
-/** Returns the value from \a table associated with \a key.
- Returns NULL if \a key is not found. */
-void* grpc_slice_hash_table_get(const grpc_slice_hash_table* table,
- const grpc_slice key);
-
-/** Compares \a a vs. \a b.
- * A table is considered "smaller" (resp. "greater") if:
- * - GPR_ICMP(a->value_cmp, b->value_cmp) < 1 (resp. > 1),
- * - else, it contains fewer (resp. more) entries,
- * - else, if strcmp(a_key, b_key) < 1 (resp. > 1),
- * - else, if value_cmp(a_value, b_value) < 1 (resp. > 1). */
-int grpc_slice_hash_table_cmp(const grpc_slice_hash_table* a,
- const grpc_slice_hash_table* b);
+} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SLICE_SLICE_HASH_TABLE_H */
diff --git a/src/core/lib/slice/slice_intern.cc b/src/core/lib/slice/slice_intern.cc
index 2d633c4903..e53c040e1a 100644
--- a/src/core/lib/slice/slice_intern.cc
+++ b/src/core/lib/slice/slice_intern.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/slice/slice_internal.h"
#include <inttypes.h>
diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h
index 4e9ab80261..065c25c90c 100644
--- a/src/core/lib/slice/slice_internal.h
+++ b/src/core/lib/slice/slice_internal.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
#define GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
diff --git a/src/core/lib/slice/slice_string_helpers.cc b/src/core/lib/slice/slice_string_helpers.cc
index f91ece3b98..6af9c33eb5 100644
--- a/src/core/lib/slice/slice_string_helpers.cc
+++ b/src/core/lib/slice/slice_string_helpers.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/slice/slice_string_helpers.h"
#include <string.h>
diff --git a/src/core/lib/slice/slice_string_helpers.h b/src/core/lib/slice/slice_string_helpers.h
index 429f9ff4b5..976f72411a 100644
--- a/src/core/lib/slice/slice_string_helpers.h
+++ b/src/core/lib/slice/slice_string_helpers.h
@@ -19,12 +19,13 @@
#ifndef GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H
#define GRPC_CORE_LIB_SLICE_SLICE_STRING_HELPERS_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <stddef.h>
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
-#include <grpc/support/port_platform.h>
#include "src/core/lib/gpr/string.h"
diff --git a/src/core/lib/slice/slice_traits.h b/src/core/lib/slice/slice_traits.h
index 4b898bdcd4..ee01916525 100644
--- a/src/core/lib/slice/slice_traits.h
+++ b/src/core/lib/slice/slice_traits.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SLICE_SLICE_TRAITS_H
#define GRPC_CORE_LIB_SLICE_SLICE_TRAITS_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <stdbool.h>
diff --git a/src/core/lib/slice/slice_weak_hash_table.h b/src/core/lib/slice/slice_weak_hash_table.h
new file mode 100644
index 0000000000..9d0ddfc2d2
--- /dev/null
+++ b/src/core/lib/slice/slice_weak_hash_table.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H
+#define GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/slice/slice_internal.h"
+
+/// Weak hash table implementation.
+///
+/// This entries in this table are weak: an entry may be removed at any time due
+/// to a number of reasons: memory pressure, hash collisions, etc.
+///
+/// The keys are \a grpc_slice objects. The values are of arbitrary type.
+///
+/// This class is thread unsafe. It's the caller's responsibility to ensure
+/// proper locking when accessing its methods.
+
+namespace grpc_core {
+
+template <typename T, size_t Size>
+class SliceWeakHashTable : public RefCounted<SliceWeakHashTable<T, Size>> {
+ public:
+ /// Creates a new table of at most \a size entries.
+ static RefCountedPtr<SliceWeakHashTable> Create() {
+ return MakeRefCounted<SliceWeakHashTable<T, Size>>();
+ }
+
+ /// Add a mapping from \a key to \a value, taking ownership of \a key. This
+ /// operation will always succeed. It may discard older entries.
+ void Add(grpc_slice key, T value) {
+ const size_t idx = grpc_slice_hash(key) % Size;
+ entries_[idx].Set(key, std::move(value));
+ return;
+ }
+
+ /// Returns the value from the table associated with / \a key or null if not
+ /// found.
+ const T* Get(const grpc_slice key) const {
+ const size_t idx = grpc_slice_hash(key) % Size;
+ const auto& entry = entries_[idx];
+ return grpc_slice_eq(entry.key(), key) ? entry.value() : nullptr;
+ }
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T2, typename... Args>
+ friend T2* New(Args&&... args);
+
+ SliceWeakHashTable() = default;
+ ~SliceWeakHashTable() = default;
+
+ /// The type of the table "rows".
+ class Entry {
+ public:
+ Entry() = default;
+ ~Entry() {
+ if (is_set_) grpc_slice_unref_internal(key_);
+ }
+ grpc_slice key() const { return key_; }
+
+ /// Return the entry's value, or null if unset.
+ const T* value() const {
+ if (!is_set_) return nullptr;
+ return &value_;
+ }
+
+ /// Set the \a key and \a value (which is moved) for the entry.
+ void Set(grpc_slice key, T&& value) {
+ if (is_set_) grpc_slice_unref_internal(key_);
+ key_ = key;
+ value_ = std::move(value);
+ is_set_ = true;
+ }
+
+ private:
+ grpc_slice key_;
+ T value_;
+ bool is_set_ = false;
+ };
+
+ Entry entries_[Size];
+};
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_LIB_SLICE_SLICE_WEAK_HASH_TABLE_H */
diff --git a/src/core/lib/surface/api_trace.cc b/src/core/lib/surface/api_trace.cc
index 7ab836a9ba..bab5a7910c 100644
--- a/src/core/lib/surface/api_trace.cc
+++ b/src/core/lib/surface/api_trace.cc
@@ -16,7 +16,9 @@
*
*/
-#include "src/core/lib/surface/api_trace.h"
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/debug/trace.h"
+#include "src/core/lib/surface/api_trace.h"
grpc_core::TraceFlag grpc_api_trace(false, "api");
diff --git a/src/core/lib/surface/api_trace.h b/src/core/lib/surface/api_trace.h
index a4e11ce154..72ed830554 100644
--- a/src/core/lib/surface/api_trace.h
+++ b/src/core/lib/surface/api_trace.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_API_TRACE_H
#define GRPC_CORE_LIB_SURFACE_API_TRACE_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/support/log.h>
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/lib/surface/byte_buffer.cc b/src/core/lib/surface/byte_buffer.cc
index 01cbf7354a..fce87dc611 100644
--- a/src/core/lib/surface/byte_buffer.cc
+++ b/src/core/lib/surface/byte_buffer.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/byte_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
diff --git a/src/core/lib/surface/byte_buffer_reader.cc b/src/core/lib/surface/byte_buffer_reader.cc
index f7ea5161c7..a10f1a3933 100644
--- a/src/core/lib/surface/byte_buffer_reader.cc
+++ b/src/core/lib/surface/byte_buffer_reader.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/byte_buffer_reader.h>
#include <string.h>
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 2d5077525c..c4844da318 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -48,6 +50,7 @@
#include "src/core/lib/transport/error_utils.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
+#include "src/core/lib/transport/status_metadata.h"
#include "src/core/lib/transport/transport.h"
/** The maximum number of concurrent batches possible.
@@ -974,32 +977,6 @@ static int prepare_application_metadata(grpc_call* call, int count,
return 1;
}
-/* we offset status by a small amount when storing it into transport metadata
- as metadata cannot store a 0 value (which is used as OK for grpc_status_codes
- */
-#define STATUS_OFFSET 1
-static void destroy_status(void* ignored) {}
-
-static uint32_t decode_status(grpc_mdelem md) {
- uint32_t status;
- void* user_data;
- if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) return 0;
- if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) return 1;
- if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) return 2;
- user_data = grpc_mdelem_get_user_data(md, destroy_status);
- if (user_data != nullptr) {
- status = (static_cast<uint32_t>((intptr_t)user_data)) - STATUS_OFFSET;
- } else {
- if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(md), &status)) {
- status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
- }
- grpc_mdelem_set_user_data(
- md, destroy_status,
- (void*)static_cast<intptr_t>(status + STATUS_OFFSET));
- }
- return status;
-}
-
static grpc_message_compression_algorithm decode_message_compression(
grpc_mdelem md) {
grpc_message_compression_algorithm algorithm =
@@ -1091,7 +1068,8 @@ static void recv_initial_filter(grpc_call* call, grpc_metadata_batch* b) {
static void recv_trailing_filter(void* args, grpc_metadata_batch* b) {
grpc_call* call = static_cast<grpc_call*>(args);
if (b->idx.named.grpc_status != nullptr) {
- uint32_t status_code = decode_status(b->idx.named.grpc_status->md);
+ grpc_status_code status_code =
+ grpc_get_status_code_from_metadata(b->idx.named.grpc_status->md);
grpc_error* error =
status_code == GRPC_STATUS_OK
? GRPC_ERROR_NONE
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 189329ccc4..793cce4efa 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_CALL_H
#define GRPC_CORE_LIB_SURFACE_CALL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/context.h"
#include "src/core/lib/surface/api_trace.h"
diff --git a/src/core/lib/surface/call_details.cc b/src/core/lib/surface/call_details.cc
index cd0b14586a..7f20b1dae7 100644
--- a/src/core/lib/surface/call_details.cc
+++ b/src/core/lib/surface/call_details.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/surface/call_log_batch.cc b/src/core/lib/surface/call_log_batch.cc
index d56ea2a932..f0c82c0357 100644
--- a/src/core/lib/surface/call_log_batch.cc
+++ b/src/core/lib/surface/call_log_batch.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/call.h"
#include <inttypes.h>
diff --git a/src/core/lib/surface/call_test_only.h b/src/core/lib/surface/call_test_only.h
index 9eb32f03fb..dbd1a866ca 100644
--- a/src/core/lib/surface/call_test_only.h
+++ b/src/core/lib/surface/call_test_only.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_CALL_TEST_ONLY_H
#define GRPC_CORE_LIB_SURFACE_CALL_TEST_ONLY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
/** Return the message compression algorithm from \a call.
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index fa5e751acf..8851aac739 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/channel.h"
#include <inttypes.h>
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 12a806ecd7..c980151537 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_H
#define GRPC_CORE_LIB_SURFACE_CHANNEL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/surface/channel_stack_type.h"
diff --git a/src/core/lib/surface/channel_init.cc b/src/core/lib/surface/channel_init.cc
index b1e1dceed3..62eb1c3f9d 100644
--- a/src/core/lib/surface/channel_init.cc
+++ b/src/core/lib/surface/channel_init.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/channel_init.h"
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h
index d702f0f325..f01852473b 100644
--- a/src/core/lib/surface/channel_init.h
+++ b/src/core/lib/surface/channel_init.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H
#define GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack_builder.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/transport/transport.h"
diff --git a/src/core/lib/surface/channel_ping.cc b/src/core/lib/surface/channel_ping.cc
index 513519d991..bae945942f 100644
--- a/src/core/lib/surface/channel_ping.cc
+++ b/src/core/lib/surface/channel_ping.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/channel.h"
#include <string.h>
diff --git a/src/core/lib/surface/channel_stack_type.cc b/src/core/lib/surface/channel_stack_type.cc
index 366c452942..fcf96ddc9f 100644
--- a/src/core/lib/surface/channel_stack_type.cc
+++ b/src/core/lib/surface/channel_stack_type.cc
@@ -16,10 +16,11 @@
*
*/
-#include "src/core/lib/surface/channel_stack_type.h"
-#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
+#include <grpc/support/log.h>
+#include "src/core/lib/surface/channel_stack_type.h"
+
bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) {
switch (type) {
case GRPC_CLIENT_CHANNEL:
diff --git a/src/core/lib/surface/channel_stack_type.h b/src/core/lib/surface/channel_stack_type.h
index 52f85a6406..8a3c08e1cc 100644
--- a/src/core/lib/surface/channel_stack_type.h
+++ b/src/core/lib/surface/channel_stack_type.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_STACK_TYPE_H
#define GRPC_CORE_LIB_SURFACE_CHANNEL_STACK_TYPE_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
typedef enum {
diff --git a/src/core/lib/surface/completion_queue.h b/src/core/lib/surface/completion_queue.h
index aea47afaf5..c9dc2d93c1 100644
--- a/src/core/lib/surface/completion_queue.h
+++ b/src/core/lib/surface/completion_queue.h
@@ -21,6 +21,8 @@
/* Internal API for completion queues */
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/pollset.h"
diff --git a/src/core/lib/surface/completion_queue_factory.cc b/src/core/lib/surface/completion_queue_factory.cc
index d0bb065c8f..51c1183c5f 100644
--- a/src/core/lib/surface/completion_queue_factory.cc
+++ b/src/core/lib/surface/completion_queue_factory.cc
@@ -16,8 +16,10 @@
*
*/
-#include "src/core/lib/surface/completion_queue_factory.h"
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/completion_queue.h"
+#include "src/core/lib/surface/completion_queue_factory.h"
#include <grpc/support/log.h>
diff --git a/src/core/lib/surface/completion_queue_factory.h b/src/core/lib/surface/completion_queue_factory.h
index 89be8f8216..d2b30a9ce1 100644
--- a/src/core/lib/surface/completion_queue_factory.h
+++ b/src/core/lib/surface/completion_queue_factory.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_FACTORY_H
#define GRPC_CORE_LIB_SURFACE_COMPLETION_QUEUE_FACTORY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/surface/completion_queue.h"
diff --git a/src/core/lib/surface/event_string.cc b/src/core/lib/surface/event_string.cc
index 7f40bb2405..d639baec45 100644
--- a/src/core/lib/surface/event_string.cc
+++ b/src/core/lib/surface/event_string.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/event_string.h"
#include <stdio.h>
diff --git a/src/core/lib/surface/event_string.h b/src/core/lib/surface/event_string.h
index cbf96da6c5..e6095705e9 100644
--- a/src/core/lib/surface/event_string.h
+++ b/src/core/lib/surface/event_string.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_EVENT_STRING_H
#define GRPC_CORE_LIB_SURFACE_EVENT_STRING_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
/* Returns a string describing an event. Must be later freed with gpr_free() */
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index b8e2ea0043..775fb468c6 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -33,7 +33,7 @@
#include "src/core/lib/debug/stats.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/fork.h"
-#include "src/core/lib/gpr/thd_internal.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/call_combiner.h"
#include "src/core/lib/iomgr/combiner.h"
diff --git a/src/core/lib/surface/init_secure.cc b/src/core/lib/surface/init_secure.cc
index 75ed9faef0..78e983e0cd 100644
--- a/src/core/lib/surface/init_secure.cc
+++ b/src/core/lib/surface/init_secure.cc
@@ -27,9 +27,9 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/plugin/plugin_credentials.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/security/transport/auth_filters.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
-#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/surface/channel_init.h"
#include "src/core/tsi/transport_security_interface.h"
diff --git a/src/core/lib/surface/init_unsecure.cc b/src/core/lib/surface/init_unsecure.cc
index b852cab985..2b3bc64382 100644
--- a/src/core/lib/surface/init_unsecure.cc
+++ b/src/core/lib/surface/init_unsecure.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/init.h"
void grpc_security_pre_init(void) {}
diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc
index a1f1cf1107..f5aca91f97 100644
--- a/src/core/lib/surface/lame_client.cc
+++ b/src/core/lib/surface/lame_client.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <string.h>
diff --git a/src/core/lib/surface/lame_client.h b/src/core/lib/surface/lame_client.h
index 3ce353f101..aefa67c24a 100644
--- a/src/core/lib/surface/lame_client.h
+++ b/src/core/lib/surface/lame_client.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H
#define GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/channel/channel_stack.h"
extern const grpc_channel_filter grpc_lame_filter;
diff --git a/src/core/lib/surface/metadata_array.cc b/src/core/lib/surface/metadata_array.cc
index 0afb8b4b87..f794a2bb95 100644
--- a/src/core/lib/surface/metadata_array.cc
+++ b/src/core/lib/surface/metadata_array.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index d71a23a5d7..f7505c888e 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/surface/server.h"
#include <limits.h>
diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h
index 63b6dff16b..c617cc223e 100644
--- a/src/core/lib/surface/server.h
+++ b/src/core/lib/surface/server.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_SERVER_H
#define GRPC_CORE_LIB_SURFACE_SERVER_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/lib/surface/validate_metadata.cc b/src/core/lib/surface/validate_metadata.cc
index fc94ea7dbe..2dd18f3dd3 100644
--- a/src/core/lib/surface/validate_metadata.cc
+++ b/src/core/lib/surface/validate_metadata.cc
@@ -16,12 +16,13 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <stdlib.h>
#include <string.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
-#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/slice/slice_internal.h"
diff --git a/src/core/lib/surface/validate_metadata.h b/src/core/lib/surface/validate_metadata.h
index ff074b00b2..e87fb7beed 100644
--- a/src/core/lib/surface/validate_metadata.h
+++ b/src/core/lib/surface/validate_metadata.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_SURFACE_VALIDATE_METADATA_H
#define GRPC_CORE_LIB_SURFACE_VALIDATE_METADATA_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include "src/core/lib/iomgr/error.h"
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index 51daad0368..be196a78bc 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -19,8 +19,10 @@
/* This file is autogenerated from:
templates/src/core/surface/version.c.template */
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
const char* grpc_version_string(void) { return "6.0.0-dev"; }
-const char* grpc_g_stands_for(void) { return "glamorous"; }
+const char* grpc_g_stands_for(void) { return "gorgeous"; }
diff --git a/src/core/lib/transport/bdp_estimator.cc b/src/core/lib/transport/bdp_estimator.cc
index 70b308230b..8130535ddd 100644
--- a/src/core/lib/transport/bdp_estimator.cc
+++ b/src/core/lib/transport/bdp_estimator.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/bdp_estimator.h"
#include <inttypes.h>
diff --git a/src/core/lib/transport/byte_stream.cc b/src/core/lib/transport/byte_stream.cc
index afb55b2f20..e1751f8010 100644
--- a/src/core/lib/transport/byte_stream.cc
+++ b/src/core/lib/transport/byte_stream.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/byte_stream.h"
#include <stdlib.h>
@@ -51,7 +53,7 @@ static bool slice_buffer_stream_next(grpc_byte_stream* byte_stream,
grpc_closure* on_complete) {
grpc_slice_buffer_stream* stream =
reinterpret_cast<grpc_slice_buffer_stream*>(byte_stream);
- GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
+ GPR_ASSERT(stream->cursor < stream->backing_buffer.count);
return true;
}
@@ -62,9 +64,9 @@ static grpc_error* slice_buffer_stream_pull(grpc_byte_stream* byte_stream,
if (stream->shutdown_error != GRPC_ERROR_NONE) {
return GRPC_ERROR_REF(stream->shutdown_error);
}
- GPR_ASSERT(stream->cursor < stream->backing_buffer->count);
+ GPR_ASSERT(stream->cursor < stream->backing_buffer.count);
*slice =
- grpc_slice_ref_internal(stream->backing_buffer->slices[stream->cursor]);
+ grpc_slice_ref_internal(stream->backing_buffer.slices[stream->cursor]);
stream->cursor++;
return GRPC_ERROR_NONE;
}
@@ -80,7 +82,7 @@ static void slice_buffer_stream_shutdown(grpc_byte_stream* byte_stream,
static void slice_buffer_stream_destroy(grpc_byte_stream* byte_stream) {
grpc_slice_buffer_stream* stream =
reinterpret_cast<grpc_slice_buffer_stream*>(byte_stream);
- grpc_slice_buffer_reset_and_unref_internal(stream->backing_buffer);
+ grpc_slice_buffer_destroy(&stream->backing_buffer);
GRPC_ERROR_UNREF(stream->shutdown_error);
}
@@ -95,7 +97,8 @@ void grpc_slice_buffer_stream_init(grpc_slice_buffer_stream* stream,
stream->base.length = static_cast<uint32_t>(slice_buffer->length);
stream->base.flags = flags;
stream->base.vtable = &slice_buffer_stream_vtable;
- stream->backing_buffer = slice_buffer;
+ grpc_slice_buffer_init(&stream->backing_buffer);
+ grpc_slice_buffer_swap(slice_buffer, &stream->backing_buffer);
stream->cursor = 0;
stream->shutdown_error = GRPC_ERROR_NONE;
}
diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h
index 52c7a07f56..4d3c3c131b 100644
--- a/src/core/lib/transport/byte_stream.h
+++ b/src/core/lib/transport/byte_stream.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_BYTE_STREAM_H
#define GRPC_CORE_LIB_TRANSPORT_BYTE_STREAM_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice_buffer.h>
#include "src/core/lib/iomgr/exec_ctx.h"
@@ -81,7 +83,7 @@ void grpc_byte_stream_destroy(grpc_byte_stream* byte_stream);
typedef struct grpc_slice_buffer_stream {
grpc_byte_stream base;
- grpc_slice_buffer* backing_buffer;
+ grpc_slice_buffer backing_buffer;
size_t cursor;
grpc_error* shutdown_error;
} grpc_slice_buffer_stream;
diff --git a/src/core/lib/transport/connectivity_state.cc b/src/core/lib/transport/connectivity_state.cc
index 17f3529a0e..0122e773ca 100644
--- a/src/core/lib/transport/connectivity_state.cc
+++ b/src/core/lib/transport/connectivity_state.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/connectivity_state.h"
#include <string.h>
diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h
index c3a50f3211..421db5aa39 100644
--- a/src/core/lib/transport/connectivity_state.h
+++ b/src/core/lib/transport/connectivity_state.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H
#define GRPC_CORE_LIB_TRANSPORT_CONNECTIVITY_STATE_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/exec_ctx.h"
diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc
index 79d904315e..2eff8b2916 100644
--- a/src/core/lib/transport/error_utils.cc
+++ b/src/core/lib/transport/error_utils.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/error_utils.h"
#include <grpc/support/string_util.h>
diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h
index 4100f65d6d..9a46267f38 100644
--- a/src/core/lib/transport/error_utils.h
+++ b/src/core/lib/transport/error_utils.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
#define GRPC_CORE_LIB_TRANSPORT_ERROR_UTILS_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/http2_errors.h"
diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc
index e06e0b5313..d10194a2fe 100644
--- a/src/core/lib/transport/metadata.cc
+++ b/src/core/lib/transport/metadata.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/metadata.h"
#include <assert.h>
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 82142ebed8..5e0ecbdb96 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_H
#define GRPC_CORE_LIB_TRANSPORT_METADATA_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/slice.h>
diff --git a/src/core/lib/transport/metadata_batch.cc b/src/core/lib/transport/metadata_batch.cc
index 9c95339ba0..49740fcd1e 100644
--- a/src/core/lib/transport/metadata_batch.cc
+++ b/src/core/lib/transport/metadata_batch.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/metadata_batch.h"
#include <stdbool.h>
@@ -301,3 +303,27 @@ grpc_error* grpc_metadata_batch_filter(grpc_metadata_batch* batch,
}
return error;
}
+
+void grpc_metadata_batch_copy(grpc_metadata_batch* src,
+ grpc_metadata_batch* dst,
+ grpc_linked_mdelem* storage) {
+ grpc_metadata_batch_init(dst);
+ dst->deadline = src->deadline;
+ size_t i = 0;
+ for (grpc_linked_mdelem* elem = src->list.head; elem != nullptr;
+ elem = elem->next) {
+ grpc_error* error = grpc_metadata_batch_add_tail(dst, &storage[i++],
+ GRPC_MDELEM_REF(elem->md));
+ // The only way that grpc_metadata_batch_add_tail() can fail is if
+ // there's a duplicate entry for a callout. However, that can't be
+ // the case here, because we would not have been allowed to create
+ // a source batch that had that kind of conflict.
+ GPR_ASSERT(error == GRPC_ERROR_NONE);
+ }
+}
+
+void grpc_metadata_batch_move(grpc_metadata_batch* src,
+ grpc_metadata_batch* dst) {
+ *dst = *src;
+ grpc_metadata_batch_init(src);
+}
diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h
index 8353a426f8..3876063b52 100644
--- a/src/core/lib/transport/metadata_batch.h
+++ b/src/core/lib/transport/metadata_batch.h
@@ -19,11 +19,12 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
#define GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include <grpc/grpc.h>
#include <grpc/slice.h>
-#include <grpc/support/port_platform.h>
#include <grpc/support/time.h>
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
@@ -136,4 +137,13 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch* comd);
} while (0)
#endif
+/// Copies \a src to \a dst. \a storage must point to an array of
+/// \a grpc_linked_mdelem structs of at least the same size as \a src.
+void grpc_metadata_batch_copy(grpc_metadata_batch* src,
+ grpc_metadata_batch* dst,
+ grpc_linked_mdelem* storage);
+
+void grpc_metadata_batch_move(grpc_metadata_batch* src,
+ grpc_metadata_batch* dst);
+
#endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */
diff --git a/src/core/lib/transport/pid_controller.cc b/src/core/lib/transport/pid_controller.cc
index b33ea63df6..dbc98f4917 100644
--- a/src/core/lib/transport/pid_controller.cc
+++ b/src/core/lib/transport/pid_controller.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/pid_controller.h"
#include "src/core/lib/gpr/useful.h"
diff --git a/src/core/lib/transport/pid_controller.h b/src/core/lib/transport/pid_controller.h
index 87e59a1a90..e26205bf20 100644
--- a/src/core/lib/transport/pid_controller.h
+++ b/src/core/lib/transport/pid_controller.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H
#define GRPC_CORE_LIB_TRANSPORT_PID_CONTROLLER_H
+#include <grpc/support/port_platform.h>
+
#include <limits>
/* \file Simple PID controller.
diff --git a/src/core/lib/transport/service_config.cc b/src/core/lib/transport/service_config.cc
index 75196c5f88..e1a55d98ab 100644
--- a/src/core/lib/transport/service_config.cc
+++ b/src/core/lib/transport/service_config.cc
@@ -14,6 +14,8 @@
// limitations under the License.
//
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/service_config.h"
#include <string.h>
@@ -29,74 +31,30 @@
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
-// The main purpose of the code here is to parse the service config in
-// JSON form, which will look like this:
-//
-// {
-// "loadBalancingPolicy": "string", // optional
-// "methodConfig": [ // array of one or more method_config objects
-// {
-// "name": [ // array of one or more name objects
-// {
-// "service": "string", // required
-// "method": "string", // optional
-// }
-// ],
-// // remaining fields are optional.
-// // see https://developers.google.com/protocol-buffers/docs/proto3#json
-// // for format details.
-// "waitForReady": bool,
-// "timeout": "duration_string",
-// "maxRequestMessageBytes": "int64_string",
-// "maxResponseMessageBytes": "int64_string",
-// }
-// ]
-// }
-
-struct grpc_service_config {
- char* json_string; // Underlying storage for json_tree.
- grpc_json* json_tree;
-};
+namespace grpc_core {
-grpc_service_config* grpc_service_config_create(const char* json_string) {
- grpc_service_config* service_config =
- static_cast<grpc_service_config*>(gpr_malloc(sizeof(*service_config)));
- service_config->json_string = gpr_strdup(json_string);
- service_config->json_tree =
- grpc_json_parse_string(service_config->json_string);
- if (service_config->json_tree == nullptr) {
+UniquePtr<ServiceConfig> ServiceConfig::Create(const char* json) {
+ UniquePtr<char> json_string(gpr_strdup(json));
+ grpc_json* json_tree = grpc_json_parse_string(json_string.get());
+ if (json_tree == nullptr) {
gpr_log(GPR_INFO, "failed to parse JSON for service config");
- gpr_free(service_config->json_string);
- gpr_free(service_config);
return nullptr;
}
- return service_config;
+ return MakeUnique<ServiceConfig>(std::move(json_string), json_tree);
}
-void grpc_service_config_destroy(grpc_service_config* service_config) {
- grpc_json_destroy(service_config->json_tree);
- gpr_free(service_config->json_string);
- gpr_free(service_config);
-}
+ServiceConfig::ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree)
+ : json_string_(std::move(json_string)), json_tree_(json_tree) {}
-void grpc_service_config_parse_global_params(
- const grpc_service_config* service_config,
- void (*process_json)(const grpc_json* json, void* arg), void* arg) {
- const grpc_json* json = service_config->json_tree;
- if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return;
- for (grpc_json* field = json->child; field != nullptr; field = field->next) {
- if (field->key == nullptr) return;
- if (strcmp(field->key, "methodConfig") == 0) continue;
- process_json(field, arg);
- }
-}
+ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); }
-const char* grpc_service_config_get_lb_policy_name(
- const grpc_service_config* service_config) {
- const grpc_json* json = service_config->json_tree;
- if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return nullptr;
+const char* ServiceConfig::GetLoadBalancingPolicyName() const {
+ if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
+ return nullptr;
+ }
const char* lb_policy_name = nullptr;
- for (grpc_json* field = json->child; field != nullptr; field = field->next) {
+ for (grpc_json* field = json_tree_->child; field != nullptr;
+ field = field->next) {
if (field->key == nullptr) return nullptr;
if (strcmp(field->key, "loadBalancingPolicy") == 0) {
if (lb_policy_name != nullptr) return nullptr; // Duplicate.
@@ -107,8 +65,7 @@ const char* grpc_service_config_get_lb_policy_name(
return lb_policy_name;
}
-// Returns the number of names specified in the method config \a json.
-static size_t count_names_in_method_config_json(grpc_json* json) {
+size_t ServiceConfig::CountNamesInMethodConfig(grpc_json* json) {
size_t num_names = 0;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key != nullptr && strcmp(field->key, "name") == 0) {
@@ -122,9 +79,7 @@ static size_t count_names_in_method_config_json(grpc_json* json) {
return num_names;
}
-// Returns a path string for the JSON name object specified by \a json.
-// Returns NULL on error. Caller takes ownership of result.
-static char* parse_json_method_name(grpc_json* json) {
+UniquePtr<char> ServiceConfig::ParseJsonMethodName(grpc_json* json) {
if (json->type != GRPC_JSON_OBJECT) return nullptr;
const char* service_name = nullptr;
const char* method_name = nullptr;
@@ -145,116 +100,7 @@ static char* parse_json_method_name(grpc_json* json) {
char* path;
gpr_asprintf(&path, "/%s/%s", service_name,
method_name == nullptr ? "*" : method_name);
- return path;
-}
-
-// Parses the method config from \a json. Adds an entry to \a entries for
-// each name found, incrementing \a idx for each entry added.
-// Returns false on error.
-static bool parse_json_method_config(
- grpc_json* json, void* (*create_value)(const grpc_json* method_config_json),
- void* (*ref_value)(void* value), void (*unref_value)(void* value),
- grpc_slice_hash_table_entry* entries, size_t* idx) {
- // Construct value.
- void* method_config = create_value(json);
- if (method_config == nullptr) return false;
- // Construct list of paths.
- bool success = false;
- gpr_strvec paths;
- gpr_strvec_init(&paths);
- for (grpc_json* child = json->child; child != nullptr; child = child->next) {
- if (child->key == nullptr) continue;
- if (strcmp(child->key, "name") == 0) {
- if (child->type != GRPC_JSON_ARRAY) goto done;
- for (grpc_json* name = child->child; name != nullptr; name = name->next) {
- char* path = parse_json_method_name(name);
- if (path == nullptr) goto done;
- gpr_strvec_add(&paths, path);
- }
- }
- }
- if (paths.count == 0) goto done; // No names specified.
- // Add entry for each path.
- for (size_t i = 0; i < paths.count; ++i) {
- entries[*idx].key = grpc_slice_from_copied_string(paths.strs[i]);
- entries[*idx].value = ref_value(method_config);
- ++*idx;
- }
- success = true;
-done:
- unref_value(method_config);
- gpr_strvec_destroy(&paths);
- return success;
-}
-
-grpc_slice_hash_table* grpc_service_config_create_method_config_table(
- const grpc_service_config* service_config,
- void* (*create_value)(const grpc_json* method_config_json),
- void* (*ref_value)(void* value), void (*unref_value)(void* value)) {
- const grpc_json* json = service_config->json_tree;
- // Traverse parsed JSON tree.
- if (json->type != GRPC_JSON_OBJECT || json->key != nullptr) return nullptr;
- size_t num_entries = 0;
- grpc_slice_hash_table_entry* entries = nullptr;
- for (grpc_json* field = json->child; field != nullptr; field = field->next) {
- if (field->key == nullptr) return nullptr;
- if (strcmp(field->key, "methodConfig") == 0) {
- if (entries != nullptr) return nullptr; // Duplicate.
- if (field->type != GRPC_JSON_ARRAY) return nullptr;
- // Find number of entries.
- for (grpc_json* method = field->child; method != nullptr;
- method = method->next) {
- size_t count = count_names_in_method_config_json(method);
- if (count <= 0) return nullptr;
- num_entries += count;
- }
- // Populate method config table entries.
- entries = static_cast<grpc_slice_hash_table_entry*>(
- gpr_malloc(num_entries * sizeof(grpc_slice_hash_table_entry)));
- size_t idx = 0;
- for (grpc_json* method = field->child; method != nullptr;
- method = method->next) {
- if (!parse_json_method_config(method, create_value, ref_value,
- unref_value, entries, &idx)) {
- for (size_t i = 0; i < idx; ++i) {
- grpc_slice_unref_internal(entries[i].key);
- unref_value(entries[i].value);
- }
- gpr_free(entries);
- return nullptr;
- }
- }
- GPR_ASSERT(idx == num_entries);
- }
- }
- // Instantiate method config table.
- grpc_slice_hash_table* method_config_table = nullptr;
- if (entries != nullptr) {
- method_config_table = grpc_slice_hash_table_create(num_entries, entries,
- unref_value, nullptr);
- gpr_free(entries);
- }
- return method_config_table;
+ return UniquePtr<char>(path);
}
-void* grpc_method_config_table_get(const grpc_slice_hash_table* table,
- grpc_slice path) {
- void* value = grpc_slice_hash_table_get(table, path);
- // If we didn't find a match for the path, try looking for a wildcard
- // entry (i.e., change "/service/method" to "/service/*").
- if (value == nullptr) {
- char* path_str = grpc_slice_to_c_string(path);
- const char* sep = strrchr(path_str, '/') + 1;
- const size_t len = static_cast<size_t>(sep - path_str);
- char* buf = static_cast<char*>(gpr_malloc(len + 2)); // '*' and NUL
- memcpy(buf, path_str, len);
- buf[len] = '*';
- buf[len + 1] = '\0';
- grpc_slice wildcard_path = grpc_slice_from_copied_string(buf);
- gpr_free(buf);
- value = grpc_slice_hash_table_get(table, wildcard_path);
- grpc_slice_unref_internal(wildcard_path);
- gpr_free(path_str);
- }
- return value;
-}
+} // namespace grpc_core
diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h
index 98554b9f0f..a65b267d46 100644
--- a/src/core/lib/transport/service_config.h
+++ b/src/core/lib/transport/service_config.h
@@ -17,45 +17,233 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H
#define GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/string_util.h>
+#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/slice/slice_hash_table.h"
-typedef struct grpc_service_config grpc_service_config;
-
-grpc_service_config* grpc_service_config_create(const char* json_string);
-void grpc_service_config_destroy(grpc_service_config* service_config);
-
-/// Invokes \a process_json() for each global parameter in the service
-/// config. \a arg is passed as the second argument to \a process_json().
-void grpc_service_config_parse_global_params(
- const grpc_service_config* service_config,
- void (*process_json)(const grpc_json* json, void* arg), void* arg);
-
-/// Gets the LB policy name from \a service_config.
-/// Returns NULL if no LB policy name was specified.
-/// Caller does NOT take ownership.
-const char* grpc_service_config_get_lb_policy_name(
- const grpc_service_config* service_config);
-
-/// Creates a method config table based on the data in \a json.
-/// The table's keys are request paths. The table's value type is
-/// returned by \a create_value(), based on data parsed from the JSON tree.
-/// \a ref_value() and \a unref_value() are used to ref and unref values.
-/// Returns NULL on error.
-grpc_slice_hash_table* grpc_service_config_create_method_config_table(
- const grpc_service_config* service_config,
- void* (*create_value)(const grpc_json* method_config_json),
- void* (*ref_value)(void* value), void (*unref_value)(void* value));
-
-/// A helper function for looking up values in the table returned by
-/// \a grpc_service_config_create_method_config_table().
-/// Gets the method config for the specified \a path, which should be of
-/// the form "/service/method".
-/// Returns NULL if the method has no config.
-/// Caller does NOT own a reference to the result.
-void* grpc_method_config_table_get(const grpc_slice_hash_table* table,
- grpc_slice path);
+// The main purpose of the code here is to parse the service config in
+// JSON form, which will look like this:
+//
+// {
+// "loadBalancingPolicy": "string", // optional
+// "methodConfig": [ // array of one or more method_config objects
+// {
+// "name": [ // array of one or more name objects
+// {
+// "service": "string", // required
+// "method": "string", // optional
+// }
+// ],
+// // remaining fields are optional.
+// // see
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+// // for format details.
+// "waitForReady": bool,
+// "timeout": "duration_string",
+// "maxRequestMessageBytes": "int64_string",
+// "maxResponseMessageBytes": "int64_string",
+// }
+// ]
+// }
+
+namespace grpc_core {
+
+class ServiceConfig {
+ public:
+ /// Creates a new service config from parsing \a json_string.
+ /// Returns null on parse error.
+ static UniquePtr<ServiceConfig> Create(const char* json);
+
+ ~ServiceConfig();
+
+ /// Invokes \a process_json() for each global parameter in the service
+ /// config. \a arg is passed as the second argument to \a process_json().
+ template <typename T>
+ using ProcessJson = void (*)(const grpc_json*, T*);
+ template <typename T>
+ void ParseGlobalParams(ProcessJson<T> process_json, T* arg) const;
+
+ /// Gets the LB policy name from \a service_config.
+ /// Returns NULL if no LB policy name was specified.
+ /// Caller does NOT take ownership.
+ const char* GetLoadBalancingPolicyName() const;
+
+ /// Creates a method config table based on the data in \a json.
+ /// The table's keys are request paths. The table's value type is
+ /// returned by \a create_value(), based on data parsed from the JSON tree.
+ /// Returns null on error.
+ template <typename T>
+ using CreateValue = RefCountedPtr<T> (*)(const grpc_json* method_config_json);
+ template <typename T>
+ RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> CreateMethodConfigTable(
+ CreateValue<T> create_value);
+
+ /// A helper function for looking up values in the table returned by
+ /// \a CreateMethodConfigTable().
+ /// Gets the method config for the specified \a path, which should be of
+ /// the form "/service/method".
+ /// Returns null if the method has no config.
+ /// Caller does NOT own a reference to the result.
+ template <typename T>
+ static RefCountedPtr<T> MethodConfigTableLookup(
+ const SliceHashTable<RefCountedPtr<T>>& table, grpc_slice path);
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T, typename... Args>
+ friend T* New(Args&&... args);
+
+ // Takes ownership of \a json_tree.
+ ServiceConfig(UniquePtr<char> json_string, grpc_json* json_tree);
+
+ // Returns the number of names specified in the method config \a json.
+ static size_t CountNamesInMethodConfig(grpc_json* json);
+
+ // Returns a path string for the JSON name object specified by \a json.
+ // Returns null on error.
+ static UniquePtr<char> ParseJsonMethodName(grpc_json* json);
+
+ // Parses the method config from \a json. Adds an entry to \a entries for
+ // each name found, incrementing \a idx for each entry added.
+ // Returns false on error.
+ template <typename T>
+ static bool ParseJsonMethodConfig(
+ grpc_json* json, CreateValue<T> create_value,
+ typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx);
+
+ UniquePtr<char> json_string_; // Underlying storage for json_tree.
+ grpc_json* json_tree_;
+};
+
+//
+// implementation -- no user-serviceable parts below
+//
+
+template <typename T>
+void ServiceConfig::ParseGlobalParams(ProcessJson<T> process_json,
+ T* arg) const {
+ if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
+ return;
+ }
+ for (grpc_json* field = json_tree_->child; field != nullptr;
+ field = field->next) {
+ if (field->key == nullptr) return;
+ if (strcmp(field->key, "methodConfig") == 0) continue;
+ process_json(field, arg);
+ }
+}
+
+template <typename T>
+bool ServiceConfig::ParseJsonMethodConfig(
+ grpc_json* json, CreateValue<T> create_value,
+ typename SliceHashTable<RefCountedPtr<T>>::Entry* entries, size_t* idx) {
+ // Construct value.
+ RefCountedPtr<T> method_config = create_value(json);
+ if (method_config == nullptr) return false;
+ // Construct list of paths.
+ InlinedVector<UniquePtr<char>, 10> paths;
+ for (grpc_json* child = json->child; child != nullptr; child = child->next) {
+ if (child->key == nullptr) continue;
+ if (strcmp(child->key, "name") == 0) {
+ if (child->type != GRPC_JSON_ARRAY) return false;
+ for (grpc_json* name = child->child; name != nullptr; name = name->next) {
+ UniquePtr<char> path = ParseJsonMethodName(name);
+ if (path == nullptr) return false;
+ paths.push_back(std::move(path));
+ }
+ }
+ }
+ if (paths.size() == 0) return false; // No names specified.
+ // Add entry for each path.
+ for (size_t i = 0; i < paths.size(); ++i) {
+ entries[*idx].key = grpc_slice_from_copied_string(paths[i].get());
+ entries[*idx].value = method_config; // Takes a new ref.
+ ++*idx;
+ }
+ // Success.
+ return true;
+}
+
+template <typename T>
+RefCountedPtr<SliceHashTable<RefCountedPtr<T>>>
+ServiceConfig::CreateMethodConfigTable(CreateValue<T> create_value) {
+ // Traverse parsed JSON tree.
+ if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) {
+ return nullptr;
+ }
+ size_t num_entries = 0;
+ typename SliceHashTable<RefCountedPtr<T>>::Entry* entries = nullptr;
+ for (grpc_json* field = json_tree_->child; field != nullptr;
+ field = field->next) {
+ if (field->key == nullptr) return nullptr;
+ if (strcmp(field->key, "methodConfig") == 0) {
+ if (entries != nullptr) return nullptr; // Duplicate.
+ if (field->type != GRPC_JSON_ARRAY) return nullptr;
+ // Find number of entries.
+ for (grpc_json* method = field->child; method != nullptr;
+ method = method->next) {
+ size_t count = CountNamesInMethodConfig(method);
+ if (count <= 0) return nullptr;
+ num_entries += count;
+ }
+ // Populate method config table entries.
+ entries = static_cast<typename SliceHashTable<RefCountedPtr<T>>::Entry*>(
+ gpr_zalloc(num_entries *
+ sizeof(typename SliceHashTable<RefCountedPtr<T>>::Entry)));
+ size_t idx = 0;
+ for (grpc_json* method = field->child; method != nullptr;
+ method = method->next) {
+ if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) {
+ for (size_t i = 0; i < idx; ++i) {
+ grpc_slice_unref_internal(entries[i].key);
+ entries[i].value.reset();
+ }
+ gpr_free(entries);
+ return nullptr;
+ }
+ }
+ GPR_ASSERT(idx == num_entries);
+ }
+ }
+ // Instantiate method config table.
+ RefCountedPtr<SliceHashTable<RefCountedPtr<T>>> method_config_table;
+ if (entries != nullptr) {
+ method_config_table =
+ SliceHashTable<RefCountedPtr<T>>::Create(num_entries, entries, nullptr);
+ gpr_free(entries);
+ }
+ return method_config_table;
+}
+
+template <typename T>
+RefCountedPtr<T> ServiceConfig::MethodConfigTableLookup(
+ const SliceHashTable<RefCountedPtr<T>>& table, grpc_slice path) {
+ const RefCountedPtr<T>* value = table.Get(path);
+ // If we didn't find a match for the path, try looking for a wildcard
+ // entry (i.e., change "/service/method" to "/service/*").
+ if (value == nullptr) {
+ char* path_str = grpc_slice_to_c_string(path);
+ const char* sep = strrchr(path_str, '/') + 1;
+ const size_t len = (size_t)(sep - path_str);
+ char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL
+ memcpy(buf, path_str, len);
+ buf[len] = '*';
+ buf[len + 1] = '\0';
+ grpc_slice wildcard_path = grpc_slice_from_copied_string(buf);
+ gpr_free(buf);
+ value = table.Get(wildcard_path);
+ grpc_slice_unref_internal(wildcard_path);
+ gpr_free(path_str);
+ }
+ return RefCountedPtr<T>(*value);
+}
+
+} // namespace grpc_core
#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */
diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc
index 5994cbc265..6a5144f21a 100644
--- a/src/core/lib/transport/static_metadata.cc
+++ b/src/core/lib/transport/static_metadata.cc
@@ -24,6 +24,8 @@
* an explanation of what's going on.
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -48,61 +50,64 @@ static uint8_t g_bytes[] = {
114, 110, 97, 108, 45, 115, 116, 114, 101, 97, 109, 45, 101, 110, 99,
111, 100, 105, 110, 103, 45, 114, 101, 113, 117, 101, 115, 116, 117, 115,
101, 114, 45, 97, 103, 101, 110, 116, 104, 111, 115, 116, 108, 98, 45,
- 116, 111, 107, 101, 110, 103, 114, 112, 99, 45, 116, 105, 109, 101, 111,
- 117, 116, 103, 114, 112, 99, 46, 119, 97, 105, 116, 95, 102, 111, 114,
- 95, 114, 101, 97, 100, 121, 103, 114, 112, 99, 46, 116, 105, 109, 101,
- 111, 117, 116, 103, 114, 112, 99, 46, 109, 97, 120, 95, 114, 101, 113,
- 117, 101, 115, 116, 95, 109, 101, 115, 115, 97, 103, 101, 95, 98, 121,
- 116, 101, 115, 103, 114, 112, 99, 46, 109, 97, 120, 95, 114, 101, 115,
- 112, 111, 110, 115, 101, 95, 109, 101, 115, 115, 97, 103, 101, 95, 98,
- 121, 116, 101, 115, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49,
- 46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66,
- 97, 108, 97, 110, 99, 101, 76, 111, 97, 100, 100, 101, 102, 108, 97,
- 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, 97, 109, 47, 103, 122,
- 105, 112, 48, 49, 50, 105, 100, 101, 110, 116, 105, 116, 121, 116, 114,
- 97, 105, 108, 101, 114, 115, 97, 112, 112, 108, 105, 99, 97, 116, 105,
- 111, 110, 47, 103, 114, 112, 99, 80, 79, 83, 84, 50, 48, 48, 52,
- 48, 52, 104, 116, 116, 112, 104, 116, 116, 112, 115, 103, 114, 112, 99,
- 71, 69, 84, 80, 85, 84, 47, 47, 105, 110, 100, 101, 120, 46, 104,
- 116, 109, 108, 50, 48, 52, 50, 48, 54, 51, 48, 52, 52, 48, 48,
- 53, 48, 48, 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115,
- 101, 116, 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101,
- 97, 99, 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101,
- 97, 99, 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99,
- 99, 101, 112, 116, 97, 99, 99, 101, 115, 115, 45, 99, 111, 110, 116,
- 114, 111, 108, 45, 97, 108, 108, 111, 119, 45, 111, 114, 105, 103, 105,
- 110, 97, 103, 101, 97, 108, 108, 111, 119, 97, 117, 116, 104, 111, 114,
- 105, 122, 97, 116, 105, 111, 110, 99, 97, 99, 104, 101, 45, 99, 111,
- 110, 116, 114, 111, 108, 99, 111, 110, 116, 101, 110, 116, 45, 100, 105,
- 115, 112, 111, 115, 105, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110,
- 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116, 101,
- 110, 116, 45, 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101, 110,
- 116, 45, 108, 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116, 101,
- 110, 116, 45, 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101, 100,
- 97, 116, 101, 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101, 120,
- 112, 105, 114, 101, 115, 102, 114, 111, 109, 105, 102, 45, 109, 97, 116,
- 99, 104, 105, 102, 45, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115,
- 105, 110, 99, 101, 105, 102, 45, 110, 111, 110, 101, 45, 109, 97, 116,
- 99, 104, 105, 102, 45, 114, 97, 110, 103, 101, 105, 102, 45, 117, 110,
- 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 108,
- 97, 115, 116, 45, 109, 111, 100, 105, 102, 105, 101, 100, 108, 98, 45,
- 99, 111, 115, 116, 45, 98, 105, 110, 108, 105, 110, 107, 108, 111, 99,
- 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114,
- 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116,
- 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104,
- 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114,
- 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101,
- 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114,
- 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99,
- 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99,
- 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101,
- 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119,
- 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101,
- 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116,
- 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, 105, 112, 100,
- 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, 100, 101, 110,
- 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122,
- 105, 112};
+ 116, 111, 107, 101, 110, 103, 114, 112, 99, 45, 112, 114, 101, 118, 105,
+ 111, 117, 115, 45, 114, 112, 99, 45, 97, 116, 116, 101, 109, 112, 116,
+ 115, 103, 114, 112, 99, 45, 114, 101, 116, 114, 121, 45, 112, 117, 115,
+ 104, 98, 97, 99, 107, 45, 109, 115, 103, 114, 112, 99, 45, 116, 105,
+ 109, 101, 111, 117, 116, 49, 50, 51, 52, 103, 114, 112, 99, 46, 119,
+ 97, 105, 116, 95, 102, 111, 114, 95, 114, 101, 97, 100, 121, 103, 114,
+ 112, 99, 46, 116, 105, 109, 101, 111, 117, 116, 103, 114, 112, 99, 46,
+ 109, 97, 120, 95, 114, 101, 113, 117, 101, 115, 116, 95, 109, 101, 115,
+ 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 103, 114, 112, 99, 46,
+ 109, 97, 120, 95, 114, 101, 115, 112, 111, 110, 115, 101, 95, 109, 101,
+ 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 47, 103, 114, 112,
+ 99, 46, 108, 98, 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108,
+ 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111,
+ 97, 100, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116,
+ 114, 101, 97, 109, 47, 103, 122, 105, 112, 48, 105, 100, 101, 110, 116,
+ 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97, 112, 112, 108,
+ 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, 80, 79, 83,
+ 84, 50, 48, 48, 52, 48, 52, 104, 116, 116, 112, 104, 116, 116, 112,
+ 115, 103, 114, 112, 99, 71, 69, 84, 80, 85, 84, 47, 47, 105, 110,
+ 100, 101, 120, 46, 104, 116, 109, 108, 50, 48, 52, 50, 48, 54, 51,
+ 48, 52, 52, 48, 48, 53, 48, 48, 97, 99, 99, 101, 112, 116, 45,
+ 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, 32, 100, 101,
+ 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, 108, 97, 110,
+ 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, 114, 97, 110,
+ 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, 101, 115, 115,
+ 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, 111, 119, 45,
+ 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, 111, 119, 97,
+ 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 99, 97, 99,
+ 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, 110, 116, 101,
+ 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, 111, 110, 99,
+ 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101,
+ 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, 116, 104, 99,
+ 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, 105, 111, 110,
+ 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, 101, 99, 111,
+ 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, 101, 120, 112,
+ 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, 111, 109, 105,
+ 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, 100, 105, 102,
+ 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, 110, 111, 110,
+ 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, 110, 103, 101,
+ 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115,
+ 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, 105, 102, 105,
+ 101, 100, 108, 98, 45, 99, 111, 115, 116, 45, 98, 105, 110, 108, 105,
+ 110, 107, 108, 111, 99, 97, 116, 105, 111, 110, 109, 97, 120, 45, 102,
+ 111, 114, 119, 97, 114, 100, 115, 112, 114, 111, 120, 121, 45, 97, 117,
+ 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121,
+ 45, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 114,
+ 97, 110, 103, 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114,
+ 101, 115, 104, 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 115,
+ 101, 114, 118, 101, 114, 115, 101, 116, 45, 99, 111, 111, 107, 105, 101,
+ 115, 116, 114, 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111, 114,
+ 116, 45, 115, 101, 99, 117, 114, 105, 116, 121, 116, 114, 97, 110, 115,
+ 102, 101, 114, 45, 101, 110, 99, 111, 100, 105, 110, 103, 118, 97, 114,
+ 121, 118, 105, 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116,
+ 105, 99, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100,
+ 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44,
+ 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105,
+ 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97,
+ 116, 101, 44, 103, 122, 105, 112};
static void static_ref(void* unused) {}
static void static_unref(void* unused) {}
@@ -215,6 +220,10 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
+ {&grpc_static_metadata_vtable, &static_sub_refcnt},
+ {&grpc_static_metadata_vtable, &static_sub_refcnt},
+ {&grpc_static_metadata_vtable, &static_sub_refcnt},
+ {&grpc_static_metadata_vtable, &static_sub_refcnt},
};
const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
@@ -240,85 +249,89 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}},
{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}},
{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}},
- {&grpc_static_metadata_refcounts[22], {{g_bytes + 290, 12}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}},
- {&grpc_static_metadata_refcounts[24], {{g_bytes + 302, 19}}},
- {&grpc_static_metadata_refcounts[25], {{g_bytes + 321, 12}}},
- {&grpc_static_metadata_refcounts[26], {{g_bytes + 333, 30}}},
- {&grpc_static_metadata_refcounts[27], {{g_bytes + 363, 31}}},
- {&grpc_static_metadata_refcounts[28], {{g_bytes + 394, 36}}},
- {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 7}}},
- {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}},
- {&grpc_static_metadata_refcounts[31], {{g_bytes + 441, 11}}},
- {&grpc_static_metadata_refcounts[32], {{g_bytes + 452, 1}}},
- {&grpc_static_metadata_refcounts[33], {{g_bytes + 453, 1}}},
- {&grpc_static_metadata_refcounts[34], {{g_bytes + 454, 1}}},
- {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 463, 8}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 471, 16}}},
- {&grpc_static_metadata_refcounts[38], {{g_bytes + 487, 4}}},
- {&grpc_static_metadata_refcounts[39], {{g_bytes + 491, 3}}},
- {&grpc_static_metadata_refcounts[40], {{g_bytes + 494, 3}}},
- {&grpc_static_metadata_refcounts[41], {{g_bytes + 497, 4}}},
- {&grpc_static_metadata_refcounts[42], {{g_bytes + 501, 5}}},
- {&grpc_static_metadata_refcounts[43], {{g_bytes + 506, 4}}},
- {&grpc_static_metadata_refcounts[44], {{g_bytes + 510, 3}}},
- {&grpc_static_metadata_refcounts[45], {{g_bytes + 513, 3}}},
- {&grpc_static_metadata_refcounts[46], {{g_bytes + 516, 1}}},
- {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 11}}},
- {&grpc_static_metadata_refcounts[48], {{g_bytes + 528, 3}}},
- {&grpc_static_metadata_refcounts[49], {{g_bytes + 531, 3}}},
- {&grpc_static_metadata_refcounts[50], {{g_bytes + 534, 3}}},
- {&grpc_static_metadata_refcounts[51], {{g_bytes + 537, 3}}},
- {&grpc_static_metadata_refcounts[52], {{g_bytes + 540, 3}}},
- {&grpc_static_metadata_refcounts[53], {{g_bytes + 543, 14}}},
- {&grpc_static_metadata_refcounts[54], {{g_bytes + 557, 13}}},
- {&grpc_static_metadata_refcounts[55], {{g_bytes + 570, 15}}},
- {&grpc_static_metadata_refcounts[56], {{g_bytes + 585, 13}}},
- {&grpc_static_metadata_refcounts[57], {{g_bytes + 598, 6}}},
- {&grpc_static_metadata_refcounts[58], {{g_bytes + 604, 27}}},
- {&grpc_static_metadata_refcounts[59], {{g_bytes + 631, 3}}},
- {&grpc_static_metadata_refcounts[60], {{g_bytes + 634, 5}}},
- {&grpc_static_metadata_refcounts[61], {{g_bytes + 639, 13}}},
- {&grpc_static_metadata_refcounts[62], {{g_bytes + 652, 13}}},
- {&grpc_static_metadata_refcounts[63], {{g_bytes + 665, 19}}},
- {&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 16}}},
- {&grpc_static_metadata_refcounts[65], {{g_bytes + 700, 14}}},
- {&grpc_static_metadata_refcounts[66], {{g_bytes + 714, 16}}},
- {&grpc_static_metadata_refcounts[67], {{g_bytes + 730, 13}}},
- {&grpc_static_metadata_refcounts[68], {{g_bytes + 743, 6}}},
- {&grpc_static_metadata_refcounts[69], {{g_bytes + 749, 4}}},
- {&grpc_static_metadata_refcounts[70], {{g_bytes + 753, 4}}},
- {&grpc_static_metadata_refcounts[71], {{g_bytes + 757, 6}}},
- {&grpc_static_metadata_refcounts[72], {{g_bytes + 763, 7}}},
- {&grpc_static_metadata_refcounts[73], {{g_bytes + 770, 4}}},
- {&grpc_static_metadata_refcounts[74], {{g_bytes + 774, 8}}},
- {&grpc_static_metadata_refcounts[75], {{g_bytes + 782, 17}}},
- {&grpc_static_metadata_refcounts[76], {{g_bytes + 799, 13}}},
- {&grpc_static_metadata_refcounts[77], {{g_bytes + 812, 8}}},
- {&grpc_static_metadata_refcounts[78], {{g_bytes + 820, 19}}},
- {&grpc_static_metadata_refcounts[79], {{g_bytes + 839, 13}}},
- {&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 11}}},
- {&grpc_static_metadata_refcounts[81], {{g_bytes + 863, 4}}},
- {&grpc_static_metadata_refcounts[82], {{g_bytes + 867, 8}}},
- {&grpc_static_metadata_refcounts[83], {{g_bytes + 875, 12}}},
- {&grpc_static_metadata_refcounts[84], {{g_bytes + 887, 18}}},
- {&grpc_static_metadata_refcounts[85], {{g_bytes + 905, 19}}},
- {&grpc_static_metadata_refcounts[86], {{g_bytes + 924, 5}}},
- {&grpc_static_metadata_refcounts[87], {{g_bytes + 929, 7}}},
- {&grpc_static_metadata_refcounts[88], {{g_bytes + 936, 7}}},
- {&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 11}}},
- {&grpc_static_metadata_refcounts[90], {{g_bytes + 954, 6}}},
- {&grpc_static_metadata_refcounts[91], {{g_bytes + 960, 10}}},
- {&grpc_static_metadata_refcounts[92], {{g_bytes + 970, 25}}},
- {&grpc_static_metadata_refcounts[93], {{g_bytes + 995, 17}}},
- {&grpc_static_metadata_refcounts[94], {{g_bytes + 1012, 4}}},
- {&grpc_static_metadata_refcounts[95], {{g_bytes + 1016, 3}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1019, 16}}},
- {&grpc_static_metadata_refcounts[97], {{g_bytes + 1035, 16}}},
- {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}},
- {&grpc_static_metadata_refcounts[99], {{g_bytes + 1064, 12}}},
- {&grpc_static_metadata_refcounts[100], {{g_bytes + 1076, 21}}},
+ {&grpc_static_metadata_refcounts[22], {{g_bytes + 290, 26}}},
+ {&grpc_static_metadata_refcounts[23], {{g_bytes + 316, 22}}},
+ {&grpc_static_metadata_refcounts[24], {{g_bytes + 338, 12}}},
+ {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}},
+ {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}},
+ {&grpc_static_metadata_refcounts[27], {{g_bytes + 352, 1}}},
+ {&grpc_static_metadata_refcounts[28], {{g_bytes + 353, 1}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}},
+ {&grpc_static_metadata_refcounts[30], {{g_bytes + 354, 19}}},
+ {&grpc_static_metadata_refcounts[31], {{g_bytes + 373, 12}}},
+ {&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}},
+ {&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}},
+ {&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}},
+ {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 493, 11}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}},
+ {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}},
+ {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}},
+ {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}},
+ {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}},
+ {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}},
+ {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}},
+ {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}},
+ {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}},
+ {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}},
+ {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}},
+ {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}},
+ {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}},
+ {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}},
+ {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}},
+ {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}},
+ {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}},
+ {&grpc_static_metadata_refcounts[56], {{g_bytes + 590, 3}}},
+ {&grpc_static_metadata_refcounts[57], {{g_bytes + 593, 14}}},
+ {&grpc_static_metadata_refcounts[58], {{g_bytes + 607, 13}}},
+ {&grpc_static_metadata_refcounts[59], {{g_bytes + 620, 15}}},
+ {&grpc_static_metadata_refcounts[60], {{g_bytes + 635, 13}}},
+ {&grpc_static_metadata_refcounts[61], {{g_bytes + 648, 6}}},
+ {&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 27}}},
+ {&grpc_static_metadata_refcounts[63], {{g_bytes + 681, 3}}},
+ {&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 5}}},
+ {&grpc_static_metadata_refcounts[65], {{g_bytes + 689, 13}}},
+ {&grpc_static_metadata_refcounts[66], {{g_bytes + 702, 13}}},
+ {&grpc_static_metadata_refcounts[67], {{g_bytes + 715, 19}}},
+ {&grpc_static_metadata_refcounts[68], {{g_bytes + 734, 16}}},
+ {&grpc_static_metadata_refcounts[69], {{g_bytes + 750, 14}}},
+ {&grpc_static_metadata_refcounts[70], {{g_bytes + 764, 16}}},
+ {&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 13}}},
+ {&grpc_static_metadata_refcounts[72], {{g_bytes + 793, 6}}},
+ {&grpc_static_metadata_refcounts[73], {{g_bytes + 799, 4}}},
+ {&grpc_static_metadata_refcounts[74], {{g_bytes + 803, 4}}},
+ {&grpc_static_metadata_refcounts[75], {{g_bytes + 807, 6}}},
+ {&grpc_static_metadata_refcounts[76], {{g_bytes + 813, 7}}},
+ {&grpc_static_metadata_refcounts[77], {{g_bytes + 820, 4}}},
+ {&grpc_static_metadata_refcounts[78], {{g_bytes + 824, 8}}},
+ {&grpc_static_metadata_refcounts[79], {{g_bytes + 832, 17}}},
+ {&grpc_static_metadata_refcounts[80], {{g_bytes + 849, 13}}},
+ {&grpc_static_metadata_refcounts[81], {{g_bytes + 862, 8}}},
+ {&grpc_static_metadata_refcounts[82], {{g_bytes + 870, 19}}},
+ {&grpc_static_metadata_refcounts[83], {{g_bytes + 889, 13}}},
+ {&grpc_static_metadata_refcounts[84], {{g_bytes + 902, 11}}},
+ {&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 4}}},
+ {&grpc_static_metadata_refcounts[86], {{g_bytes + 917, 8}}},
+ {&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 12}}},
+ {&grpc_static_metadata_refcounts[88], {{g_bytes + 937, 18}}},
+ {&grpc_static_metadata_refcounts[89], {{g_bytes + 955, 19}}},
+ {&grpc_static_metadata_refcounts[90], {{g_bytes + 974, 5}}},
+ {&grpc_static_metadata_refcounts[91], {{g_bytes + 979, 7}}},
+ {&grpc_static_metadata_refcounts[92], {{g_bytes + 986, 7}}},
+ {&grpc_static_metadata_refcounts[93], {{g_bytes + 993, 11}}},
+ {&grpc_static_metadata_refcounts[94], {{g_bytes + 1004, 6}}},
+ {&grpc_static_metadata_refcounts[95], {{g_bytes + 1010, 10}}},
+ {&grpc_static_metadata_refcounts[96], {{g_bytes + 1020, 25}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1045, 17}}},
+ {&grpc_static_metadata_refcounts[98], {{g_bytes + 1062, 4}}},
+ {&grpc_static_metadata_refcounts[99], {{g_bytes + 1066, 3}}},
+ {&grpc_static_metadata_refcounts[100], {{g_bytes + 1069, 16}}},
+ {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}},
+ {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}},
+ {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}},
};
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
@@ -328,50 +341,51 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
static const int8_t elems_r[] = {
- 13, 2, 1, 0, 15, 4, 0, 21, 0, 23, -3, 0, 0, 0, 10, 19, -4,
- 0, 0, 1, 10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -52, 0, -55, -36, -57, -58, -58, -58, 0, 40, 39, 38, 37, 36, 35,
- 34, 33, 32, 31, 30, 29, 28, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,
- 18, 17, 16, 15, 18, 17, 16, 15, 14, 13, 12, 11, 11, 0};
+ 16, 11, -1, 0, 15, 2, -78, 24, 0, 18, -5, 0, 0, 0, 17, 14, -8, 0,
+ 0, 27, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -64, 0, -44, -43, -70, 0, 34, 33, 33, 32, 31, 30, 29, 28, 27,
+ 27, 26, 25, 24, 23, 22, 21, 20, 20, 19, 19, 18, 17, 16, 15, 14, 13, 12,
+ 11, 14, 13, 12, 11, 10, 9, 9, 8, 7, 6, 5, 0};
static uint32_t elems_phash(uint32_t i) {
- i -= 46;
- uint32_t x = i % 99;
- uint32_t y = i / 99;
+ i -= 50;
+ uint32_t x = i % 103;
+ uint32_t y = i / 103;
uint32_t h = x;
if (y < GPR_ARRAY_SIZE(elems_r)) {
- uint32_t delta = static_cast<uint32_t>(elems_r[y]);
+ uint32_t delta = (uint32_t)elems_r[y];
h += delta;
}
return h;
}
static const uint16_t elem_keys[] = {
- 1039, 1040, 145, 146, 541, 1639, 1045, 250, 251, 252, 253, 254,
- 1646, 46, 47, 1437, 1942, 1651, 445, 446, 447, 739, 740, 741,
- 938, 939, 1538, 2043, 2144, 1451, 944, 5376, 5578, 1545, 5780, 5881,
- 1670, 5982, 1550, 6083, 6184, 6285, 6386, 6487, 6588, 6689, 6790, 6891,
- 6992, 7093, 7194, 7295, 7396, 5679, 7497, 7598, 7699, 7800, 7901, 8002,
- 8103, 8204, 8305, 8406, 8507, 8608, 8709, 8810, 1107, 1108, 1109, 1110,
- 8911, 9012, 9113, 9214, 9315, 9416, 9517, 9618, 1714, 9719, 0, 326,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 241, 242, 0, 0, 0, 0, 0, 0, 139, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0};
+ 1085, 1086, 565, 1709, 1089, 262, 263, 264, 265, 266, 1716,
+ 153, 154, 1719, 760, 761, 50, 51, 465, 466, 467, 980,
+ 981, 1604, 1499, 984, 773, 2129, 2234, 6014, 1611, 6434, 1738,
+ 1614, 6539, 6644, 1511, 6749, 6854, 6959, 7064, 7169, 7274, 7379,
+ 2024, 7484, 7589, 7694, 7799, 7904, 8009, 8114, 8219, 6224, 8324,
+ 8429, 6329, 8534, 8639, 8744, 8849, 8954, 9059, 9164, 9269, 9374,
+ 1151, 1152, 1153, 1154, 9479, 9584, 9689, 9794, 9899, 10004, 1782,
+ 10109, 10214, 10319, 10424, 10529, 0, 0, 0, 0, 0, 344,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 253, 254, 147, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0};
static const uint8_t elem_idxs[] = {
- 77, 79, 15, 16, 6, 25, 76, 19, 20, 21, 22, 23, 84, 17,
- 18, 43, 72, 83, 11, 12, 13, 0, 1, 2, 5, 4, 38, 50,
- 57, 7, 3, 24, 27, 37, 29, 30, 26, 31, 36, 32, 33, 34,
- 35, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 28, 51, 52,
- 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 78, 80,
- 81, 82, 66, 67, 68, 69, 70, 71, 73, 74, 85, 75, 255, 14,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 9, 10, 255, 255, 255, 255, 255, 255, 8};
+ 77, 79, 6, 25, 76, 19, 20, 21, 22, 23, 84, 15, 16, 83, 1,
+ 2, 17, 18, 11, 12, 13, 5, 4, 38, 43, 3, 0, 50, 57, 24,
+ 37, 29, 26, 36, 30, 31, 7, 32, 33, 34, 35, 39, 40, 41, 72,
+ 42, 44, 45, 46, 47, 48, 49, 51, 27, 52, 53, 28, 54, 55, 56,
+ 58, 59, 60, 61, 62, 63, 78, 80, 81, 82, 64, 65, 66, 67, 68,
+ 69, 85, 70, 71, 73, 74, 75, 255, 255, 255, 255, 255, 14, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 9, 10, 8};
grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
if (a == -1 || b == -1) return GRPC_MDNULL;
- uint32_t k = static_cast<uint32_t>(a * 101 + b);
+ uint32_t k = (uint32_t)(a * 105 + b);
uint32_t h = elems_phash(k);
return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
elem_idxs[h] != 255
@@ -382,177 +396,177 @@ grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
- {&grpc_static_metadata_refcounts[32], {{g_bytes + 452, 1}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 1}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
- {&grpc_static_metadata_refcounts[33], {{g_bytes + 453, 1}}}},
+ {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
- {&grpc_static_metadata_refcounts[34], {{g_bytes + 454, 1}}}},
+ {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 7}}}},
+ {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}},
{{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 463, 8}}}},
+ {&grpc_static_metadata_refcounts[40], {{g_bytes + 513, 8}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 471, 16}}}},
+ {&grpc_static_metadata_refcounts[41], {{g_bytes + 521, 16}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[38], {{g_bytes + 487, 4}}}},
+ {&grpc_static_metadata_refcounts[42], {{g_bytes + 537, 4}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[39], {{g_bytes + 491, 3}}}},
+ {&grpc_static_metadata_refcounts[43], {{g_bytes + 541, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[40], {{g_bytes + 494, 3}}}},
+ {&grpc_static_metadata_refcounts[44], {{g_bytes + 544, 3}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[41], {{g_bytes + 497, 4}}}},
+ {&grpc_static_metadata_refcounts[45], {{g_bytes + 547, 4}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[42], {{g_bytes + 501, 5}}}},
+ {&grpc_static_metadata_refcounts[46], {{g_bytes + 551, 5}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[43], {{g_bytes + 506, 4}}}},
+ {&grpc_static_metadata_refcounts[47], {{g_bytes + 556, 4}}}},
{{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[44], {{g_bytes + 510, 3}}}},
+ {&grpc_static_metadata_refcounts[48], {{g_bytes + 560, 3}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[45], {{g_bytes + 513, 3}}}},
+ {&grpc_static_metadata_refcounts[49], {{g_bytes + 563, 3}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
- {&grpc_static_metadata_refcounts[46], {{g_bytes + 516, 1}}}},
+ {&grpc_static_metadata_refcounts[50], {{g_bytes + 566, 1}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
- {&grpc_static_metadata_refcounts[47], {{g_bytes + 517, 11}}}},
+ {&grpc_static_metadata_refcounts[51], {{g_bytes + 567, 11}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[48], {{g_bytes + 528, 3}}}},
+ {&grpc_static_metadata_refcounts[52], {{g_bytes + 578, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[49], {{g_bytes + 531, 3}}}},
+ {&grpc_static_metadata_refcounts[53], {{g_bytes + 581, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[50], {{g_bytes + 534, 3}}}},
+ {&grpc_static_metadata_refcounts[54], {{g_bytes + 584, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[51], {{g_bytes + 537, 3}}}},
+ {&grpc_static_metadata_refcounts[55], {{g_bytes + 587, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[52], {{g_bytes + 540, 3}}}},
- {{&grpc_static_metadata_refcounts[53], {{g_bytes + 543, 14}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[56], {{g_bytes + 590, 3}}}},
+ {{&grpc_static_metadata_refcounts[57], {{g_bytes + 593, 14}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[54], {{g_bytes + 557, 13}}}},
- {{&grpc_static_metadata_refcounts[55], {{g_bytes + 570, 15}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[56], {{g_bytes + 585, 13}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[57], {{g_bytes + 598, 6}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[58], {{g_bytes + 604, 27}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[59], {{g_bytes + 631, 3}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[60], {{g_bytes + 634, 5}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[61], {{g_bytes + 639, 13}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[62], {{g_bytes + 652, 13}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[63], {{g_bytes + 665, 19}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[58], {{g_bytes + 607, 13}}}},
+ {{&grpc_static_metadata_refcounts[59], {{g_bytes + 620, 15}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[60], {{g_bytes + 635, 13}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[61], {{g_bytes + 648, 6}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[62], {{g_bytes + 654, 27}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[63], {{g_bytes + 681, 3}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 5}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[65], {{g_bytes + 689, 13}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[66], {{g_bytes + 702, 13}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[67], {{g_bytes + 715, 19}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
- {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
- {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[64], {{g_bytes + 684, 16}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[65], {{g_bytes + 700, 14}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[66], {{g_bytes + 714, 16}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[67], {{g_bytes + 730, 13}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[68], {{g_bytes + 734, 16}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[69], {{g_bytes + 750, 14}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[70], {{g_bytes + 764, 16}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 13}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[68], {{g_bytes + 743, 6}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[69], {{g_bytes + 749, 4}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[70], {{g_bytes + 753, 4}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[71], {{g_bytes + 757, 6}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[72], {{g_bytes + 763, 7}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[73], {{g_bytes + 770, 4}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[72], {{g_bytes + 793, 6}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[73], {{g_bytes + 799, 4}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[74], {{g_bytes + 803, 4}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[75], {{g_bytes + 807, 6}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[76], {{g_bytes + 813, 7}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[77], {{g_bytes + 820, 4}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[74], {{g_bytes + 774, 8}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[75], {{g_bytes + 782, 17}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[76], {{g_bytes + 799, 13}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[77], {{g_bytes + 812, 8}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[78], {{g_bytes + 820, 19}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[79], {{g_bytes + 839, 13}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[78], {{g_bytes + 824, 8}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[79], {{g_bytes + 832, 17}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[80], {{g_bytes + 849, 13}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[81], {{g_bytes + 862, 8}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[82], {{g_bytes + 870, 19}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[83], {{g_bytes + 889, 13}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[80], {{g_bytes + 852, 11}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[81], {{g_bytes + 863, 4}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[82], {{g_bytes + 867, 8}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[83], {{g_bytes + 875, 12}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[84], {{g_bytes + 887, 18}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[85], {{g_bytes + 905, 19}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[86], {{g_bytes + 924, 5}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[87], {{g_bytes + 929, 7}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[88], {{g_bytes + 936, 7}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[89], {{g_bytes + 943, 11}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[90], {{g_bytes + 954, 6}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[91], {{g_bytes + 960, 10}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[92], {{g_bytes + 970, 25}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[93], {{g_bytes + 995, 17}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[84], {{g_bytes + 902, 11}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[85], {{g_bytes + 913, 4}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[86], {{g_bytes + 917, 8}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[87], {{g_bytes + 925, 12}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[88], {{g_bytes + 937, 18}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[89], {{g_bytes + 955, 19}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[90], {{g_bytes + 974, 5}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[91], {{g_bytes + 979, 7}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[92], {{g_bytes + 986, 7}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[93], {{g_bytes + 993, 11}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1004, 6}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1010, 10}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[96], {{g_bytes + 1020, 25}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[97], {{g_bytes + 1045, 17}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1012, 4}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1016, 3}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
- {{&grpc_static_metadata_refcounts[96], {{g_bytes + 1019, 16}}},
- {&grpc_static_metadata_refcounts[23], {{g_bytes + 302, 0}}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[98], {{g_bytes + 1062, 4}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[99], {{g_bytes + 1066, 3}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
+ {{&grpc_static_metadata_refcounts[100], {{g_bytes + 1069, 16}}},
+ {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[29], {{g_bytes + 430, 7}}}},
+ {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[97], {{g_bytes + 1035, 16}}}},
+ {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}},
+ {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[99], {{g_bytes + 1064, 12}}}},
+ {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[100], {{g_bytes + 1076, 21}}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[35], {{g_bytes + 455, 8}}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 505, 8}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[30], {{g_bytes + 437, 4}}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[98], {{g_bytes + 1051, 13}}}},
+ {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}},
};
bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = {
true, // :path
@@ -577,6 +591,8 @@ bool grpc_static_callout_is_default[GRPC_BATCH_CALLOUTS_COUNT] = {
true, // user-agent
true, // host
true, // lb-token
+ true, // grpc-previous-rpc-attempts
+ true, // grpc-retry-pushback-ms
};
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78,
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index 8ce9b21bc1..b3a10f5873 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -27,9 +27,11 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H
#define GRPC_CORE_LIB_TRANSPORT_STATIC_METADATA_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/metadata.h"
-#define GRPC_STATIC_MDSTR_COUNT 101
+#define GRPC_STATIC_MDSTR_COUNT 105
extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* ":path" */
#define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -76,168 +78,176 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
#define GRPC_MDSTR_HOST (grpc_static_slice_table[20])
/* "lb-token" */
#define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[21])
+/* "grpc-previous-rpc-attempts" */
+#define GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS (grpc_static_slice_table[22])
+/* "grpc-retry-pushback-ms" */
+#define GRPC_MDSTR_GRPC_RETRY_PUSHBACK_MS (grpc_static_slice_table[23])
/* "grpc-timeout" */
-#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[22])
+#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[24])
+/* "1" */
+#define GRPC_MDSTR_1 (grpc_static_slice_table[25])
+/* "2" */
+#define GRPC_MDSTR_2 (grpc_static_slice_table[26])
+/* "3" */
+#define GRPC_MDSTR_3 (grpc_static_slice_table[27])
+/* "4" */
+#define GRPC_MDSTR_4 (grpc_static_slice_table[28])
/* "" */
-#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[23])
+#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[29])
/* "grpc.wait_for_ready" */
-#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[24])
+#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[30])
/* "grpc.timeout" */
-#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[25])
+#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[31])
/* "grpc.max_request_message_bytes" */
#define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \
- (grpc_static_slice_table[26])
+ (grpc_static_slice_table[32])
/* "grpc.max_response_message_bytes" */
#define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \
- (grpc_static_slice_table[27])
+ (grpc_static_slice_table[33])
/* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
- (grpc_static_slice_table[28])
+ (grpc_static_slice_table[34])
/* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[29])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35])
/* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[30])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[36])
/* "stream/gzip" */
-#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[31])
+#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[37])
/* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[32])
-/* "1" */
-#define GRPC_MDSTR_1 (grpc_static_slice_table[33])
-/* "2" */
-#define GRPC_MDSTR_2 (grpc_static_slice_table[34])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[38])
/* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[35])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[39])
/* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[36])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[40])
/* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[37])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[41])
/* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[38])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[42])
/* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[39])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[43])
/* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[40])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[44])
/* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[41])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[45])
/* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[42])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[46])
/* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[43])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[47])
/* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[44])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[48])
/* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[45])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[49])
/* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[46])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[50])
/* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[47])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[51])
/* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[48])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[52])
/* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[49])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[53])
/* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[50])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[54])
/* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[51])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[55])
/* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[52])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[56])
/* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[57])
/* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[58])
/* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[59])
/* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[60])
/* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[61])
/* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[62])
/* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[59])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[63])
/* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[64])
/* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[65])
/* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[66])
/* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[67])
/* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[68])
/* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[69])
/* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[70])
/* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[71])
/* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[72])
/* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[69])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[73])
/* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[74])
/* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[75])
/* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[76])
/* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[73])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[77])
/* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[78])
/* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[79])
/* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[80])
/* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[81])
/* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[82])
/* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[83])
/* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[80])
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[84])
/* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[81])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[85])
/* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[82])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[86])
/* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[83])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[87])
/* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[84])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[88])
/* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[85])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[89])
/* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[86])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[90])
/* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[87])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[91])
/* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[88])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[92])
/* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[89])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[93])
/* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[90])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[94])
/* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[91])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[95])
/* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[92])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[96])
/* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[93])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[97])
/* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[94])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[98])
/* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[95])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[99])
/* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[96])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[100])
/* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[97])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[101])
/* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[98])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[102])
/* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[99])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[103])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (grpc_static_slice_table[100])
+ (grpc_static_slice_table[104])
extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
extern grpc_slice_refcount
@@ -535,6 +545,8 @@ typedef enum {
GRPC_BATCH_USER_AGENT,
GRPC_BATCH_HOST,
GRPC_BATCH_LB_TOKEN,
+ GRPC_BATCH_GRPC_PREVIOUS_RPC_ATTEMPTS,
+ GRPC_BATCH_GRPC_RETRY_PUSHBACK_MS,
GRPC_BATCH_CALLOUTS_COUNT
} grpc_metadata_batch_callouts_index;
@@ -563,6 +575,8 @@ typedef union {
struct grpc_linked_mdelem* user_agent;
struct grpc_linked_mdelem* host;
struct grpc_linked_mdelem* lb_token;
+ struct grpc_linked_mdelem* grpc_previous_rpc_attempts;
+ struct grpc_linked_mdelem* grpc_retry_pushback_ms;
} named;
} grpc_metadata_batch_callouts;
diff --git a/src/core/lib/transport/status_conversion.cc b/src/core/lib/transport/status_conversion.cc
index 46cba4292b..e58bef5ba9 100644
--- a/src/core/lib/transport/status_conversion.cc
+++ b/src/core/lib/transport/status_conversion.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/status_conversion.h"
grpc_http2_error_code grpc_status_to_http2_error(grpc_status_code status) {
diff --git a/src/core/lib/transport/status_conversion.h b/src/core/lib/transport/status_conversion.h
index 107eb92a53..9f14e9bee0 100644
--- a/src/core/lib/transport/status_conversion.h
+++ b/src/core/lib/transport/status_conversion.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_STATUS_CONVERSION_H
#define GRPC_CORE_LIB_TRANSPORT_STATUS_CONVERSION_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/transport/http2_errors.h"
diff --git a/src/core/lib/transport/status_metadata.cc b/src/core/lib/transport/status_metadata.cc
new file mode 100644
index 0000000000..f896053e4d
--- /dev/null
+++ b/src/core/lib/transport/status_metadata.cc
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/transport/status_metadata.h"
+
+#include "src/core/lib/slice/slice_string_helpers.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+/* we offset status by a small amount when storing it into transport metadata
+ as metadata cannot store a 0 value (which is used as OK for grpc_status_codes
+ */
+#define STATUS_OFFSET 1
+
+static void destroy_status(void* ignored) {}
+
+grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md) {
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_0)) {
+ return GRPC_STATUS_OK;
+ }
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_1)) {
+ return GRPC_STATUS_CANCELLED;
+ }
+ if (grpc_mdelem_eq(md, GRPC_MDELEM_GRPC_STATUS_2)) {
+ return GRPC_STATUS_UNKNOWN;
+ }
+ void* user_data = grpc_mdelem_get_user_data(md, destroy_status);
+ if (user_data != nullptr) {
+ return static_cast<grpc_status_code>((intptr_t)user_data - STATUS_OFFSET);
+ }
+ uint32_t status;
+ if (!grpc_parse_slice_to_uint32(GRPC_MDVALUE(md), &status)) {
+ status = GRPC_STATUS_UNKNOWN; /* could not parse status code */
+ }
+ grpc_mdelem_set_user_data(
+ md, destroy_status, (void*)static_cast<intptr_t>(status + STATUS_OFFSET));
+ return static_cast<grpc_status_code>(status);
+}
diff --git a/src/core/lib/transport/status_metadata.h b/src/core/lib/transport/status_metadata.h
new file mode 100644
index 0000000000..aed9c7ac20
--- /dev/null
+++ b/src/core/lib/transport/status_metadata.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H
+#define GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpc/status.h>
+
+#include "src/core/lib/transport/metadata.h"
+
+grpc_status_code grpc_get_status_code_from_metadata(grpc_mdelem md);
+
+#endif /* GRPC_CORE_LIB_TRANSPORT_STATUS_METADATA_H */
diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc
index 6800255be2..c37249920b 100644
--- a/src/core/lib/transport/timeout_encoding.cc
+++ b/src/core/lib/transport/timeout_encoding.cc
@@ -16,12 +16,13 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/timeout_encoding.h"
#include <stdio.h>
#include <string.h>
-#include <grpc/support/port_platform.h>
#include "src/core/lib/gpr/string.h"
static int64_t round_up(int64_t x, int64_t divisor) {
diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h
index 4e9268262e..8505e32ff0 100644
--- a/src/core/lib/transport/timeout_encoding.h
+++ b/src/core/lib/transport/timeout_encoding.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H
#define GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice.h>
#include <grpc/support/time.h>
diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc
index d71d4fdd76..c90d16fc32 100644
--- a/src/core/lib/transport/transport.cc
+++ b/src/core/lib/transport/transport.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/transport.h"
#include <string.h>
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index b392c696cd..37e50344c4 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H
#define GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H
+#include <grpc/support/port_platform.h>
+
#include <stddef.h>
#include "src/core/lib/channel/context.h"
@@ -96,6 +98,19 @@ void grpc_transport_move_one_way_stats(grpc_transport_one_way_stats* from,
void grpc_transport_move_stats(grpc_transport_stream_stats* from,
grpc_transport_stream_stats* to);
+// This struct (which is present in both grpc_transport_stream_op_batch
+// and grpc_transport_op_batch) is a convenience to allow filters or
+// transports to schedule a closure related to a particular batch without
+// having to allocate memory. The general pattern is to initialize the
+// closure with the callback arg set to the batch and extra_arg set to
+// whatever state is associated with the handler (e.g., the call element
+// or the transport stream object).
+//
+// Note that this can only be used by the current handler of a given
+// batch on the way down the stack (i.e., whichever filter or transport is
+// currently handling the batch). Once a filter or transport passes control
+// of the batch to the next handler, it cannot depend on the contents of
+// this struct anymore, because the next handler may reuse it.
typedef struct {
void* extra_arg;
grpc_closure closure;
@@ -155,6 +170,11 @@ struct grpc_transport_stream_op_batch_payload {
uint32_t send_initial_metadata_flags;
// If non-NULL, will be set by the transport to the peer string
// (a char*, which the caller takes ownership of).
+ // Note: This pointer may be used by the transport after the
+ // send_initial_metadata op is completed. It must remain valid
+ // until the call is destroyed.
+ // Note: When a transport sets this, it must free the previous
+ // value, if any.
gpr_atm* peer_string;
} send_initial_metadata;
@@ -173,6 +193,9 @@ struct grpc_transport_stream_op_batch_payload {
struct {
grpc_metadata_batch* recv_initial_metadata;
+ // Flags are used only on the server side. If non-null, will be set to
+ // a bitfield of the GRPC_INITIAL_METADATA_xxx macros (e.g., to
+ // indicate if the call is idempotent).
uint32_t* recv_flags;
/** Should be enqueued when initial metadata is ready to be processed. */
grpc_closure* recv_initial_metadata_ready;
@@ -182,6 +205,11 @@ struct grpc_transport_stream_op_batch_payload {
bool* trailing_metadata_available;
// If non-NULL, will be set by the transport to the peer string
// (a char*, which the caller takes ownership of).
+ // Note: This pointer may be used by the transport after the
+ // recv_initial_metadata op is completed. It must remain valid
+ // until the call is destroyed.
+ // Note: When a transport sets this, it must free the previous
+ // value, if any.
gpr_atm* peer_string;
} recv_initial_metadata;
@@ -190,6 +218,7 @@ struct grpc_transport_stream_op_batch_payload {
// containing a received message.
// The caller is responsible for calling grpc_byte_stream_destroy()
// on this byte stream.
+ // Will be NULL if trailing metadata is received instead of a message.
grpc_byte_stream** recv_message;
/** Should be enqueued when one message is ready to be processed. */
grpc_closure* recv_message_ready;
diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h
index 50b8a5f9b7..ba5e05df0a 100644
--- a/src/core/lib/transport/transport_impl.h
+++ b/src/core/lib/transport/transport_impl.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H
#define GRPC_CORE_LIB_TRANSPORT_TRANSPORT_IMPL_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/lib/transport/transport.h"
typedef struct grpc_transport_vtable {
diff --git a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
index fe5eb28f05..49b9c7d4fe 100644
--- a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
void grpc_http_filters_init(void);
diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc
index fdf9acc09c..ccf5f79a8e 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_plugin_registry.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
void grpc_http_filters_init(void);
diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
index d73f946241..b08c5ce3ae 100644
--- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
void grpc_http_filters_init(void);
diff --git a/src/core/tsi/alts_transport_security.cc b/src/core/tsi/alts_transport_security.cc
index 1654d893d0..b45b4e0736 100644
--- a/src/core/tsi/alts_transport_security.cc
+++ b/src/core/tsi/alts_transport_security.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/alts_transport_security.h"
#include <string.h>
diff --git a/src/core/tsi/alts_transport_security.h b/src/core/tsi/alts_transport_security.h
index 5d693d04af..3ca064992b 100644
--- a/src/core/tsi/alts_transport_security.h
+++ b/src/core/tsi/alts_transport_security.h
@@ -19,9 +19,12 @@
#ifndef GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H
#define GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
typedef struct alts_shared_resource {
gpr_thd_id thread_id;
diff --git a/src/core/tsi/fake_transport_security.cc b/src/core/tsi/fake_transport_security.cc
index b5b7203d20..ad08b50ede 100644
--- a/src/core/tsi/fake_transport_security.cc
+++ b/src/core/tsi/fake_transport_security.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/fake_transport_security.h"
#include <stdlib.h>
@@ -23,7 +25,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/slice/slice_internal.h"
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
index 3848e7c6bf..37791827e1 100644
--- a/src/core/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
#define GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/transport_security_interface.h"
/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for FAKE certs. */
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index 643b5a5c79..971170b7c5 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -16,10 +16,10 @@
*
*/
-#include "src/core/tsi/ssl_transport_security.h"
-
#include <grpc/support/port_platform.h>
+#include "src/core/tsi/ssl_transport_security.h"
+
#include <limits.h>
#include <string.h>
@@ -36,7 +36,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
extern "C" {
#include <openssl/bio.h>
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index bf211e110a..edebadc1be 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
#define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/transport_security_interface.h"
/* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */
diff --git a/src/core/tsi/ssl_types.h b/src/core/tsi/ssl_types.h
index 3788643355..b15d02be39 100644
--- a/src/core/tsi/ssl_types.h
+++ b/src/core/tsi/ssl_types.h
@@ -27,6 +27,8 @@
* function
*/
+#include <grpc/support/port_platform.h>
+
#include <openssl/ssl.h>
#ifdef OPENSSL_IS_BORINGSSL
diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc
index 0c8e3e9dcc..129533f779 100644
--- a/src/core/tsi/transport_security.cc
+++ b/src/core/tsi/transport_security.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/transport_security.h"
#include <grpc/support/alloc.h>
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index ed662d48af..b1ec82d3f7 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_H
#define GRPC_CORE_TSI_TRANSPORT_SECURITY_H
+#include <grpc/support/port_platform.h>
+
#include <stdbool.h>
#include "src/core/lib/debug/trace.h"
diff --git a/src/core/tsi/transport_security_adapter.cc b/src/core/tsi/transport_security_adapter.cc
index 5f094b3201..25608f065a 100644
--- a/src/core/tsi/transport_security_adapter.cc
+++ b/src/core/tsi/transport_security_adapter.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/transport_security_adapter.h"
#include <string.h>
diff --git a/src/core/tsi/transport_security_adapter.h b/src/core/tsi/transport_security_adapter.h
index 9818fceb86..f83ecc53e5 100644
--- a/src/core/tsi/transport_security_adapter.h
+++ b/src/core/tsi/transport_security_adapter.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H
#define GRPC_CORE_TSI_TRANSPORT_SECURITY_ADAPTER_H
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/transport_security_interface.h"
/* Create a tsi handshaker that takes an implementation of old interface and
diff --git a/src/core/tsi/transport_security_grpc.cc b/src/core/tsi/transport_security_grpc.cc
index 76f7ae782f..c73a6e303e 100644
--- a/src/core/tsi/transport_security_grpc.cc
+++ b/src/core/tsi/transport_security_grpc.cc
@@ -16,6 +16,8 @@
*
*/
+#include <grpc/support/port_platform.h>
+
#include "src/core/tsi/transport_security_grpc.h"
/* This method creates a tsi_zero_copy_grpc_protector object. */
diff --git a/src/core/tsi/transport_security_grpc.h b/src/core/tsi/transport_security_grpc.h
index 0156ff1c68..d3bb04d07f 100644
--- a/src/core/tsi/transport_security_grpc.h
+++ b/src/core/tsi/transport_security_grpc.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_GRPC_H
#define GRPC_CORE_TSI_TRANSPORT_SECURITY_GRPC_H
+#include <grpc/support/port_platform.h>
+
#include <grpc/slice_buffer.h>
#include "src/core/tsi/transport_security.h"
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index e925598463..8c10866934 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -19,6 +19,8 @@
#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
#define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
+#include <grpc/support/port_platform.h>
+
#include <stdint.h>
#include <stdlib.h>
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index e4ed3490fd..cba5984f4b 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -16,33 +16,33 @@
*
*/
-#include <grpc++/channel.h>
+#include <grpcpp/channel.h>
#include <chrono>
#include <condition_variable>
#include <memory>
#include <mutex>
-#include <grpc++/client_context.h>
-#include <grpc++/completion_queue.h>
-#include <grpc++/impl/call.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/impl/rpc_method.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/support/channel_arguments.h>
-#include <grpc++/support/config.h>
-#include <grpc++/support/status.h>
-#include <grpc++/support/time.h>
#include <grpc/grpc.h>
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include <grpcpp/client_context.h>
+#include <grpcpp/completion_queue.h>
+#include <grpcpp/impl/call.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/impl/rpc_method.h>
+#include <grpcpp/security/credentials.h>
+#include <grpcpp/support/channel_arguments.h>
+#include <grpcpp/support/config.h>
+#include <grpcpp/support/status.h>
+#include <grpcpp/support/time.h>
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/profiling/timers.h"
namespace grpc {
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 5c90838440..07a04e4268 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/client_context.h>
+#include <grpcpp/client_context.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
@@ -24,10 +24,10 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/server_context.h>
-#include <grpc++/support/time.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/security/credentials.h>
+#include <grpcpp/server_context.h>
+#include <grpcpp/support/time.h>
namespace grpc {
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index 93233153d0..67a46ce0e1 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -18,10 +18,10 @@
#include <memory>
-#include <grpc++/channel.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/support/channel_arguments.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/create_channel.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/support/channel_arguments.h>
#include "src/cpp/client/create_channel_internal.h"
diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc
index 89e2f8dfdf..aa96edfcff 100644
--- a/src/cpp/client/create_channel_internal.cc
+++ b/src/cpp/client/create_channel_internal.cc
@@ -18,7 +18,7 @@
#include <memory>
-#include <grpc++/channel.h>
+#include <grpcpp/channel.h>
struct grpc_channel;
diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h
index 2cb316343a..86e8167277 100644
--- a/src/cpp/client/create_channel_internal.h
+++ b/src/cpp/client/create_channel_internal.h
@@ -21,7 +21,7 @@
#include <memory>
-#include <grpc++/support/config.h>
+#include <grpcpp/support/config.h>
struct grpc_channel;
diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc
index cea002f2a3..f9285c9b28 100644
--- a/src/cpp/client/create_channel_posix.cc
+++ b/src/cpp/client/create_channel_posix.cc
@@ -16,11 +16,11 @@
*
*/
-#include <grpc++/channel.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/impl/grpc_library.h>
#include <grpc/grpc.h>
#include <grpc/grpc_posix.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/create_channel.h>
+#include <grpcpp/impl/grpc_library.h>
#include "src/cpp/client/create_channel_internal.h"
diff --git a/src/cpp/client/credentials_cc.cc b/src/cpp/client/credentials_cc.cc
index 8d692429e1..2a0f06f424 100644
--- a/src/cpp/client/credentials_cc.cc
+++ b/src/cpp/client/credentials_cc.cc
@@ -16,8 +16,8 @@
*
*/
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/security/credentials.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/security/credentials.h>
namespace grpc {
diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc
index a874a6e68f..5c65ad05ea 100644
--- a/src/cpp/client/cronet_credentials.cc
+++ b/src/cpp/client/cronet_credentials.cc
@@ -16,11 +16,11 @@
*
*/
-#include <grpc++/security/credentials.h>
+#include <grpcpp/security/credentials.h>
-#include <grpc++/channel.h>
-#include <grpc++/support/channel_arguments.h>
#include <grpc/grpc_cronet.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/support/channel_arguments.h>
#include "src/cpp/client/create_channel_internal.h"
namespace grpc {
diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc
index 4b4b8dd427..67ef46bebe 100644
--- a/src/cpp/client/generic_stub.cc
+++ b/src/cpp/client/generic_stub.cc
@@ -16,9 +16,9 @@
*
*/
-#include <grpc++/generic/generic_stub.h>
+#include <grpcpp/generic/generic_stub.h>
-#include <grpc++/impl/rpc_method.h>
+#include <grpcpp/impl/rpc_method.h>
namespace grpc {
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index 21128447db..04dc5c0bcc 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -16,13 +16,13 @@
*
*/
-#include <grpc++/security/credentials.h>
+#include <grpcpp/security/credentials.h>
-#include <grpc++/channel.h>
-#include <grpc++/support/channel_arguments.h>
-#include <grpc++/support/config.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/support/channel_arguments.h>
+#include <grpcpp/support/config.h>
#include "src/cpp/client/create_channel_internal.h"
namespace grpc {
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 4fb128d98b..539db84db3 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -17,11 +17,11 @@
*/
#include "src/cpp/client/secure_credentials.h"
-#include <grpc++/channel.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/support/channel_arguments.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/support/channel_arguments.h>
#include "src/cpp/client/create_channel_internal.h"
#include "src/cpp/common/secure_auth_context.h"
diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h
index ed9afb37b0..85cb54227c 100644
--- a/src/cpp/client/secure_credentials.h
+++ b/src/cpp/client/secure_credentials.h
@@ -21,8 +21,8 @@
#include <grpc/grpc_security.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/support/config.h>
+#include <grpcpp/security/credentials.h>
+#include <grpcpp/support/config.h>
#include "src/cpp/server/thread_pool_interface.h"
diff --git a/src/cpp/codegen/codegen_init.cc b/src/cpp/codegen/codegen_init.cc
index 2da15560b5..684d7218b9 100644
--- a/src/cpp/codegen/codegen_init.cc
+++ b/src/cpp/codegen/codegen_init.cc
@@ -16,8 +16,8 @@
*
*/
-#include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc++/impl/codegen/grpc_library.h>
+#include <grpcpp/impl/codegen/core_codegen_interface.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
/// Null-initializes the global gRPC variables for the codegen library. These
/// stay null in the absence of of grpc++ library. In this case, no gRPC
diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc
index 0eecbb6261..15a373d8a5 100644
--- a/src/cpp/common/alarm.cc
+++ b/src/cpp/common/alarm.cc
@@ -15,15 +15,15 @@
*
*/
-#include <grpc++/alarm.h>
+#include <grpcpp/alarm.h>
#include <memory>
-#include <grpc++/completion_queue.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/support/time.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
+#include <grpcpp/completion_queue.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/support/time.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/timer.h"
#include "src/core/lib/surface/completion_queue.h"
diff --git a/src/cpp/common/auth_property_iterator.cc b/src/cpp/common/auth_property_iterator.cc
index 4f0948c204..fbb18e9915 100644
--- a/src/cpp/common/auth_property_iterator.cc
+++ b/src/cpp/common/auth_property_iterator.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/security/auth_context.h>
+#include <grpcpp/security/auth_context.h>
#include <grpc/grpc_security.h>
diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc
index b696774243..50ee9d871f 100644
--- a/src/cpp/common/channel_arguments.cc
+++ b/src/cpp/common/channel_arguments.cc
@@ -15,14 +15,14 @@
* limitations under the License.
*
*/
-#include <grpc++/support/channel_arguments.h>
+#include <grpcpp/support/channel_arguments.h>
#include <sstream>
-#include <grpc++/grpc++.h>
-#include <grpc++/resource_quota.h>
#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/log.h>
+#include <grpcpp/grpcpp.h>
+#include <grpcpp/resource_quota.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/socket_mutator.h"
diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc
index 874f31b639..422e7bb65e 100644
--- a/src/cpp/common/channel_filter.cc
+++ b/src/cpp/common/channel_filter.cc
@@ -21,7 +21,7 @@
#include "src/core/lib/channel/channel_stack.h"
#include "src/cpp/common/channel_filter.h"
-#include <grpc++/impl/codegen/slice.h>
+#include <grpcpp/impl/codegen/slice.h>
namespace grpc {
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index a1d22085bf..642372be78 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -19,9 +19,9 @@
#ifndef GRPCXX_CHANNEL_FILTER_H
#define GRPCXX_CHANNEL_FILTER_H
-#include <grpc++/impl/codegen/config.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
+#include <grpcpp/impl/codegen/config.h>
#include <functional>
#include <vector>
diff --git a/src/cpp/common/completion_queue_cc.cc b/src/cpp/common/completion_queue_cc.cc
index eb6dc8cc5f..6893201e2e 100644
--- a/src/cpp/common/completion_queue_cc.cc
+++ b/src/cpp/common/completion_queue_cc.cc
@@ -15,14 +15,14 @@
*
*/
-#include <grpc++/completion_queue.h>
+#include <grpcpp/completion_queue.h>
#include <memory>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/support/time.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/support/time.h>
namespace grpc {
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index 936d6996b2..aa9788da76 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -16,11 +16,10 @@
*
*/
-#include <grpc++/impl/codegen/core_codegen.h>
+#include <grpcpp/impl/codegen/core_codegen.h>
#include <stdlib.h>
-#include <grpc++/support/config.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
#include <grpc/grpc.h>
@@ -30,6 +29,7 @@
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/sync.h>
+#include <grpcpp/support/config.h>
#include "src/core/lib/profiling/timers.h"
diff --git a/src/cpp/common/insecure_create_auth_context.cc b/src/cpp/common/insecure_create_auth_context.cc
index 28de47bd5d..4e5cbd0372 100644
--- a/src/cpp/common/insecure_create_auth_context.cc
+++ b/src/cpp/common/insecure_create_auth_context.cc
@@ -17,8 +17,8 @@
*/
#include <memory>
-#include <grpc++/security/auth_context.h>
#include <grpc/grpc.h>
+#include <grpcpp/security/auth_context.h>
namespace grpc {
diff --git a/src/cpp/common/resource_quota_cc.cc b/src/cpp/common/resource_quota_cc.cc
index 0e9be15eaf..daeb0ba171 100644
--- a/src/cpp/common/resource_quota_cc.cc
+++ b/src/cpp/common/resource_quota_cc.cc
@@ -16,8 +16,8 @@
*
*/
-#include <grpc++/resource_quota.h>
#include <grpc/grpc.h>
+#include <grpcpp/resource_quota.h>
namespace grpc {
diff --git a/src/cpp/common/rpc_method.cc b/src/cpp/common/rpc_method.cc
index d00339ac33..a47dd3e444 100644
--- a/src/cpp/common/rpc_method.cc
+++ b/src/cpp/common/rpc_method.cc
@@ -16,6 +16,6 @@
*
*/
-#include <grpc++/impl/rpc_method.h>
+#include <grpcpp/impl/rpc_method.h>
namespace grpc {} // namespace grpc
diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h
index 0aea642756..142617959c 100644
--- a/src/cpp/common/secure_auth_context.h
+++ b/src/cpp/common/secure_auth_context.h
@@ -19,7 +19,7 @@
#ifndef GRPC_INTERNAL_CPP_COMMON_SECURE_AUTH_CONTEXT_H
#define GRPC_INTERNAL_CPP_COMMON_SECURE_AUTH_CONTEXT_H
-#include <grpc++/security/auth_context.h>
+#include <grpcpp/security/auth_context.h>
struct grpc_auth_context;
diff --git a/src/cpp/common/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc
index f6cd584fb9..2fb8ea44fb 100644
--- a/src/cpp/common/secure_channel_arguments.cc
+++ b/src/cpp/common/secure_channel_arguments.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/support/channel_arguments.h>
+#include <grpcpp/support/channel_arguments.h>
#include <grpc/grpc_security.h>
#include "src/core/lib/channel/channel_args.h"
diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc
index 4b9e39ad3e..bc1387c8d7 100644
--- a/src/cpp/common/secure_create_auth_context.cc
+++ b/src/cpp/common/secure_create_auth_context.cc
@@ -17,9 +17,9 @@
*/
#include <memory>
-#include <grpc++/security/auth_context.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
+#include <grpcpp/security/auth_context.h>
#include "src/cpp/common/secure_auth_context.h"
namespace grpc {
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 8bc926048f..fb1723c816 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -19,8 +19,8 @@
/* This file is autogenerated from:
templates/src/core/surface/version.c.template */
-#include <grpc++/grpc++.h>
+#include <grpcpp/grpcpp.h>
namespace grpc {
-grpc::string Version() { return "1.10.0-dev"; }
+grpc::string Version() { return "1.11.0-dev"; }
} // namespace grpc
diff --git a/src/cpp/ext/proto_server_reflection.cc b/src/cpp/ext/proto_server_reflection.cc
index e6122115fe..f26f007c8e 100644
--- a/src/cpp/ext/proto_server_reflection.cc
+++ b/src/cpp/ext/proto_server_reflection.cc
@@ -19,7 +19,7 @@
#include <unordered_set>
#include <vector>
-#include <grpc++/grpc++.h>
+#include <grpcpp/grpcpp.h>
#include "src/cpp/ext/proto_server_reflection.h"
diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h
index ee2327ca67..bf40c3c180 100644
--- a/src/cpp/ext/proto_server_reflection.h
+++ b/src/cpp/ext/proto_server_reflection.h
@@ -22,7 +22,7 @@
#include <unordered_set>
#include <vector>
-#include <grpc++/grpc++.h>
+#include <grpcpp/grpcpp.h>
#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h"
namespace grpc {
diff --git a/src/cpp/ext/proto_server_reflection_plugin.cc b/src/cpp/ext/proto_server_reflection_plugin.cc
index c299661bf8..ee3ac3fee8 100644
--- a/src/cpp/ext/proto_server_reflection_plugin.cc
+++ b/src/cpp/ext/proto_server_reflection_plugin.cc
@@ -16,10 +16,10 @@
*
*/
-#include <grpc++/ext/proto_server_reflection_plugin.h>
-#include <grpc++/impl/server_builder_plugin.h>
-#include <grpc++/impl/server_initializer.h>
-#include <grpc++/server.h>
+#include <grpcpp/ext/proto_server_reflection_plugin.h>
+#include <grpcpp/impl/server_builder_plugin.h>
+#include <grpcpp/impl/server_initializer.h>
+#include <grpcpp/server.h>
#include "src/cpp/ext/proto_server_reflection.h"
diff --git a/src/cpp/server/async_generic_service.cc b/src/cpp/server/async_generic_service.cc
index 998f516d4f..3061376829 100644
--- a/src/cpp/server/async_generic_service.cc
+++ b/src/cpp/server/async_generic_service.cc
@@ -16,9 +16,9 @@
*
*/
-#include <grpc++/generic/async_generic_service.h>
+#include <grpcpp/generic/async_generic_service.h>
-#include <grpc++/server.h>
+#include <grpcpp/server.h>
namespace grpc {
diff --git a/src/cpp/server/channel_argument_option.cc b/src/cpp/server/channel_argument_option.cc
index dcad2531d5..4d6be9011c 100644
--- a/src/cpp/server/channel_argument_option.cc
+++ b/src/cpp/server/channel_argument_option.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/impl/channel_argument_option.h>
+#include <grpcpp/impl/channel_argument_option.h>
namespace grpc {
diff --git a/src/cpp/server/dynamic_thread_pool.h b/src/cpp/server/dynamic_thread_pool.h
index 9237c6e5ca..880a03d0f0 100644
--- a/src/cpp/server/dynamic_thread_pool.h
+++ b/src/cpp/server/dynamic_thread_pool.h
@@ -26,7 +26,7 @@
#include <queue>
#include <thread>
-#include <grpc++/support/config.h>
+#include <grpcpp/support/config.h>
#include "src/cpp/server/thread_pool_interface.h"
diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc
index 10dbd3c39a..0b45a8b714 100644
--- a/src/cpp/server/health/default_health_check_service.cc
+++ b/src/cpp/server/health/default_health_check_service.cc
@@ -19,10 +19,10 @@
#include <memory>
#include <mutex>
-#include <grpc++/impl/codegen/method_handler_impl.h>
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpcpp/impl/codegen/method_handler_impl.h>
#include "src/cpp/server/health/default_health_check_service.h"
#include "src/cpp/server/health/health.pb.h"
diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h
index 99d6680c50..a1ce5aa64e 100644
--- a/src/cpp/server/health/default_health_check_service.h
+++ b/src/cpp/server/health/default_health_check_service.h
@@ -21,9 +21,9 @@
#include <mutex>
-#include <grpc++/health_check_service_interface.h>
-#include <grpc++/impl/codegen/service_type.h>
-#include <grpc++/support/byte_buffer.h>
+#include <grpcpp/health_check_service_interface.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/support/byte_buffer.h>
namespace grpc {
diff --git a/src/cpp/server/health/health_check_service.cc b/src/cpp/server/health/health_check_service.cc
index a34b533bb2..a0fa2d62f5 100644
--- a/src/cpp/server/health/health_check_service.cc
+++ b/src/cpp/server/health/health_check_service.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/health_check_service_interface.h>
+#include <grpcpp/health_check_service_interface.h>
namespace grpc {
namespace {
diff --git a/src/cpp/server/health/health_check_service_server_builder_option.cc b/src/cpp/server/health/health_check_service_server_builder_option.cc
index a722eea4b5..7148265d27 100644
--- a/src/cpp/server/health/health_check_service_server_builder_option.cc
+++ b/src/cpp/server/health/health_check_service_server_builder_option.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/ext/health_check_service_server_builder_option.h>
+#include <grpcpp/ext/health_check_service_server_builder_option.h>
namespace grpc {
diff --git a/src/cpp/server/insecure_server_credentials.cc b/src/cpp/server/insecure_server_credentials.cc
index 87605f8ec9..7d749ddca4 100644
--- a/src/cpp/server/insecure_server_credentials.cc
+++ b/src/cpp/server/insecure_server_credentials.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/security/server_credentials.h>
+#include <grpcpp/security/server_credentials.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index 0fbe4ccd18..49ab2ea1bf 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -20,8 +20,8 @@
#include <map>
#include <memory>
-#include <grpc++/impl/codegen/slice.h>
-#include <grpc++/security/auth_metadata_processor.h>
+#include <grpcpp/impl/codegen/slice.h>
+#include <grpcpp/security/auth_metadata_processor.h>
#include "src/cpp/common/secure_auth_context.h"
#include "src/cpp/server/secure_server_credentials.h"
diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h
index 212f0d1df3..8a81af2f59 100644
--- a/src/cpp/server/secure_server_credentials.h
+++ b/src/cpp/server/secure_server_credentials.h
@@ -21,7 +21,7 @@
#include <memory>
-#include <grpc++/security/server_credentials.h>
+#include <grpcpp/security/server_credentials.h>
#include <grpc/grpc_security.h>
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 790095e1f6..e951801965 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -16,13 +16,13 @@
*
*/
-#include <grpc++/server_builder.h>
+#include <grpcpp/server_builder.h>
-#include <grpc++/impl/service_type.h>
-#include <grpc++/resource_quota.h>
-#include <grpc++/server.h>
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
+#include <grpcpp/impl/service_type.h>
+#include <grpcpp/resource_quota.h>
+#include <grpcpp/server.h>
#include "src/core/lib/gpr/useful.h"
#include "src/cpp/server/thread_pool_interface.h"
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 4f8f4e06fc..5638636e67 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -15,27 +15,27 @@
*
*/
-#include <grpc++/server.h>
+#include <grpcpp/server.h>
#include <cstdlib>
#include <sstream>
#include <utility>
-#include <grpc++/completion_queue.h>
-#include <grpc++/generic/async_generic_service.h>
-#include <grpc++/impl/codegen/async_unary_call.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/impl/method_handler_impl.h>
-#include <grpc++/impl/rpc_service_method.h>
-#include <grpc++/impl/server_initializer.h>
-#include <grpc++/impl/service_type.h>
-#include <grpc++/security/server_credentials.h>
-#include <grpc++/server_context.h>
-#include <grpc++/support/time.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpcpp/completion_queue.h>
+#include <grpcpp/generic/async_generic_service.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/impl/method_handler_impl.h>
+#include <grpcpp/impl/rpc_service_method.h>
+#include <grpcpp/impl/server_initializer.h>
+#include <grpcpp/impl/service_type.h>
+#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/server_context.h>
+#include <grpcpp/support/time.h>
#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/profiling/timers.h"
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 878be1c4b6..6f5bde0d9f 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -16,20 +16,20 @@
*
*/
-#include <grpc++/server_context.h>
+#include <grpcpp/server_context.h>
#include <algorithm>
#include <mutex>
#include <utility>
-#include <grpc++/completion_queue.h>
-#include <grpc++/impl/call.h>
-#include <grpc++/support/time.h>
#include <grpc/compression.h>
#include <grpc/grpc.h>
#include <grpc/load_reporting.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpcpp/completion_queue.h>
+#include <grpcpp/impl/call.h>
+#include <grpcpp/support/time.h>
#include "src/core/lib/surface/call.h"
diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc
index 158dfa8136..c3b3a8b379 100644
--- a/src/cpp/server/server_credentials.cc
+++ b/src/cpp/server/server_credentials.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/security/server_credentials.h>
+#include <grpcpp/security/server_credentials.h>
namespace grpc {
diff --git a/src/cpp/server/server_posix.cc b/src/cpp/server/server_posix.cc
index d3ef5cb650..7c221ed036 100644
--- a/src/cpp/server/server_posix.cc
+++ b/src/cpp/server/server_posix.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/server_posix.h>
+#include <grpcpp/server_posix.h>
#include <grpc/grpc_posix.h>
diff --git a/src/cpp/thread_manager/thread_manager.h b/src/cpp/thread_manager/thread_manager.h
index a206e0bd8a..1113031695 100644
--- a/src/cpp/thread_manager/thread_manager.h
+++ b/src/cpp/thread_manager/thread_manager.h
@@ -25,7 +25,7 @@
#include <mutex>
#include <thread>
-#include <grpc++/support/config.h>
+#include <grpcpp/support/config.h>
namespace grpc {
diff --git a/src/cpp/util/byte_buffer_cc.cc b/src/cpp/util/byte_buffer_cc.cc
index 180c813762..fbc1768bcc 100644
--- a/src/cpp/util/byte_buffer_cc.cc
+++ b/src/cpp/util/byte_buffer_cc.cc
@@ -16,10 +16,10 @@
*
*/
-#include <grpc++/impl/grpc_library.h>
-#include <grpc++/support/byte_buffer.h>
#include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/support/byte_buffer.h>
namespace grpc {
diff --git a/src/cpp/util/error_details.cc b/src/cpp/util/error_details.cc
index f06b475683..42c887aed7 100644
--- a/src/cpp/util/error_details.cc
+++ b/src/cpp/util/error_details.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/support/error_details.h>
+#include <grpcpp/support/error_details.h>
#include "src/proto/grpc/status/status.pb.h"
diff --git a/src/cpp/util/slice_cc.cc b/src/cpp/util/slice_cc.cc
index 3ae17e8052..9b50d10d17 100644
--- a/src/cpp/util/slice_cc.cc
+++ b/src/cpp/util/slice_cc.cc
@@ -16,8 +16,8 @@
*
*/
-#include <grpc++/support/slice.h>
#include <grpc/slice.h>
+#include <grpcpp/support/slice.h>
namespace grpc {
diff --git a/src/cpp/util/status.cc b/src/cpp/util/status.cc
index 0f793365e0..93696d8126 100644
--- a/src/cpp/util/status.cc
+++ b/src/cpp/util/status.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/support/status.h>
+#include <grpcpp/support/status.h>
namespace grpc {
diff --git a/src/cpp/util/string_ref.cc b/src/cpp/util/string_ref.cc
index 30c2ab6230..8b09a82a63 100644
--- a/src/cpp/util/string_ref.cc
+++ b/src/cpp/util/string_ref.cc
@@ -16,7 +16,7 @@
*
*/
-#include <grpc++/support/string_ref.h>
+#include <grpcpp/support/string_ref.h>
namespace grpc {
diff --git a/src/cpp/util/time_cc.cc b/src/cpp/util/time_cc.cc
index d475c25a5b..6c9c228d7c 100644
--- a/src/cpp/util/time_cc.cc
+++ b/src/cpp/util/time_cc.cc
@@ -16,9 +16,9 @@
*
*/
-#include <grpc++/support/config.h>
-#include <grpc++/support/time.h>
#include <grpc/support/time.h>
+#include <grpcpp/support/config.h>
+#include <grpcpp/support/time.h>
using std::chrono::duration_cast;
using std::chrono::high_resolution_clock;
diff --git a/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs b/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs
new file mode 100644
index 0000000000..02f6f6ffc6
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/Interceptors/ClientInterceptorTest.cs
@@ -0,0 +1,228 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Interceptors;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using Grpc.Core.Tests;
+using NUnit.Framework;
+
+namespace Grpc.Core.Interceptors.Tests
+{
+ public class ClientInterceptorTest
+ {
+ const string Host = "127.0.0.1";
+
+ [Test]
+ public void AddRequestHeaderInClientInterceptor()
+ {
+ const string HeaderKey = "x-client-interceptor";
+ const string HeaderValue = "hello-world";
+ var helper = new MockServiceHelper(Host);
+ helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
+ {
+ var interceptorHeader = context.RequestHeaders.Last(m => (m.Key == HeaderKey)).Value;
+ Assert.AreEqual(interceptorHeader, HeaderValue);
+ return Task.FromResult("PASS");
+ });
+ var server = helper.GetServer();
+ server.Start();
+ var callInvoker = helper.GetChannel().Intercept(metadata =>
+ {
+ metadata = metadata ?? new Metadata();
+ metadata.Add(new Metadata.Entry(HeaderKey, HeaderValue));
+ return metadata;
+ });
+ Assert.AreEqual("PASS", callInvoker.BlockingUnaryCall(new Method<string, string>(MethodType.Unary, MockServiceHelper.ServiceName, "Unary", Marshallers.StringMarshaller, Marshallers.StringMarshaller), Host, new CallOptions(), ""));
+ }
+
+ [Test]
+ public void CheckInterceptorOrderInClientInterceptors()
+ {
+ var helper = new MockServiceHelper(Host);
+ helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
+ {
+ return Task.FromResult("PASS");
+ });
+ var server = helper.GetServer();
+ server.Start();
+ var stringBuilder = new StringBuilder();
+ var callInvoker = helper.GetChannel().Intercept(metadata => {
+ stringBuilder.Append("interceptor1");
+ return metadata;
+ }).Intercept(new CallbackInterceptor(() => stringBuilder.Append("array1")),
+ new CallbackInterceptor(() => stringBuilder.Append("array2")),
+ new CallbackInterceptor(() => stringBuilder.Append("array3")))
+ .Intercept(metadata =>
+ {
+ stringBuilder.Append("interceptor2");
+ return metadata;
+ }).Intercept(metadata =>
+ {
+ stringBuilder.Append("interceptor3");
+ return metadata;
+ });
+ Assert.AreEqual("PASS", callInvoker.BlockingUnaryCall(new Method<string, string>(MethodType.Unary, MockServiceHelper.ServiceName, "Unary", Marshallers.StringMarshaller, Marshallers.StringMarshaller), Host, new CallOptions(), ""));
+ Assert.AreEqual("interceptor3interceptor2array1array2array3interceptor1", stringBuilder.ToString());
+ }
+
+ [Test]
+ public void CheckNullInterceptorRegistrationFails()
+ {
+ var helper = new MockServiceHelper(Host);
+ helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
+ {
+ return Task.FromResult("PASS");
+ });
+ Assert.Throws<ArgumentNullException>(() => helper.GetChannel().Intercept(default(Interceptor)));
+ Assert.Throws<ArgumentNullException>(() => helper.GetChannel().Intercept(new[]{default(Interceptor)}));
+ Assert.Throws<ArgumentNullException>(() => helper.GetChannel().Intercept(new[]{new CallbackInterceptor(()=>{}), null}));
+ Assert.Throws<ArgumentNullException>(() => helper.GetChannel().Intercept(default(Interceptor[])));
+ }
+
+ [Test]
+ public async Task CountNumberOfRequestsInClientInterceptors()
+ {
+ var helper = new MockServiceHelper(Host);
+ helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
+ {
+ var stringBuilder = new StringBuilder();
+ await requestStream.ForEachAsync(request =>
+ {
+ stringBuilder.Append(request);
+ return TaskUtils.CompletedTask;
+ });
+ await Task.Delay(100);
+ return stringBuilder.ToString();
+ });
+
+ var callInvoker = helper.GetChannel().Intercept(new ClientStreamingCountingInterceptor());
+
+ var server = helper.GetServer();
+ server.Start();
+ var call = callInvoker.AsyncClientStreamingCall(new Method<string, string>(MethodType.ClientStreaming, MockServiceHelper.ServiceName, "ClientStreaming", Marshallers.StringMarshaller, Marshallers.StringMarshaller), Host, new CallOptions());
+ await call.RequestStream.WriteAllAsync(new string[] { "A", "B", "C" });
+ Assert.AreEqual("3", await call.ResponseAsync);
+
+ Assert.AreEqual(StatusCode.OK, call.GetStatus().StatusCode);
+ Assert.IsNotNull(call.GetTrailers());
+ }
+
+ private class CallbackInterceptor : Interceptor
+ {
+ readonly Action callback;
+
+ public CallbackInterceptor(Action callback)
+ {
+ this.callback = GrpcPreconditions.CheckNotNull(callback, nameof(callback));
+ }
+
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation)
+ {
+ callback();
+ return continuation(request, context);
+ }
+
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
+ {
+ callback();
+ return continuation(request, context);
+ }
+
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ callback();
+ return continuation(request, context);
+ }
+
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ callback();
+ return continuation(context);
+ }
+
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncDuplexStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ callback();
+ return continuation(context);
+ }
+ }
+
+ private class ClientStreamingCountingInterceptor : Interceptor
+ {
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ var response = continuation(context);
+ int counter = 0;
+ var requestStream = new WrappedClientStreamWriter<TRequest>(response.RequestStream,
+ message => { counter++; return message; }, null);
+ var responseAsync = response.ResponseAsync.ContinueWith(
+ unaryResponse => (TResponse)(object)counter.ToString() // Cast to object first is needed to satisfy the type-checker
+ );
+ return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, responseAsync, response.ResponseHeadersAsync, response.GetStatus, response.GetTrailers, response.Dispose);
+ }
+ }
+
+ private class WrappedClientStreamWriter<T> : IClientStreamWriter<T>
+ {
+ readonly IClientStreamWriter<T> writer;
+ readonly Func<T, T> onMessage;
+ readonly Action onResponseStreamEnd;
+ public WrappedClientStreamWriter(IClientStreamWriter<T> writer, Func<T, T> onMessage, Action onResponseStreamEnd)
+ {
+ this.writer = writer;
+ this.onMessage = onMessage;
+ this.onResponseStreamEnd = onResponseStreamEnd;
+ }
+ public Task CompleteAsync()
+ {
+ if (onResponseStreamEnd != null)
+ {
+ return writer.CompleteAsync().ContinueWith(x => onResponseStreamEnd());
+ }
+ return writer.CompleteAsync();
+ }
+ public Task WriteAsync(T message)
+ {
+ if (onMessage != null)
+ {
+ message = onMessage(message);
+ }
+ return writer.WriteAsync(message);
+ }
+ public WriteOptions WriteOptions
+ {
+ get
+ {
+ return writer.WriteOptions;
+ }
+ set
+ {
+ writer.WriteOptions = value;
+ }
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs
new file mode 100644
index 0000000000..e76f21d098
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/Interceptors/ServerInterceptorTest.cs
@@ -0,0 +1,126 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Interceptors;
+using Grpc.Core.Internal;
+using Grpc.Core.Tests;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Interceptors.Tests
+{
+ public class ServerInterceptorTest
+ {
+ const string Host = "127.0.0.1";
+
+ [Test]
+ public void AddRequestHeaderInServerInterceptor()
+ {
+ var helper = new MockServiceHelper(Host);
+ const string MetadataKey = "x-interceptor";
+ const string MetadataValue = "hello world";
+ var interceptor = new ServerCallContextInterceptor(ctx => ctx.RequestHeaders.Add(new Metadata.Entry(MetadataKey, MetadataValue)));
+ helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
+ {
+ var interceptorHeader = context.RequestHeaders.Last(m => (m.Key == MetadataKey)).Value;
+ Assert.AreEqual(interceptorHeader, MetadataValue);
+ return Task.FromResult("PASS");
+ });
+ helper.ServiceDefinition = helper.ServiceDefinition.Intercept(interceptor);
+ var server = helper.GetServer();
+ server.Start();
+ var channel = helper.GetChannel();
+ Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
+ }
+
+ [Test]
+ public void VerifyInterceptorOrdering()
+ {
+ var helper = new MockServiceHelper(Host);
+ helper.UnaryHandler = new UnaryServerMethod<string, string>((request, context) =>
+ {
+ return Task.FromResult("PASS");
+ });
+ var stringBuilder = new StringBuilder();
+ helper.ServiceDefinition = helper.ServiceDefinition
+ .Intercept(new ServerCallContextInterceptor(ctx => stringBuilder.Append("A")))
+ .Intercept(new ServerCallContextInterceptor(ctx => stringBuilder.Append("B1")),
+ new ServerCallContextInterceptor(ctx => stringBuilder.Append("B2")),
+ new ServerCallContextInterceptor(ctx => stringBuilder.Append("B3")))
+ .Intercept(new ServerCallContextInterceptor(ctx => stringBuilder.Append("C")));
+ var server = helper.GetServer();
+ server.Start();
+ var channel = helper.GetChannel();
+ Assert.AreEqual("PASS", Calls.BlockingUnaryCall(helper.CreateUnaryCall(), ""));
+ Assert.AreEqual("CB1B2B3A", stringBuilder.ToString());
+ }
+
+ [Test]
+ public void CheckNullInterceptorRegistrationFails()
+ {
+ var helper = new MockServiceHelper(Host);
+ var sd = helper.ServiceDefinition;
+ Assert.Throws<ArgumentNullException>(() => sd.Intercept(default(Interceptor)));
+ Assert.Throws<ArgumentNullException>(() => sd.Intercept(new[]{default(Interceptor)}));
+ Assert.Throws<ArgumentNullException>(() => sd.Intercept(new[]{new ServerCallContextInterceptor(ctx=>{}), null}));
+ Assert.Throws<ArgumentNullException>(() => sd.Intercept(default(Interceptor[])));
+ }
+
+ private class ServerCallContextInterceptor : Interceptor
+ {
+ readonly Action<ServerCallContext> interceptor;
+
+ public ServerCallContextInterceptor(Action<ServerCallContext> interceptor)
+ {
+ GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor));
+ this.interceptor = interceptor;
+ }
+
+ public override Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
+ {
+ interceptor(context);
+ return continuation(request, context);
+ }
+
+ public override Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)
+ {
+ interceptor(context);
+ return continuation(requestStream, context);
+ }
+
+ public override Task ServerStreamingServerHandler<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)
+ {
+ interceptor(context);
+ return continuation(request, responseStream, context);
+ }
+
+ public override Task DuplexStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)
+ {
+ interceptor(context);
+ return continuation(requestStream, responseStream, context);
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
index 7f4677d57f..a925f865ff 100644
--- a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
+++ b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
@@ -37,7 +37,6 @@ namespace Grpc.Core.Tests
public const string ServiceName = "tests.Test";
readonly string host;
- readonly ServerServiceDefinition serviceDefinition;
readonly IEnumerable<ChannelOption> channelOptions;
readonly Method<string, string> unaryMethod;
@@ -87,7 +86,7 @@ namespace Grpc.Core.Tests
marshaller,
marshaller);
- serviceDefinition = ServerServiceDefinition.CreateBuilder()
+ ServiceDefinition = ServerServiceDefinition.CreateBuilder()
.AddMethod(unaryMethod, (request, context) => unaryHandler(request, context))
.AddMethod(clientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context))
.AddMethod(serverStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context))
@@ -131,7 +130,7 @@ namespace Grpc.Core.Tests
// Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{
- Services = { serviceDefinition },
+ Services = { ServiceDefinition },
Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
};
}
@@ -178,13 +177,7 @@ namespace Grpc.Core.Tests
}
}
- public ServerServiceDefinition ServiceDefinition
- {
- get
- {
- return this.serviceDefinition;
- }
- }
+ public ServerServiceDefinition ServiceDefinition { get; set; }
public UnaryServerMethod<string, string> UnaryHandler
{
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index 2d41b29fa0..fac34071be 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -16,6 +16,8 @@
#endregion
+using System;
+using Grpc.Core.Interceptors;
using Grpc.Core.Internal;
using Grpc.Core.Utils;
@@ -147,6 +149,52 @@ namespace Grpc.Core
/// </summary>
protected internal class ClientBaseConfiguration
{
+ private class ClientBaseConfigurationInterceptor : Interceptor
+ {
+ readonly Func<IMethod, string, CallOptions, Tuple<string, CallOptions>> interceptor;
+
+ /// <summary>
+ /// Creates a new instance of ClientBaseConfigurationInterceptor given the specified header and host interceptor function.
+ /// </summary>
+ public ClientBaseConfigurationInterceptor(Func<IMethod, string, CallOptions, Tuple<string, CallOptions>> interceptor)
+ {
+ this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor));
+ }
+
+ private ClientInterceptorContext<TRequest, TResponse> GetNewContext<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class
+ {
+ var newHostAndCallOptions = interceptor(context.Method, context.Host, context.Options);
+ return new ClientInterceptorContext<TRequest, TResponse>(context.Method, newHostAndCallOptions.Item1, newHostAndCallOptions.Item2);
+ }
+
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(request, GetNewContext(context));
+ }
+
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(request, GetNewContext(context));
+ }
+
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(request, GetNewContext(context));
+ }
+
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(GetNewContext(context));
+ }
+
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncDuplexStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(GetNewContext(context));
+ }
+ }
+
readonly CallInvoker undecoratedCallInvoker;
readonly string host;
@@ -158,12 +206,12 @@ namespace Grpc.Core
internal CallInvoker CreateDecoratedCallInvoker()
{
- return new InterceptingCallInvoker(undecoratedCallInvoker, hostInterceptor: (h) => host);
+ return undecoratedCallInvoker.Intercept(new ClientBaseConfigurationInterceptor((method, host, options) => Tuple.Create(this.host, options)));
}
internal ClientBaseConfiguration WithHost(string host)
{
- GrpcPreconditions.CheckNotNull(host, "host");
+ GrpcPreconditions.CheckNotNull(host, nameof(host));
return new ClientBaseConfiguration(this.undecoratedCallInvoker, host);
}
}
diff --git a/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs b/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs
new file mode 100644
index 0000000000..421b5d379e
--- /dev/null
+++ b/src/csharp/Grpc.Core/Interceptors/CallInvokerExtensions.cs
@@ -0,0 +1,144 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Linq;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Interceptors
+{
+ /// <summary>
+ /// Extends the CallInvoker class to provide the interceptor facility on the client side.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ public static class CallInvokerExtensions
+ {
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts
+ /// the invoker with the given interceptor.
+ /// </summary>
+ /// <param name="invoker">The underlying invoker to intercept.</param>
+ /// <param name="interceptor">The interceptor to intercept calls to the invoker with.</param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by calling
+ /// "invoker.Intercept(a, b, c)". The order of invocation will be "a", "b", and then "c".
+ /// Interceptors can be later added to an existing intercepted CallInvoker, effectively
+ /// building a chain like "invoker.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static CallInvoker Intercept(this CallInvoker invoker, Interceptor interceptor)
+ {
+ return new InterceptingCallInvoker(invoker, interceptor);
+ }
+
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts
+ /// the invoker with the given interceptors.
+ /// </summary>
+ /// <param name="invoker">The channel to intercept.</param>
+ /// <param name="interceptors">
+ /// An array of interceptors to intercept the calls to the invoker with.
+ /// Control is passed to the interceptors in the order specified.
+ /// </param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by calling
+ /// "invoker.Intercept(a, b, c)". The order of invocation will be "a", "b", and then "c".
+ /// Interceptors can be later added to an existing intercepted CallInvoker, effectively
+ /// building a chain like "invoker.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static CallInvoker Intercept(this CallInvoker invoker, params Interceptor[] interceptors)
+ {
+ GrpcPreconditions.CheckNotNull(invoker, nameof(invoker));
+ GrpcPreconditions.CheckNotNull(interceptors, nameof(interceptors));
+
+ foreach (var interceptor in interceptors.Reverse())
+ {
+ invoker = Intercept(invoker, interceptor);
+ }
+
+ return invoker;
+ }
+
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts
+ /// the invoker with the given interceptor.
+ /// </summary>
+ /// <param name="invoker">The underlying invoker to intercept.</param>
+ /// <param name="interceptor">
+ /// An interceptor delegate that takes the request metadata to be sent with an outgoing call
+ /// and returns a <see cref="Grpc.Core.Metadata" /> instance that will replace the existing
+ /// invocation metadata.
+ /// </param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by
+ /// building a chain like "invoker.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static CallInvoker Intercept(this CallInvoker invoker, Func<Metadata, Metadata> interceptor)
+ {
+ return new InterceptingCallInvoker(invoker, new MetadataInterceptor(interceptor));
+ }
+
+ private class MetadataInterceptor : Interceptor
+ {
+ readonly Func<Metadata, Metadata> interceptor;
+
+ /// <summary>
+ /// Creates a new instance of MetadataInterceptor given the specified interceptor function.
+ /// </summary>
+ public MetadataInterceptor(Func<Metadata, Metadata> interceptor)
+ {
+ this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor));
+ }
+
+ private ClientInterceptorContext<TRequest, TResponse> GetNewContext<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class
+ {
+ var metadata = context.Options.Headers ?? new Metadata();
+ return new ClientInterceptorContext<TRequest, TResponse>(context.Method, context.Host, context.Options.WithHeaders(interceptor(metadata)));
+ }
+
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(request, GetNewContext(context));
+ }
+
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(request, GetNewContext(context));
+ }
+
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(request, GetNewContext(context));
+ }
+
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(GetNewContext(context));
+ }
+
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncDuplexStreamingCallContinuation<TRequest, TResponse> continuation)
+ {
+ return continuation(GetNewContext(context));
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs
new file mode 100644
index 0000000000..00b2fa8bec
--- /dev/null
+++ b/src/csharp/Grpc.Core/Interceptors/ChannelExtensions.cs
@@ -0,0 +1,88 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+
+namespace Grpc.Core.Interceptors
+{
+ /// <summary>
+ /// Provides extension methods to make it easy to register interceptors on Channel objects.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ public static class ChannelExtensions
+ {
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts
+ /// the channel with the given interceptor.
+ /// </summary>
+ /// <param name="channel">The channel to intercept.</param>
+ /// <param name="interceptor">The interceptor to intercept the channel with.</param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by calling
+ /// "channel.Intercept(a, b, c)". The order of invocation will be "a", "b", and then "c".
+ /// Interceptors can be later added to an existing intercepted channel, effectively
+ /// building a chain like "channel.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static CallInvoker Intercept(this Channel channel, Interceptor interceptor)
+ {
+ return new DefaultCallInvoker(channel).Intercept(interceptor);
+ }
+
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts
+ /// the channel with the given interceptors.
+ /// </summary>
+ /// <param name="channel">The channel to intercept.</param>
+ /// <param name="interceptors">
+ /// An array of interceptors to intercept the channel with.
+ /// Control is passed to the interceptors in the order specified.
+ /// </param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by calling
+ /// "channel.Intercept(a, b, c)". The order of invocation will be "a", "b", and then "c".
+ /// Interceptors can be later added to an existing intercepted channel, effectively
+ /// building a chain like "channel.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static CallInvoker Intercept(this Channel channel, params Interceptor[] interceptors)
+ {
+ return new DefaultCallInvoker(channel).Intercept(interceptors);
+ }
+
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.CallInvoker" /> instance that intercepts
+ /// the invoker with the given interceptor.
+ /// </summary>
+ /// <param name="channel">The channel to intercept.</param>
+ /// <param name="interceptor">
+ /// An interceptor delegate that takes the request metadata to be sent with an outgoing call
+ /// and returns a <see cref="Grpc.Core.Metadata" /> instance that will replace the existing
+ /// invocation metadata.
+ /// </param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by
+ /// building a chain like "channel.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static CallInvoker Intercept(this Channel channel, Func<Metadata, Metadata> interceptor)
+ {
+ return new DefaultCallInvoker(channel).Intercept(interceptor);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs b/src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs
new file mode 100644
index 0000000000..de06a77077
--- /dev/null
+++ b/src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs
@@ -0,0 +1,65 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Reflection;
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
+
+namespace Grpc.Core.Interceptors
+{
+ /// <summary>
+ /// Carries along the context associated with intercepted invocations on the client side.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ public struct ClientInterceptorContext<TRequest, TResponse>
+ where TRequest : class
+ where TResponse : class
+ {
+ /// <summary>
+ /// Creates a new instance of <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}" />
+ /// with the specified method, host, and call options.
+ /// </summary>
+ /// <param name="method">A <see cref="Grpc.Core.Method{TRequest, TResponse}"/> object representing the method to be invoked.</param>
+ /// <param name="host">The host to dispatch the current call to.</param>
+ /// <param name="options">A <see cref="Grpc.Core.CallOptions"/> instance containing the call options of the current call.</param>
+ public ClientInterceptorContext(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ Method = method;
+ Host = host;
+ Options = options;
+ }
+
+ /// <summary>
+ /// Gets the <see cref="Grpc.Core.Method{TRequest, TResponse}"/> instance
+ /// representing the method to be invoked.
+ /// </summary>
+ public Method<TRequest, TResponse> Method { get; }
+
+ /// <summary>
+ /// Gets the host that the currect invocation will be dispatched to.
+ /// </summary>
+ public string Host { get; }
+
+ /// <summary>
+ /// Gets the <see cref="Grpc.Core.CallOptions"/> structure representing the
+ /// call options associated with the current invocation.
+ /// </summary>
+ public CallOptions Options { get; }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Interceptors/InterceptingCallInvoker.cs b/src/csharp/Grpc.Core/Interceptors/InterceptingCallInvoker.cs
new file mode 100644
index 0000000000..84d2a0b958
--- /dev/null
+++ b/src/csharp/Grpc.Core/Interceptors/InterceptingCallInvoker.cs
@@ -0,0 +1,96 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Interceptors
+{
+ /// <summary>
+ /// Decorates an underlying <see cref="Grpc.Core.CallInvoker" /> to
+ /// intercept calls through a given interceptor.
+ /// </summary>
+ internal class InterceptingCallInvoker : CallInvoker
+ {
+ readonly CallInvoker invoker;
+ readonly Interceptor interceptor;
+
+ /// <summary>
+ /// Creates a new instance of <see cref="Grpc.Core.Interceptors.InterceptingCallInvoker" />
+ /// with the given underlying invoker and interceptor instances.
+ /// </summary>
+ public InterceptingCallInvoker(CallInvoker invoker, Interceptor interceptor)
+ {
+ this.invoker = GrpcPreconditions.CheckNotNull(invoker, nameof(invoker));
+ this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor));
+ }
+
+ /// <summary>
+ /// Intercepts a simple blocking call with the registered interceptor.
+ /// </summary>
+ public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ return interceptor.BlockingUnaryCall(
+ request,
+ new ClientInterceptorContext<TRequest, TResponse>(method, host, options),
+ (req, ctx) => invoker.BlockingUnaryCall(ctx.Method, ctx.Host, ctx.Options, req));
+ }
+
+ /// <summary>
+ /// Intercepts a simple asynchronous call with the registered interceptor.
+ /// </summary>
+ public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ return interceptor.AsyncUnaryCall(
+ request,
+ new ClientInterceptorContext<TRequest, TResponse>(method, host, options),
+ (req, ctx) => invoker.AsyncUnaryCall(ctx.Method, ctx.Host, ctx.Options, req));
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous server streaming call with the registered interceptor.
+ /// </summary>
+ public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
+ {
+ return interceptor.AsyncServerStreamingCall(
+ request,
+ new ClientInterceptorContext<TRequest, TResponse>(method, host, options),
+ (req, ctx) => invoker.AsyncServerStreamingCall(ctx.Method, ctx.Host, ctx.Options, req));
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous client streaming call with the registered interceptor.
+ /// </summary>
+ public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ return interceptor.AsyncClientStreamingCall(
+ new ClientInterceptorContext<TRequest, TResponse>(method, host, options),
+ ctx => invoker.AsyncClientStreamingCall(ctx.Method, ctx.Host, ctx.Options));
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous duplex streaming call with the registered interceptor.
+ /// </summary>
+ public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
+ {
+ return interceptor.AsyncDuplexStreamingCall(
+ new ClientInterceptorContext<TRequest, TResponse>(method, host, options),
+ ctx => invoker.AsyncDuplexStreamingCall(ctx.Method, ctx.Host, ctx.Options));
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Interceptors/Interceptor.cs b/src/csharp/Grpc.Core/Interceptors/Interceptor.cs
new file mode 100644
index 0000000000..56a30c34af
--- /dev/null
+++ b/src/csharp/Grpc.Core/Interceptors/Interceptor.cs
@@ -0,0 +1,406 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Reflection;
+using System.Threading.Tasks;
+using Grpc.Core.Internal;
+
+namespace Grpc.Core.Interceptors
+{
+ /// <summary>
+ /// Serves as the base class for gRPC interceptors.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ public abstract class Interceptor
+ {
+ /// <summary>
+ /// Represents a continuation for intercepting simple blocking invocations.
+ /// A delegate of this type is passed to the BlockingUnaryCall method
+ /// when an outgoing invocation is being intercepted and calling the
+ /// delegate will invoke the next interceptor in the chain, or the underlying
+ /// call invoker if called from the last interceptor. The interceptor is
+ /// allowed to call it zero, one, or multiple times, passing it the appropriate
+ /// context and request values as it sees fit.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
+ /// <param name="request">The request value to continue the invocation with.</param>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// instance to pass to the next step in the invocation process.
+ /// </param>
+ /// <returns>
+ /// The response value of the invocation to return to the caller.
+ /// The interceptor can choose to return the return value of the
+ /// continuation delegate or an arbitrary value as it sees fit.
+ /// </returns>
+ public delegate TResponse BlockingUnaryCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Represents a continuation for intercepting simple asynchronous invocations.
+ /// A delegate of this type is passed to the AsyncUnaryCall method
+ /// when an outgoing invocation is being intercepted and calling the
+ /// delegate will invoke the next interceptor in the chain, or the underlying
+ /// call invoker if called from the last interceptor. The interceptor is
+ /// allowed to call it zero, one, or multiple times, passing it the appropriate
+ /// request value and context as it sees fit.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
+ /// <param name="request">The request value to continue the invocation with.</param>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// instance to pass to the next step in the invocation process.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncUnaryCall{TResponse}" />
+ /// representing an asynchronous invocation of a unary RPC.
+ /// The interceptor can choose to return the same object returned from
+ /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
+ /// </returns>
+ public delegate AsyncUnaryCall<TResponse> AsyncUnaryCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Represents a continuation for intercepting asynchronous server-streaming invocations.
+ /// A delegate of this type is passed to the AsyncServerStreamingCall method
+ /// when an outgoing invocation is being intercepted and calling the
+ /// delegate will invoke the next interceptor in the chain, or the underlying
+ /// call invoker if called from the last interceptor. The interceptor is
+ /// allowed to call it zero, one, or multiple times, passing it the appropriate
+ /// request value and context as it sees fit.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
+ /// <param name="request">The request value to continue the invocation with.</param>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// instance to pass to the next step in the invocation process.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncServerStreamingCall{TResponse}" />
+ /// representing an asynchronous invocation of a server-streaming RPC.
+ /// The interceptor can choose to return the same object returned from
+ /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
+ /// </returns>
+ public delegate AsyncServerStreamingCall<TResponse> AsyncServerStreamingCallContinuation<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Represents a continuation for intercepting asynchronous client-streaming invocations.
+ /// A delegate of this type is passed to the AsyncClientStreamingCall method
+ /// when an outgoing invocation is being intercepted and calling the
+ /// delegate will invoke the next interceptor in the chain, or the underlying
+ /// call invoker if called from the last interceptor. The interceptor is
+ /// allowed to call it zero, one, or multiple times, passing it the appropriate
+ /// request value and context as it sees fit.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this invocation.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this invocation.</typeparam>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// instance to pass to the next step in the invocation process.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncClientStreamingCall{TRequest, TResponse}" />
+ /// representing an asynchronous invocation of a client-streaming RPC.
+ /// The interceptor can choose to return the same object returned from
+ /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
+ /// </returns>
+ public delegate AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCallContinuation<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Represents a continuation for intercepting asynchronous duplex invocations.
+ /// A delegate of this type is passed to the AsyncDuplexStreamingCall method
+ /// when an outgoing invocation is being intercepted and calling the
+ /// delegate will invoke the next interceptor in the chain, or the underlying
+ /// call invoker if called from the last interceptor. The interceptor is
+ /// allowed to call it zero, one, or multiple times, passing it the appropriate
+ /// request value and context as it sees fit.
+ /// </summary>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// instance to pass to the next step in the invocation process.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncDuplexStreamingCall{TRequest, TResponse}" />
+ /// representing an asynchronous invocation of a duplex-streaming RPC.
+ /// The interceptor can choose to return the same object returned from
+ /// the continuation delegate or an arbitrarily constructed instance as it sees fit.
+ /// </returns>
+ public delegate AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCallContinuation<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context)
+ where TRequest : class
+ where TResponse : class;
+
+ /// <summary>
+ /// Intercepts a blocking invocation of a simple remote call.
+ /// </summary>
+ /// <param name="request">The request message of the invocation.</param>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// associated with the current invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// The callback that continues the invocation process.
+ /// This can be invoked zero or more times by the interceptor.
+ /// The interceptor can invoke the continuation passing the given
+ /// request value and context arguments, or substitute them as it sees fit.
+ /// </param>
+ /// <returns>
+ /// The response message of the current invocation.
+ /// The interceptor can simply return the return value of the
+ /// continuation delegate passed to it intact, or an arbitrary
+ /// value as it sees fit.
+ /// </returns>
+ public virtual TResponse BlockingUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, BlockingUnaryCallContinuation<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(request, context);
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous invocation of a simple remote call.
+ /// </summary>
+ /// <param name="request">The request message of the invocation.</param>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// associated with the current invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// The callback that continues the invocation process.
+ /// This can be invoked zero or more times by the interceptor.
+ /// The interceptor can invoke the continuation passing the given
+ /// request value and context arguments, or substitute them as it sees fit.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncUnaryCall{TResponse}" />
+ /// representing an asynchronous unary invocation.
+ /// The interceptor can simply return the return value of the
+ /// continuation delegate passed to it intact, or construct its
+ /// own substitute as it sees fit.
+ /// </returns>
+ public virtual AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(request, context);
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous invocation of a streaming remote call.
+ /// </summary>
+ /// <param name="request">The request message of the invocation.</param>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// associated with the current invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// The callback that continues the invocation process.
+ /// This can be invoked zero or more times by the interceptor.
+ /// The interceptor can invoke the continuation passing the given
+ /// request value and context arguments, or substitute them as it sees fit.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncServerStreamingCall{TResponse}" />
+ /// representing an asynchronous server-streaming invocation.
+ /// The interceptor can simply return the return value of the
+ /// continuation delegate passed to it intact, or construct its
+ /// own substitute as it sees fit.
+ /// </returns>
+ public virtual AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(TRequest request, ClientInterceptorContext<TRequest, TResponse> context, AsyncServerStreamingCallContinuation<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(request, context);
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous invocation of a client streaming call.
+ /// </summary>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// associated with the current invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// The callback that continues the invocation process.
+ /// This can be invoked zero or more times by the interceptor.
+ /// The interceptor can invoke the continuation passing the given
+ /// context argument, or substitute as it sees fit.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncClientStreamingCall{TRequest, TResponse}" />
+ /// representing an asynchronous client-streaming invocation.
+ /// The interceptor can simply return the return value of the
+ /// continuation delegate passed to it intact, or construct its
+ /// own substitute as it sees fit.
+ /// </returns>
+ public virtual AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncClientStreamingCallContinuation<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(context);
+ }
+
+ /// <summary>
+ /// Intercepts an asynchronous invocation of a duplex streaming call.
+ /// </summary>
+ /// <param name="context">
+ /// The <see cref="Grpc.Core.Interceptors.ClientInterceptorContext{TRequest, TResponse}"/>
+ /// associated with the current invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// The callback that continues the invocation process.
+ /// This can be invoked zero or more times by the interceptor.
+ /// The interceptor can invoke the continuation passing the given
+ /// context argument, or substitute as it sees fit.
+ /// </param>
+ /// <returns>
+ /// An instance of <see cref="Grpc.Core.AsyncDuplexStreamingCall{TRequest, TResponse}" />
+ /// representing an asynchronous duplex-streaming invocation.
+ /// The interceptor can simply return the return value of the
+ /// continuation delegate passed to it intact, or construct its
+ /// own substitute as it sees fit.
+ /// </returns>
+ public virtual AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(ClientInterceptorContext<TRequest, TResponse> context, AsyncDuplexStreamingCallContinuation<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(context);
+ }
+
+ /// <summary>
+ /// Server-side handler for intercepting and incoming unary call.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this method.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this method.</typeparam>
+ /// <param name="request">The request value of the incoming invocation.</param>
+ /// <param name="context">
+ /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
+ /// the context of the invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// A delegate that asynchronously proceeds with the invocation, calling
+ /// the next interceptor in the chain, or the service request handler,
+ /// in case of the last interceptor and return the response value of
+ /// the RPC. The interceptor can choose to call it zero or more times
+ /// at its discretion.
+ /// </param>
+ /// <returns>
+ /// A future representing the response value of the RPC. The interceptor
+ /// can simply return the return value from the continuation intact,
+ /// or an arbitrary response value as it sees fit.
+ /// </returns>
+ public virtual Task<TResponse> UnaryServerHandler<TRequest, TResponse>(TRequest request, ServerCallContext context, UnaryServerMethod<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(request, context);
+ }
+
+ /// <summary>
+ /// Server-side handler for intercepting client streaming call.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this method.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this method.</typeparam>
+ /// <param name="requestStream">The request stream of the incoming invocation.</param>
+ /// <param name="context">
+ /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
+ /// the context of the invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// A delegate that asynchronously proceeds with the invocation, calling
+ /// the next interceptor in the chain, or the service request handler,
+ /// in case of the last interceptor and return the response value of
+ /// the RPC. The interceptor can choose to call it zero or more times
+ /// at its discretion.
+ /// </param>
+ /// <returns>
+ /// A future representing the response value of the RPC. The interceptor
+ /// can simply return the return value from the continuation intact,
+ /// or an arbitrary response value as it sees fit. The interceptor has
+ /// the ability to wrap or substitute the request stream when calling
+ /// the continuation.
+ /// </returns>
+ public virtual Task<TResponse> ClientStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, ServerCallContext context, ClientStreamingServerMethod<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(requestStream, context);
+ }
+
+ /// <summary>
+ /// Server-side handler for intercepting server streaming call.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this method.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this method.</typeparam>
+ /// <param name="request">The request value of the incoming invocation.</param>
+ /// <param name="responseStream">The response stream of the incoming invocation.</param>
+ /// <param name="context">
+ /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
+ /// the context of the invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// A delegate that asynchronously proceeds with the invocation, calling
+ /// the next interceptor in the chain, or the service request handler,
+ /// in case of the last interceptor and the interceptor can choose to
+ /// call it zero or more times at its discretion. The interceptor has
+ /// the ability to wrap or substitute the request value and the response stream
+ /// when calling the continuation.
+ /// </param>
+ public virtual Task ServerStreamingServerHandler<TRequest, TResponse>(TRequest request, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, ServerStreamingServerMethod<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(request, responseStream, context);
+ }
+
+ /// <summary>
+ /// Server-side handler for intercepting bidirectional streaming calls.
+ /// </summary>
+ /// <typeparam name="TRequest">Request message type for this method.</typeparam>
+ /// <typeparam name="TResponse">Response message type for this method.</typeparam>
+ /// <param name="requestStream">The request stream of the incoming invocation.</param>
+ /// <param name="responseStream">The response stream of the incoming invocation.</param>
+ /// <param name="context">
+ /// An instance of <see cref="Grpc.Core.ServerCallContext" /> representing
+ /// the context of the invocation.
+ /// </param>
+ /// <param name="continuation">
+ /// A delegate that asynchronously proceeds with the invocation, calling
+ /// the next interceptor in the chain, or the service request handler,
+ /// in case of the last interceptor and the interceptor can choose to
+ /// call it zero or more times at its discretion. The interceptor has
+ /// the ability to wrap or substitute the request and response streams
+ /// when calling the continuation.
+ /// </param>
+ public virtual Task DuplexStreamingServerHandler<TRequest, TResponse>(IAsyncStreamReader<TRequest> requestStream, IServerStreamWriter<TResponse> responseStream, ServerCallContext context, DuplexStreamingServerMethod<TRequest, TResponse> continuation)
+ where TRequest : class
+ where TResponse : class
+ {
+ return continuation(requestStream, responseStream, context);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs
new file mode 100644
index 0000000000..b9b53247ce
--- /dev/null
+++ b/src/csharp/Grpc.Core/Interceptors/ServerServiceDefinitionExtensions.cs
@@ -0,0 +1,82 @@
+#region Copyright notice and license
+
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Linq;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Interceptors
+{
+ /// <summary>
+ /// Extends the ServerServiceDefinition class to add methods used to register interceptors on the server side.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ public static class ServerServiceDefinitionExtensions
+ {
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.ServerServiceDefinition" /> instance that
+ /// intercepts incoming calls to the underlying service handler through the given interceptor.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ /// <param name="serverServiceDefinition">The <see cref="Grpc.Core.ServerServiceDefinition" /> instance to register interceptors on.</param>
+ /// <param name="interceptor">The interceptor to intercept the incoming invocations with.</param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by calling
+ /// "serverServiceDefinition.Intercept(a, b, c)". The order of invocation will be "a", "b", and then "c".
+ /// Interceptors can be later added to an existing intercepted service definition, effectively
+ /// building a chain like "serverServiceDefinition.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static ServerServiceDefinition Intercept(this ServerServiceDefinition serverServiceDefinition, Interceptor interceptor)
+ {
+ GrpcPreconditions.CheckNotNull(serverServiceDefinition, nameof(serverServiceDefinition));
+ GrpcPreconditions.CheckNotNull(interceptor, nameof(interceptor));
+ return new ServerServiceDefinition(serverServiceDefinition.CallHandlers.ToDictionary(x => x.Key, x => x.Value.Intercept(interceptor)));
+ }
+
+ /// <summary>
+ /// Returns a <see cref="Grpc.Core.ServerServiceDefinition" /> instance that
+ /// intercepts incoming calls to the underlying service handler through the given interceptors.
+ /// This is an EXPERIMENTAL API.
+ /// </summary>
+ /// <param name="serverServiceDefinition">The <see cref="Grpc.Core.ServerServiceDefinition" /> instance to register interceptors on.</param>
+ /// <param name="interceptors">
+ /// An array of interceptors to intercept the incoming invocations with.
+ /// Control is passed to the interceptors in the order specified.
+ /// </param>
+ /// <remarks>
+ /// Multiple interceptors can be added on top of each other by calling
+ /// "serverServiceDefinition.Intercept(a, b, c)". The order of invocation will be "a", "b", and then "c".
+ /// Interceptors can be later added to an existing intercepted service definition, effectively
+ /// building a chain like "serverServiceDefinition.Intercept(c).Intercept(b).Intercept(a)". Note that
+ /// in this case, the last interceptor added will be the first to take control.
+ /// </remarks>
+ public static ServerServiceDefinition Intercept(this ServerServiceDefinition serverServiceDefinition, params Interceptor[] interceptors)
+ {
+ GrpcPreconditions.CheckNotNull(serverServiceDefinition, nameof(serverServiceDefinition));
+ GrpcPreconditions.CheckNotNull(interceptors, nameof(interceptors));
+
+ foreach (var interceptor in interceptors.Reverse())
+ {
+ serverServiceDefinition = Intercept(serverServiceDefinition, interceptor);
+ }
+
+ return serverServiceDefinition;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs b/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
deleted file mode 100644
index eb4c7d97a7..0000000000
--- a/src/csharp/Grpc.Core/Internal/InterceptingCallInvoker.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-#region Copyright notice and license
-
-// Copyright 2015-2016 gRPC authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#endregion
-
-using System;
-using System.Threading.Tasks;
-using Grpc.Core;
-using Grpc.Core.Utils;
-
-namespace Grpc.Core.Internal
-{
- /// <summary>
- /// Decorates an underlying <c>CallInvoker</c> to intercept call invocations.
- /// </summary>
- internal class InterceptingCallInvoker : CallInvoker
- {
- readonly CallInvoker callInvoker;
- readonly Func<string, string> hostInterceptor;
- readonly Func<CallOptions, CallOptions> callOptionsInterceptor;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="Grpc.Core.Internal.InterceptingCallInvoker"/> class.
- /// </summary>
- public InterceptingCallInvoker(CallInvoker callInvoker,
- Func<string, string> hostInterceptor = null,
- Func<CallOptions, CallOptions> callOptionsInterceptor = null)
- {
- this.callInvoker = GrpcPreconditions.CheckNotNull(callInvoker);
- this.hostInterceptor = hostInterceptor;
- this.callOptionsInterceptor = callOptionsInterceptor;
- }
-
- /// <summary>
- /// Intercepts a unary call.
- /// </summary>
- public override TResponse BlockingUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
- {
- host = InterceptHost(host);
- options = InterceptCallOptions(options);
- return callInvoker.BlockingUnaryCall(method, host, options, request);
- }
-
- /// <summary>
- /// Invokes a simple remote call asynchronously.
- /// </summary>
- public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
- {
- host = InterceptHost(host);
- options = InterceptCallOptions(options);
- return callInvoker.AsyncUnaryCall(method, host, options, request);
- }
-
- /// <summary>
- /// Invokes a server streaming call asynchronously.
- /// In server streaming scenario, client sends on request and server responds with a stream of responses.
- /// </summary>
- public override AsyncServerStreamingCall<TResponse> AsyncServerStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options, TRequest request)
- {
- host = InterceptHost(host);
- options = InterceptCallOptions(options);
- return callInvoker.AsyncServerStreamingCall(method, host, options, request);
- }
-
- /// <summary>
- /// Invokes a client streaming call asynchronously.
- /// In client streaming scenario, client sends a stream of requests and server responds with a single response.
- /// </summary>
- public override AsyncClientStreamingCall<TRequest, TResponse> AsyncClientStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
- {
- host = InterceptHost(host);
- options = InterceptCallOptions(options);
- return callInvoker.AsyncClientStreamingCall(method, host, options);
- }
-
- /// <summary>
- /// Invokes a duplex streaming call asynchronously.
- /// In duplex streaming scenario, client sends a stream of requests and server responds with a stream of responses.
- /// The response stream is completely independent and both side can be sending messages at the same time.
- /// </summary>
- public override AsyncDuplexStreamingCall<TRequest, TResponse> AsyncDuplexStreamingCall<TRequest, TResponse>(Method<TRequest, TResponse> method, string host, CallOptions options)
- {
- host = InterceptHost(host);
- options = InterceptCallOptions(options);
- return callInvoker.AsyncDuplexStreamingCall(method, host, options);
- }
-
- private string InterceptHost(string host)
- {
- if (hostInterceptor == null)
- {
- return host;
- }
- return hostInterceptor(host);
- }
-
- private CallOptions InterceptCallOptions(CallOptions options)
- {
- if (callOptionsInterceptor == null)
- {
- return options;
- }
- return callOptionsInterceptor(options);
- }
- }
-}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 98995a0862..81522cf8fe 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Grpc.Core.Interceptors;
using Grpc.Core.Internal;
using Grpc.Core.Logging;
using Grpc.Core.Utils;
@@ -30,6 +31,7 @@ namespace Grpc.Core.Internal
internal interface IServerCallHandler
{
Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq);
+ IServerCallHandler Intercept(Interceptor interceptor);
}
internal class UnaryServerCallHandler<TRequest, TResponse> : IServerCallHandler
@@ -74,7 +76,7 @@ namespace Grpc.Core.Internal
{
if (!(e is RpcException))
{
- Logger.Warning(e, "Exception occured in handler.");
+ Logger.Warning(e, "Exception occurred in the handler or an interceptor.");
}
status = HandlerUtils.GetStatusFromExceptionAndMergeTrailers(e, context.ResponseTrailers);
}
@@ -89,6 +91,11 @@ namespace Grpc.Core.Internal
}
await finishedTask.ConfigureAwait(false);
}
+
+ public IServerCallHandler Intercept(Interceptor interceptor)
+ {
+ return new UnaryServerCallHandler<TRequest, TResponse>(method, (request, context) => interceptor.UnaryServerHandler(request, context, handler));
+ }
}
internal class ServerStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler
@@ -131,7 +138,7 @@ namespace Grpc.Core.Internal
{
if (!(e is RpcException))
{
- Logger.Warning(e, "Exception occured in handler.");
+ Logger.Warning(e, "Exception occurred in the handler or an interceptor.");
}
status = HandlerUtils.GetStatusFromExceptionAndMergeTrailers(e, context.ResponseTrailers);
}
@@ -147,6 +154,11 @@ namespace Grpc.Core.Internal
}
await finishedTask.ConfigureAwait(false);
}
+
+ public IServerCallHandler Intercept(Interceptor interceptor)
+ {
+ return new ServerStreamingServerCallHandler<TRequest, TResponse>(method, (request, responseStream, context) => interceptor.ServerStreamingServerHandler(request, responseStream, context, handler));
+ }
}
internal class ClientStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler
@@ -189,7 +201,7 @@ namespace Grpc.Core.Internal
{
if (!(e is RpcException))
{
- Logger.Warning(e, "Exception occured in handler.");
+ Logger.Warning(e, "Exception occurred in the handler or an interceptor.");
}
status = HandlerUtils.GetStatusFromExceptionAndMergeTrailers(e, context.ResponseTrailers);
}
@@ -205,6 +217,11 @@ namespace Grpc.Core.Internal
}
await finishedTask.ConfigureAwait(false);
}
+
+ public IServerCallHandler Intercept(Interceptor interceptor)
+ {
+ return new ClientStreamingServerCallHandler<TRequest, TResponse>(method, (requestStream, context) => interceptor.ClientStreamingServerHandler(requestStream, context, handler));
+ }
}
internal class DuplexStreamingServerCallHandler<TRequest, TResponse> : IServerCallHandler
@@ -245,7 +262,7 @@ namespace Grpc.Core.Internal
{
if (!(e is RpcException))
{
- Logger.Warning(e, "Exception occured in handler.");
+ Logger.Warning(e, "Exception occurred in the handler or an interceptor.");
}
status = HandlerUtils.GetStatusFromExceptionAndMergeTrailers(e, context.ResponseTrailers);
}
@@ -260,6 +277,11 @@ namespace Grpc.Core.Internal
}
await finishedTask.ConfigureAwait(false);
}
+
+ public IServerCallHandler Intercept(Interceptor interceptor)
+ {
+ return new DuplexStreamingServerCallHandler<TRequest, TResponse>(method, (requestStream, responseStream, context) => interceptor.DuplexStreamingServerHandler(requestStream, responseStream, context, handler));
+ }
}
internal class UnimplementedMethodCallHandler : IServerCallHandler
@@ -288,6 +310,11 @@ namespace Grpc.Core.Internal
{
return callHandlerImpl.HandleCall(newRpc, cq);
}
+
+ public IServerCallHandler Intercept(Interceptor interceptor)
+ {
+ return this; // Do not intercept unimplemented methods.
+ }
}
internal static class HandlerUtils
diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
index 59868c1f40..07c6aa1796 100644
--- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs
+++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
@@ -19,7 +19,10 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Linq;
+using Grpc.Core.Interceptors;
using Grpc.Core.Internal;
+using Grpc.Core.Utils;
namespace Grpc.Core
{
@@ -32,7 +35,7 @@ namespace Grpc.Core
{
readonly ReadOnlyDictionary<string, IServerCallHandler> callHandlers;
- private ServerServiceDefinition(Dictionary<string, IServerCallHandler> callHandlers)
+ internal ServerServiceDefinition(Dictionary<string, IServerCallHandler> callHandlers)
{
this.callHandlers = new ReadOnlyDictionary<string, IServerCallHandler>(callHandlers);
}
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index 539d3a9f80..9b55f2469a 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
- <GrpcCsharpVersion>1.10.0-dev</GrpcCsharpVersion>
+ <GrpcCsharpVersion>1.11.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.3.0</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index f1aef46c6c..2902aee8d9 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
- public const string CurrentAssemblyFileVersion = "1.10.0.0";
+ public const string CurrentAssemblyFileVersion = "1.11.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.10.0-dev";
+ public const string CurrentVersion = "1.11.0-dev";
}
}
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index e29b1087e4..045708b947 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -20,9 +20,6 @@
#pragma warning disable 1591
#region Designer generated code
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Math {
@@ -159,7 +156,7 @@ namespace Math {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Math.DivReply Div(global::Math.DivArgs request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Math.DivReply Div(global::Math.DivArgs request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Div(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -183,7 +180,7 @@ namespace Math {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return DivAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -208,7 +205,7 @@ namespace Math {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return DivMany(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -234,7 +231,7 @@ namespace Math {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Fib(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -258,7 +255,7 @@ namespace Math {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Sum(new grpc::CallOptions(headers, deadline, cancellationToken));
}
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 24a7259979..1d80bcd59e 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -20,9 +20,6 @@
#pragma warning disable 1591
#region Designer generated code
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Grpc.Health.V1 {
@@ -79,7 +76,7 @@ namespace Grpc.Health.V1 {
{
}
- public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Check(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -87,7 +84,7 @@ namespace Grpc.Health.V1 {
{
return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
}
- public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CheckAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 8e5da7b9f2..8795728906 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -32,7 +32,7 @@ namespace Grpc.Testing {
"U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy",
"X2hvc3Rfb3ZlcnJpZGUYAiABKAkSEQoJY3JlZF90eXBlGAMgASgJIk0KCkNo",
"YW5uZWxBcmcSDAoEbmFtZRgBIAEoCRITCglzdHJfdmFsdWUYAiABKAlIABIT",
- "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSLVBAoMQ2xpZW50Q29uZmln",
+ "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSLvBAoMQ2xpZW50Q29uZmln",
"EhYKDnNlcnZlcl90YXJnZXRzGAEgAygJEi0KC2NsaWVudF90eXBlGAIgASgO",
"MhguZ3JwYy50ZXN0aW5nLkNsaWVudFR5cGUSNQoPc2VjdXJpdHlfcGFyYW1z",
"GAMgASgLMhwuZ3JwYy50ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEiQKHG91dHN0",
@@ -45,59 +45,60 @@ namespace Grpc.Testing {
"dG9ncmFtUGFyYW1zEhEKCWNvcmVfbGlzdBgNIAMoBRISCgpjb3JlX2xpbWl0",
"GA4gASgFEhgKEG90aGVyX2NsaWVudF9hcGkYDyABKAkSLgoMY2hhbm5lbF9h",
"cmdzGBAgAygLMhguZ3JwYy50ZXN0aW5nLkNoYW5uZWxBcmcSFgoOdGhyZWFk",
- "c19wZXJfY3EYESABKAUSGwoTbWVzc2FnZXNfcGVyX3N0cmVhbRgSIAEoBSI4",
- "CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRlc3Rpbmcu",
- "Q2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJoCgpDbGllbnRB",
- "cmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVudENvbmZp",
- "Z0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2Fy",
- "Z3R5cGUi/QIKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlwZRgBIAEoDjIY",
- "LmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgC",
- "IAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIMCgRwb3J0GAQg",
- "ASgFEhwKFGFzeW5jX3NlcnZlcl90aHJlYWRzGAcgASgFEhIKCmNvcmVfbGlt",
- "aXQYCCABKAUSMwoOcGF5bG9hZF9jb25maWcYCSABKAsyGy5ncnBjLnRlc3Rp",
- "bmcuUGF5bG9hZENvbmZpZxIRCgljb3JlX2xpc3QYCiADKAUSGAoQb3RoZXJf",
- "c2VydmVyX2FwaRgLIAEoCRIWCg50aHJlYWRzX3Blcl9jcRgMIAEoBRIcChNy",
- "ZXNvdXJjZV9xdW90YV9zaXplGOkHIAEoBRIvCgxjaGFubmVsX2FyZ3MY6gcg",
- "AygLMhguZ3JwYy50ZXN0aW5nLkNoYW5uZWxBcmciaAoKU2VydmVyQXJncxIr",
- "CgVzZXR1cBgBIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJDb25maWdIABIi",
- "CgRtYXJrGAIgASgLMhIuZ3JwYy50ZXN0aW5nLk1hcmtIAEIJCgdhcmd0eXBl",
- "IlUKDFNlcnZlclN0YXR1cxIoCgVzdGF0cxgBIAEoCzIZLmdycGMudGVzdGlu",
- "Zy5TZXJ2ZXJTdGF0cxIMCgRwb3J0GAIgASgFEg0KBWNvcmVzGAMgASgFIg0K",
- "C0NvcmVSZXF1ZXN0Ih0KDENvcmVSZXNwb25zZRINCgVjb3JlcxgBIAEoBSIG",
- "CgRWb2lkIv0BCghTY2VuYXJpbxIMCgRuYW1lGAEgASgJEjEKDWNsaWVudF9j",
- "b25maWcYAiABKAsyGi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnEhMKC251",
- "bV9jbGllbnRzGAMgASgFEjEKDXNlcnZlcl9jb25maWcYBCABKAsyGi5ncnBj",
- "LnRlc3RpbmcuU2VydmVyQ29uZmlnEhMKC251bV9zZXJ2ZXJzGAUgASgFEhYK",
- "Dndhcm11cF9zZWNvbmRzGAYgASgFEhkKEWJlbmNobWFya19zZWNvbmRzGAcg",
- "ASgFEiAKGHNwYXduX2xvY2FsX3dvcmtlcl9jb3VudBgIIAEoBSI2CglTY2Vu",
- "YXJpb3MSKQoJc2NlbmFyaW9zGAEgAygLMhYuZ3JwYy50ZXN0aW5nLlNjZW5h",
- "cmlvIoQEChVTY2VuYXJpb1Jlc3VsdFN1bW1hcnkSCwoDcXBzGAEgASgBEhsK",
- "E3Fwc19wZXJfc2VydmVyX2NvcmUYAiABKAESGgoSc2VydmVyX3N5c3RlbV90",
- "aW1lGAMgASgBEhgKEHNlcnZlcl91c2VyX3RpbWUYBCABKAESGgoSY2xpZW50",
- "X3N5c3RlbV90aW1lGAUgASgBEhgKEGNsaWVudF91c2VyX3RpbWUYBiABKAES",
- "EgoKbGF0ZW5jeV81MBgHIAEoARISCgpsYXRlbmN5XzkwGAggASgBEhIKCmxh",
- "dGVuY3lfOTUYCSABKAESEgoKbGF0ZW5jeV85ORgKIAEoARITCgtsYXRlbmN5",
- "Xzk5ORgLIAEoARIYChBzZXJ2ZXJfY3B1X3VzYWdlGAwgASgBEiYKHnN1Y2Nl",
- "c3NmdWxfcmVxdWVzdHNfcGVyX3NlY29uZBgNIAEoARIiChpmYWlsZWRfcmVx",
- "dWVzdHNfcGVyX3NlY29uZBgOIAEoARIgChhjbGllbnRfcG9sbHNfcGVyX3Jl",
- "cXVlc3QYDyABKAESIAoYc2VydmVyX3BvbGxzX3Blcl9yZXF1ZXN0GBAgASgB",
- "EiIKGnNlcnZlcl9xdWVyaWVzX3Blcl9jcHVfc2VjGBEgASgBEiIKGmNsaWVu",
- "dF9xdWVyaWVzX3Blcl9jcHVfc2VjGBIgASgBIoMDCg5TY2VuYXJpb1Jlc3Vs",
- "dBIoCghzY2VuYXJpbxgBIAEoCzIWLmdycGMudGVzdGluZy5TY2VuYXJpbxIu",
- "CglsYXRlbmNpZXMYAiABKAsyGy5ncnBjLnRlc3RpbmcuSGlzdG9ncmFtRGF0",
- "YRIvCgxjbGllbnRfc3RhdHMYAyADKAsyGS5ncnBjLnRlc3RpbmcuQ2xpZW50",
- "U3RhdHMSLwoMc2VydmVyX3N0YXRzGAQgAygLMhkuZ3JwYy50ZXN0aW5nLlNl",
- "cnZlclN0YXRzEhQKDHNlcnZlcl9jb3JlcxgFIAMoBRI0CgdzdW1tYXJ5GAYg",
- "ASgLMiMuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvUmVzdWx0U3VtbWFyeRIWCg5j",
- "bGllbnRfc3VjY2VzcxgHIAMoCBIWCg5zZXJ2ZXJfc3VjY2VzcxgIIAMoCBI5",
- "Cg9yZXF1ZXN0X3Jlc3VsdHMYCSADKAsyIC5ncnBjLnRlc3RpbmcuUmVxdWVz",
- "dFJlc3VsdENvdW50KkEKCkNsaWVudFR5cGUSDwoLU1lOQ19DTElFTlQQABIQ",
- "CgxBU1lOQ19DTElFTlQQARIQCgxPVEhFUl9DTElFTlQQAipbCgpTZXJ2ZXJU",
- "eXBlEg8KC1NZTkNfU0VSVkVSEAASEAoMQVNZTkNfU0VSVkVSEAESGAoUQVNZ",
- "TkNfR0VORVJJQ19TRVJWRVIQAhIQCgxPVEhFUl9TRVJWRVIQAypyCgdScGNU",
- "eXBlEgkKBVVOQVJZEAASDQoJU1RSRUFNSU5HEAESGQoVU1RSRUFNSU5HX0ZS",
- "T01fQ0xJRU5UEAISGQoVU1RSRUFNSU5HX0ZST01fU0VSVkVSEAMSFwoTU1RS",
- "RUFNSU5HX0JPVEhfV0FZUxAEYgZwcm90bzM="));
+ "c19wZXJfY3EYESABKAUSGwoTbWVzc2FnZXNfcGVyX3N0cmVhbRgSIAEoBRIY",
+ "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIIjgKDENsaWVudFN0YXR1cxIoCgVz",
+ "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr",
+ "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy",
+ "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS",
+ "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2VydmVyQ29u",
+ "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl",
+ "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n",
+ "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy",
+ "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk",
+ "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK",
+ "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhYK",
+ "DnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3RhX3NpemUY",
+ "6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRlc3Rpbmcu",
+ "Q2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgLMhouZ3Jw",
+ "Yy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBj",
+ "LnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3RhdHVzEigK",
+ "BXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEgwKBHBv",
+ "cnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3QiHQoMQ29y",
+ "ZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNjZW5hcmlv",
+ "EgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIaLmdycGMu",
+ "dGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyABKAUSMQoN",
+ "c2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJDb25m",
+ "aWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29uZHMYBiAB",
+ "KAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25fbG9jYWxf",
+ "d29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2VuYXJpb3MY",
+ "ASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5hcmlvUmVz",
+ "dWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2ZXJfY29y",
+ "ZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQc2VydmVy",
+ "X3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUYBSABKAES",
+ "GAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUwGAcgASgB",
+ "EhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEoARISCgps",
+ "YXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgKEHNlcnZl",
+ "cl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0c19wZXJf",
+ "c2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vjb25kGA4g",
+ "ASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIgChhzZXJ2",
+ "ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1ZXJpZXNf",
+ "cGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVyX2NwdV9z",
+ "ZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlvGAEgASgL",
+ "MhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgCIAEoCzIb",
+ "LmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9zdGF0cxgD",
+ "IAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2ZXJfc3Rh",
+ "dHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoMc2VydmVy",
+ "X2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRlc3Rpbmcu",
+ "U2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNzGAcgAygI",
+ "EhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVzdWx0cxgJ",
+ "IAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQqQQoKQ2xp",
+ "ZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVOVBABEhAK",
+ "DE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQ",
+ "ABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhAC",
+ "EhAKDE9USEVSX1NFUlZFUhADKnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglT",
+ "VFJFQU1JTkcQARIZChVTVFJFQU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJF",
+ "QU1JTkdfRlJPTV9TRVJWRVIQAxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARi",
+ "BnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -106,7 +107,7 @@ namespace Grpc.Testing {
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride", "CredType" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
@@ -989,6 +990,7 @@ namespace Grpc.Testing {
channelArgs_ = other.channelArgs_.Clone();
threadsPerCq_ = other.threadsPerCq_;
messagesPerStream_ = other.messagesPerStream_;
+ useCoalesceApi_ = other.useCoalesceApi_;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1198,6 +1200,20 @@ namespace Grpc.Testing {
}
}
+ /// <summary>Field number for the "use_coalesce_api" field.</summary>
+ public const int UseCoalesceApiFieldNumber = 19;
+ private bool useCoalesceApi_;
+ /// <summary>
+ /// Use coalescing API when possible.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool UseCoalesceApi {
+ get { return useCoalesceApi_; }
+ set {
+ useCoalesceApi_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ClientConfig);
@@ -1227,6 +1243,7 @@ namespace Grpc.Testing {
if(!channelArgs_.Equals(other.channelArgs_)) return false;
if (ThreadsPerCq != other.ThreadsPerCq) return false;
if (MessagesPerStream != other.MessagesPerStream) return false;
+ if (UseCoalesceApi != other.UseCoalesceApi) return false;
return true;
}
@@ -1249,6 +1266,7 @@ namespace Grpc.Testing {
hash ^= channelArgs_.GetHashCode();
if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
if (MessagesPerStream != 0) hash ^= MessagesPerStream.GetHashCode();
+ if (UseCoalesceApi != false) hash ^= UseCoalesceApi.GetHashCode();
return hash;
}
@@ -1314,6 +1332,10 @@ namespace Grpc.Testing {
output.WriteRawTag(144, 1);
output.WriteInt32(MessagesPerStream);
}
+ if (UseCoalesceApi != false) {
+ output.WriteRawTag(152, 1);
+ output.WriteBool(UseCoalesceApi);
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1361,6 +1383,9 @@ namespace Grpc.Testing {
if (MessagesPerStream != 0) {
size += 2 + pb::CodedOutputStream.ComputeInt32Size(MessagesPerStream);
}
+ if (UseCoalesceApi != false) {
+ size += 2 + 1;
+ }
return size;
}
@@ -1423,6 +1448,9 @@ namespace Grpc.Testing {
if (other.MessagesPerStream != 0) {
MessagesPerStream = other.MessagesPerStream;
}
+ if (other.UseCoalesceApi != false) {
+ UseCoalesceApi = other.UseCoalesceApi;
+ }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1510,6 +1538,10 @@ namespace Grpc.Testing {
MessagesPerStream = input.ReadInt32();
break;
}
+ case 152: {
+ UseCoalesceApi = input.ReadBool();
+ break;
+ }
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index c02c9844e3..ba2107a576 100755
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -19,7 +19,7 @@
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="$(GoogleProtobufVersion)" />
<PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
- <PackageReference Include="Moq" Version="4.7.0" />
+ <PackageReference Include="Moq" Version="4.8.2" />
<PackageReference Include="NUnit" Version="3.6.0" />
<PackageReference Include="NUnitLite" Version="3.6.0" />
</ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index f71d6d197d..d18b9e7d5e 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -26,9 +26,6 @@
#pragma warning disable 1591
#region Designer generated code
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Grpc.Testing {
@@ -121,7 +118,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return GetAllGauges(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -144,7 +141,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return GetGauge(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -166,7 +163,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return GetGaugeAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index d2e4f2e4a5..46b328a773 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -22,9 +22,6 @@
#pragma warning disable 1591
#region Designer generated code
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Grpc.Testing {
@@ -177,7 +174,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -201,7 +198,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -225,7 +222,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StreamingCall(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -248,7 +245,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingFromClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StreamingFromClient(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -271,7 +268,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.SimpleResponse> StreamingFromServer(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StreamingFromServer(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -294,7 +291,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingBothWays(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StreamingBothWays(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -470,7 +467,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return RunServer(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -500,7 +497,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return RunClient(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -526,7 +523,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CoreCount(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -548,7 +545,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CoreCountAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -570,7 +567,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return QuitWorker(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -592,7 +589,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return QuitWorkerAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -692,7 +689,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Void ReportScenario(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return ReportScenario(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -714,7 +711,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Void> ReportScenarioAsync(global::Grpc.Testing.ScenarioResult request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return ReportScenarioAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index c0d147c150..6c4b77f7ac 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -23,9 +23,6 @@
#pragma warning disable 1591
#region Designer generated code
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Grpc.Testing {
@@ -244,7 +241,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return EmptyCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -266,7 +263,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return EmptyCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -288,7 +285,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -310,7 +307,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -334,7 +331,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.SimpleResponse CacheableUnaryCall(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CacheableUnaryCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -360,7 +357,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> CacheableUnaryCallAsync(global::Grpc.Testing.SimpleRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CacheableUnaryCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -385,7 +382,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StreamingOutputCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -408,7 +405,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StreamingInputCall(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -431,7 +428,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return FullDuplexCall(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -456,7 +453,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return HalfDuplexCall(new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -481,7 +478,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnimplementedCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -505,7 +502,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnimplementedCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -613,7 +610,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The response received from the server.</returns>
- public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnimplementedCall(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -635,7 +632,7 @@ namespace Grpc.Testing {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return UnimplementedCallAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -734,7 +731,7 @@ namespace Grpc.Testing {
{
}
- public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Start(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -742,7 +739,7 @@ namespace Grpc.Testing {
{
return CallInvoker.BlockingUnaryCall(__Method_Start, null, options, request);
}
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StartAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -750,7 +747,7 @@ namespace Grpc.Testing {
{
return CallInvoker.AsyncUnaryCall(__Method_Start, null, options, request);
}
- public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Stop(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
@@ -758,7 +755,7 @@ namespace Grpc.Testing {
{
return CallInvoker.BlockingUnaryCall(__Method_Stop, null, options, request);
}
- public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return StopAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index 0195186eba..e2263cfc90 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -22,9 +22,6 @@
#pragma warning disable 1591
#region Designer generated code
-using System;
-using System.Threading;
-using System.Threading.Tasks;
using grpc = global::Grpc.Core;
namespace Grpc.Reflection.V1Alpha {
@@ -97,7 +94,7 @@ namespace Grpc.Reflection.V1Alpha {
/// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
/// <param name="cancellationToken">An optional token for canceling the call.</param>
/// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ public virtual grpc::AsyncDuplexStreamingCall<global::Grpc.Reflection.V1Alpha.ServerReflectionRequest, global::Grpc.Reflection.V1Alpha.ServerReflectionResponse> ServerReflectionInfo(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return ServerReflectionInfo(new grpc::CallOptions(headers, deadline, cancellationToken));
}
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 4087d8b67a..4dd4947f00 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.10.0-dev
+set VERSION=1.11.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
index 8ccc537a60..e3f8463ee8 100755
--- a/src/csharp/build_packages_dotnetcli.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -39,7 +39,7 @@ dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
-nuget pack Grpc.nuspec -Version "1.10.0-dev" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.10.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.nuspec -Version "1.11.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.11.0-dev" -OutputDirectory ../../artifacts
(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index eb69b5829c..3e6ec474b7 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -16,8 +16,6 @@
*
*/
-#include "src/core/lib/gpr/string.h"
-
#include <grpc/byte_buffer_reader.h>
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
@@ -26,7 +24,7 @@
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
#include <string.h>
diff --git a/src/csharp/global.json b/src/csharp/global.json
index e4b797ee8e..815be4bfb9 100644
--- a/src/csharp/global.json
+++ b/src/csharp/global.json
@@ -1,5 +1,5 @@
{
"sdk": {
- "version": "1.0.0"
+ "version": "2.1.4"
}
}
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index 469328af1a..60f67ff3c9 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -1,5 +1,7 @@
{
"Grpc.Core.Tests": [
+ "Grpc.Core.Interceptors.Tests.ClientInterceptorTest",
+ "Grpc.Core.Interceptors.Tests.ServerInterceptorTest",
"Grpc.Core.Internal.Tests.AsyncCallServerTest",
"Grpc.Core.Internal.Tests.AsyncCallTest",
"Grpc.Core.Internal.Tests.ChannelArgsSafeHandleTest",
@@ -59,4 +61,4 @@
"Grpc.Reflection.Tests.ReflectionClientServerTest",
"Grpc.Reflection.Tests.SymbolRegistryTest"
]
-} \ No newline at end of file
+}
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index 037ad4d9b0..954beed8e1 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.10.0-dev'
+ v = '1.11.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/GRPCCall+MobileLog.h b/src/objective-c/GRPCClient/GRPCCall+MobileLog.h
new file mode 100644
index 0000000000..53b347d9ca
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCCall+MobileLog.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import "GRPCCall.h"
+
+@interface GRPCCall (MobileLog)
+// Set the object to be passed down along channel stack with channel arg
+// GRPC_ARG_MOBILE_LOG_CONFIG. The setting may be used by custom channel
+// filters for metrics logging.
++ (void)setLogConfig:(id)logConfig;
+
+// Obtain the object to be passed down along channel stack with channel arg
+// GRPC_ARG_MOBILE_LOG_CONFIG.
++ (id)logConfig;
+@end
diff --git a/src/objective-c/GRPCClient/GRPCCall+MobileLog.m b/src/objective-c/GRPCClient/GRPCCall+MobileLog.m
new file mode 100644
index 0000000000..4dedb7de8b
--- /dev/null
+++ b/src/objective-c/GRPCClient/GRPCCall+MobileLog.m
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import "GRPCCall+MobileLog.h"
+
+static id globalLogConfig = nil;
+
+@implementation GRPCCall (MobileLog)
+
++ (void)setLogConfig:(id)logConfig {
+ globalLogConfig = logConfig;
+}
+
++ (id)logConfig {
+ return globalLogConfig;
+}
+
+@end
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index ac4596da25..02492607cd 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -108,6 +108,9 @@ static NSString * const kBearerPrefix = @"Bearer ";
// The dispatch queue to be used for enqueuing responses to user. Defaulted to the main dispatch
// queue
dispatch_queue_t _responseQueue;
+
+ // Whether the call is finished. If it is, should not call finishWithError again.
+ BOOL _finished;
}
@synthesize state = _state;
@@ -206,6 +209,8 @@ static NSString * const kBearerPrefix = @"Bearer ";
} else {
[_responseWriteable enqueueSuccessfulCompletion];
}
+
+ [GRPCConnectivityMonitor unregisterObserver:self];
}
- (void)cancelCall {
@@ -214,9 +219,10 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
- (void)cancel {
- [self finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeCancelled
- userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
+ [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeCancelled
+ userInfo:@{NSLocalizedDescriptionKey: @"Canceled by app"}]];
+
if (!self.isWaitingForToken) {
[self cancelCall];
} else {
@@ -224,6 +230,19 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
}
+- (void)maybeFinishWithError:(NSError *)errorOrNil {
+ BOOL toFinish = NO;
+ @synchronized(self) {
+ if (_finished == NO) {
+ _finished = YES;
+ toFinish = YES;
+ }
+ }
+ if (toFinish == YES) {
+ [self finishWithError:errorOrNil];
+ }
+}
+
- (void)dealloc {
__block GRPCWrappedCall *wrappedCall = _wrappedCall;
dispatch_async(_callQueue, ^{
@@ -250,11 +269,13 @@ static NSString * const kBearerPrefix = @"Bearer ";
if (self.state == GRXWriterStatePaused) {
return;
}
- __weak GRPCCall *weakSelf = self;
- __weak GRXConcurrentWriteable *weakWriteable = _responseWriteable;
dispatch_async(_callQueue, ^{
- [weakSelf startReadWithHandler:^(grpc_byte_buffer *message) {
+ __weak GRPCCall *weakSelf = self;
+ __weak GRXConcurrentWriteable *weakWriteable = self->_responseWriteable;
+ [self startReadWithHandler:^(grpc_byte_buffer *message) {
+ __strong GRPCCall *strongSelf = weakSelf;
+ __strong GRXConcurrentWriteable *strongWriteable = weakWriteable;
if (message == NULL) {
// No more messages from the server
return;
@@ -266,14 +287,14 @@ static NSString * const kBearerPrefix = @"Bearer ";
// don't want to throw, because the app shouldn't crash for a behavior
// that's on the hands of any server to have. Instead we finish and ask
// the server to cancel.
- [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeResourceExhausted
- userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]];
- [weakSelf cancelCall];
+ [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeResourceExhausted
+ userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]];
+ [strongSelf cancelCall];
return;
}
- [weakWriteable enqueueValue:data completionHandler:^{
- [weakSelf startNextRead];
+ [strongWriteable enqueueValue:data completionHandler:^{
+ [strongSelf startNextRead];
}];
}];
});
@@ -333,12 +354,17 @@ static NSString * const kBearerPrefix = @"Bearer ";
_requestWriter.state = GRXWriterStatePaused;
}
- __weak GRPCCall *weakSelf = self;
dispatch_async(_callQueue, ^{
- [weakSelf writeMessage:value withErrorHandler:^{
- [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeInternal
- userInfo:nil]];
+ __weak GRPCCall *weakSelf = self;
+ [self writeMessage:value withErrorHandler:^{
+ __strong GRPCCall *strongSelf = weakSelf;
+ if (strongSelf != nil) {
+ [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeInternal
+ userInfo:nil]];
+ // Wrapped call must be canceled when error is reported to upper layers
+ [strongSelf cancelCall];
+ }
}];
});
}
@@ -360,12 +386,15 @@ static NSString * const kBearerPrefix = @"Bearer ";
if (errorOrNil) {
[self cancel];
} else {
- __weak GRPCCall *weakSelf = self;
dispatch_async(_callQueue, ^{
- [weakSelf finishRequestWithErrorHandler:^{
- [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeInternal
- userInfo:nil]];
+ __weak GRPCCall *weakSelf = self;
+ [self finishRequestWithErrorHandler:^{
+ __strong GRPCCall *strongSelf = weakSelf;
+ [strongSelf maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeInternal
+ userInfo:nil]];
+ // Wrapped call must be canceled when error is reported to upper layers
+ [strongSelf cancelCall];
}];
});
}
@@ -387,30 +416,37 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
- (void)invokeCall {
+ __weak GRPCCall *weakSelf = self;
[self invokeCallWithHeadersHandler:^(NSDictionary *headers) {
// Response headers received.
- self.responseHeaders = headers;
- [self startNextRead];
+ __strong GRPCCall *strongSelf = weakSelf;
+ if (strongSelf) {
+ strongSelf.responseHeaders = headers;
+ [strongSelf startNextRead];
+ }
} completionHandler:^(NSError *error, NSDictionary *trailers) {
- self.responseTrailers = trailers;
+ __strong GRPCCall *strongSelf = weakSelf;
+ if (strongSelf) {
+ strongSelf.responseTrailers = trailers;
- if (error) {
- NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
- if (error.userInfo) {
- [userInfo addEntriesFromDictionary:error.userInfo];
- }
- userInfo[kGRPCTrailersKey] = self.responseTrailers;
- // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be
- // called before this one, so an error might end up with trailers but no headers. We
- // shouldn't call finishWithError until ater both blocks are called. It is also when this is
- // done that we can provide a merged view of response headers and trailers in a thread-safe
- // way.
- if (self.responseHeaders) {
- userInfo[kGRPCHeadersKey] = self.responseHeaders;
+ if (error) {
+ NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
+ if (error.userInfo) {
+ [userInfo addEntriesFromDictionary:error.userInfo];
+ }
+ userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers;
+ // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be
+ // called before this one, so an error might end up with trailers but no headers. We
+ // shouldn't call finishWithError until ater both blocks are called. It is also when this is
+ // done that we can provide a merged view of response headers and trailers in a thread-safe
+ // way.
+ if (strongSelf.responseHeaders) {
+ userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders;
+ }
+ error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
}
- error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo];
+ [strongSelf maybeFinishWithError:error];
}
- [self finishWithError:error];
}];
// Now that the RPC has been initiated, request writes can start.
@synchronized(_requestWriter) {
@@ -439,16 +475,8 @@ static NSString * const kBearerPrefix = @"Bearer ";
// TODO(jcanizales): Check this on init.
[NSException raise:NSInvalidArgumentException format:@"host of %@ is nil", _host];
}
- _connectivityMonitor = [GRPCConnectivityMonitor monitorWithHost:host];
- __weak typeof(self) weakSelf = self;
- void (^handler)(void) = ^{
- typeof(self) strongSelf = weakSelf;
- [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain
- code:GRPCErrorCodeUnavailable
- userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
- };
- [_connectivityMonitor handleLossWithHandler:handler
- wifiStatusChangeHandler:nil];
+ [GRPCConnectivityMonitor registerObserver:self
+ selector:@selector(connectivityChanged:)];
}
- (void)startWithWriteable:(id<GRXWriteable>)writeable {
@@ -512,4 +540,12 @@ static NSString * const kBearerPrefix = @"Bearer ";
}
}
+- (void)connectivityChanged:(NSNotification *)note {
+ [self maybeFinishWithError:[NSError errorWithDomain:kGRPCErrorDomain
+ code:GRPCErrorCodeUnavailable
+ userInfo:@{ NSLocalizedDescriptionKey : @"Connectivity lost." }]];
+ // Cancel underlying call upon this notification
+ [self cancelCall];
+}
+
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m
index 26efe90abd..b53d84159d 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -32,6 +32,24 @@
#endif
#import "GRPCCompletionQueue.h"
+static void* copy_pointer_arg(void *p) {
+ // Add ref count to the object when making copy
+ id obj = (__bridge id)p;
+ return (__bridge_retained void *)obj;
+}
+
+static void destroy_pointer_arg(void *p) {
+ // Decrease ref count to the object when destroying
+ CFRelease((CFTreeRef)p);
+}
+
+static int cmp_pointer_arg(void *p, void *q) {
+ return p == q;
+}
+
+static const grpc_arg_pointer_vtable objc_arg_vtable = {
+ copy_pointer_arg, destroy_pointer_arg, cmp_pointer_arg};
+
static void FreeChannelArgs(grpc_channel_args *channel_args) {
for (size_t i = 0; i < channel_args->num_args; ++i) {
grpc_arg *arg = &channel_args->args[i];
@@ -75,6 +93,10 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
} else if ([value respondsToSelector:@selector(intValue)]) {
arg->type = GRPC_ARG_INTEGER;
arg->value.integer = [value intValue];
+ } else if (value != nil) {
+ arg->type = GRPC_ARG_POINTER;
+ arg->value.pointer.p = (__bridge_retained void *)value;
+ arg->value.pointer.vtable = &objc_arg_vtable;
} else {
[NSException raise:NSInvalidArgumentException
format:@"Invalid value type: %@", [value class]];
@@ -188,8 +210,7 @@ static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) {
if (timeout < 0) {
timeout = 0;
}
- grpc_slice host_slice;
- memset(&host_slice, 0, sizeof(host_slice));
+ grpc_slice host_slice = grpc_empty_slice();
if (serverName) {
host_slice = grpc_slice_from_copied_string(serverName.UTF8String);
}
diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
index cb55e46d70..394d21792d 100644
--- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
+++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.h
@@ -19,44 +19,30 @@
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
-@interface GRPCReachabilityFlags : NSObject
-
-+ (nonnull instancetype)flagsWithFlags:(SCNetworkReachabilityFlags)flags;
-
-/**
- * One accessor method to query each of the different flags. Example:
-
-@property(nonatomic, readonly) BOOL isCell;
-
- */
-#define GRPC_XMACRO_ITEM(methodName, FlagName) \
-@property(nonatomic, readonly) BOOL methodName;
-
-#include "GRPCReachabilityFlagNames.xmacro.h"
-#undef GRPC_XMACRO_ITEM
-
-@property(nonatomic, readonly) BOOL isHostReachable;
-@end
-
+typedef NS_ENUM(NSInteger, GRPCConnectivityStatus) {
+ GRPCConnectivityUnknown = 0,
+ GRPCConnectivityNoNetwork = 1,
+ GRPCConnectivityCellular = 2,
+ GRPCConnectivityWiFi = 3,
+};
+
+extern NSString * _Nonnull kGRPCConnectivityNotification;
+
+// This interface monitors OS reachability interface for any network status
+// change. Parties interested in these events should register themselves as
+// observer.
@interface GRPCConnectivityMonitor : NSObject
-+ (nullable instancetype)monitorWithHost:(nonnull NSString *)hostName;
-
- (nonnull instancetype)init NS_UNAVAILABLE;
-/**
- * Queue on which callbacks will be dispatched. Default is the main queue. Set it before calling
- * handleLossWithHandler:.
- */
-// TODO(jcanizales): Default to a serial background queue instead.
-@property(nonatomic, strong, null_resettable) dispatch_queue_t queue;
-
-/**
- * Calls handler every time the connectivity to this instance's host is lost. If this instance is
- * released before that happens, the handler won't be called.
- * Only one handler is active at a time, so if this method is called again before the previous
- * handler has been called, it might never be called at all (or yes, if it has already been queued).
- */
-- (void)handleLossWithHandler:(nullable void (^)(void))lossHandler
- wifiStatusChangeHandler:(nullable void (^)(void))wifiStatusChangeHandler;
+// Register an object as observer of network status change. \a observer
+// must have a notification method with one parameter of type
+// (NSNotification *) and should pass it to parameter \a selector. The
+// parameter of this notification method is not used for now.
++ (void)registerObserver:(_Nonnull id)observer
+ selector:(_Nonnull SEL)selector;
+
+// Ungegister an object from observers of network status change.
++ (void)unregisterObserver:(_Nonnull id)observer;
+
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
index c8e10dd75f..7f31c7e23e 100644
--- a/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
+++ b/src/objective-c/GRPCClient/private/GRPCConnectivityMonitor.m
@@ -18,175 +18,74 @@
#import "GRPCConnectivityMonitor.h"
-#pragma mark Flags
+#include <netinet/in.h>
-@implementation GRPCReachabilityFlags {
- SCNetworkReachabilityFlags _flags;
-}
+NSString *kGRPCConnectivityNotification = @"kGRPCConnectivityNotification";
-+ (instancetype)flagsWithFlags:(SCNetworkReachabilityFlags)flags {
- return [[self alloc] initWithFlags:flags];
-}
+static SCNetworkReachabilityRef reachability;
+static GRPCConnectivityStatus currentStatus;
-- (instancetype)initWithFlags:(SCNetworkReachabilityFlags)flags {
- if ((self = [super init])) {
- _flags = flags;
+// Aggregate information in flags into network status.
+GRPCConnectivityStatus CalculateConnectivityStatus(SCNetworkReachabilityFlags flags) {
+ GRPCConnectivityStatus result = GRPCConnectivityUnknown;
+ if (((flags & kSCNetworkReachabilityFlagsReachable) == 0) ||
+ ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0)) {
+ return GRPCConnectivityNoNetwork;
}
- return self;
-}
-
-/*
- * One accessor method implementation per flag. Example:
-
-- (BOOL)isCell { \
- return !!(_flags & kSCNetworkReachabilityFlagsIsWWAN); \
-}
-
- */
-#define GRPC_XMACRO_ITEM(methodName, FlagName) \
-- (BOOL)methodName { \
- return !!(_flags & kSCNetworkReachabilityFlags ## FlagName); \
-}
-#include "GRPCReachabilityFlagNames.xmacro.h"
-#undef GRPC_XMACRO_ITEM
-
-- (BOOL)isHostReachable {
- // Note: connectionOnDemand means it'll be reachable only if using the CFSocketStream API or APIs
- // on top of it.
- // connectionRequired means we can't tell until a connection is attempted (e.g. for VPN on
- // demand).
- return self.reachable && !self.interventionRequired && !self.connectionOnDemand;
-}
-
-- (NSString *)description {
- NSMutableArray *activeOptions = [NSMutableArray arrayWithCapacity:9];
-
- /*
- * For each flag, add its name to the array if it's ON. Example:
-
- if (self.isCell) {
- [activeOptions addObject:@"isCell"];
+ result = GRPCConnectivityWiFi;
+#if TARGET_OS_IPHONE
+ if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
+ return result = GRPCConnectivityCellular;
}
-
- */
- #define GRPC_XMACRO_ITEM(methodName, FlagName) \
- if (self.methodName) { \
- [activeOptions addObject:@ #methodName]; \
- }
- #include "GRPCReachabilityFlagNames.xmacro.h"
- #undef GRPC_XMACRO_ITEM
-
- return activeOptions.count == 0 ? @"(none)" : [activeOptions componentsJoinedByString:@", "];
-}
-
-- (BOOL)isEqual:(id)object {
- return [object isKindOfClass:[GRPCReachabilityFlags class]] &&
- _flags == ((GRPCReachabilityFlags *)object)->_flags;
-}
-
-- (NSUInteger)hash {
- return _flags;
-}
-@end
-
-#pragma mark Connectivity Monitor
-
-// Assumes the third argument is a block that accepts a GRPCReachabilityFlags object, and passes the
-// received ones to it.
-static void PassFlagsToContextInfoBlock(SCNetworkReachabilityRef target,
- SCNetworkReachabilityFlags flags,
- void *info) {
- #pragma unused (target)
- // This can be called many times with the same info. The info is retained by SCNetworkReachability
- // while this function is being executed.
- void (^handler)(GRPCReachabilityFlags *) = (__bridge void (^)(GRPCReachabilityFlags *))info;
- handler([[GRPCReachabilityFlags alloc] initWithFlags:flags]);
+#endif
+ return result;
}
-@implementation GRPCConnectivityMonitor {
- SCNetworkReachabilityRef _reachabilityRef;
- GRPCReachabilityFlags *_previousReachabilityFlags;
-}
+static void ReachabilityCallback(
+ SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
+ GRPCConnectivityStatus newStatus = CalculateConnectivityStatus(flags);
-- (nullable instancetype)initWithReachability:(nullable SCNetworkReachabilityRef)reachability {
- if (!reachability) {
- return nil;
+ if (newStatus != currentStatus) {
+ [[NSNotificationCenter defaultCenter] postNotificationName:kGRPCConnectivityNotification
+ object:nil];
+ currentStatus = newStatus;
}
- if ((self = [super init])) {
- _reachabilityRef = CFRetain(reachability);
- _queue = dispatch_get_main_queue();
- _previousReachabilityFlags = nil;
- }
- return self;
}
-+ (nullable instancetype)monitorWithHost:(nonnull NSString *)host {
- const char *hostName = host.UTF8String;
- if (!hostName) {
- [NSException raise:NSInvalidArgumentException
- format:@"host.UTF8String returns NULL for %@", host];
- }
- SCNetworkReachabilityRef reachability =
- SCNetworkReachabilityCreateWithName(NULL, hostName);
+@implementation GRPCConnectivityMonitor
- GRPCConnectivityMonitor *returnValue = [[self alloc] initWithReachability:reachability];
- if (reachability) {
- CFRelease(reachability);
- }
- return returnValue;
-}
++ (void)initialize {
+ if (self == [GRPCConnectivityMonitor self]) {
+ struct sockaddr_in addr = {0};
+ addr.sin_len = sizeof(addr);
+ addr.sin_family = AF_INET;
+ reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&addr);
+ currentStatus = GRPCConnectivityUnknown;
-- (void)handleLossWithHandler:(nullable void (^)(void))lossHandler
- wifiStatusChangeHandler:(nullable void (^)(void))wifiStatusChangeHandler {
- __weak typeof(self) weakSelf = self;
- [self startListeningWithHandler:^(GRPCReachabilityFlags *flags) {
- typeof(self) strongSelf = weakSelf;
- if (strongSelf) {
- if (lossHandler && !flags.reachable) {
- lossHandler();
-#if TARGET_OS_IPHONE
- } else if (wifiStatusChangeHandler &&
- strongSelf->_previousReachabilityFlags &&
- (flags.isWWAN ^
- strongSelf->_previousReachabilityFlags.isWWAN)) {
- wifiStatusChangeHandler();
-#endif
- }
- strongSelf->_previousReachabilityFlags = flags;
+ SCNetworkConnectionFlags flags;
+ if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
+ currentStatus = CalculateConnectivityStatus(flags);
}
- }];
-}
-- (void)startListeningWithHandler:(void (^)(GRPCReachabilityFlags *))handler {
- // Copy to ensure the handler block is in the heap (and so can't be deallocated when this method
- // returns).
- void (^copiedHandler)(GRPCReachabilityFlags *) = [handler copy];
- SCNetworkReachabilityContext context = {
- .version = 0,
- .info = (__bridge void *)copiedHandler,
- .retain = CFRetain,
- .release = CFRelease,
- };
- // The following will retain context.info, and release it when the callback is set to NULL.
- SCNetworkReachabilitySetCallback(_reachabilityRef, PassFlagsToContextInfoBlock, &context);
- SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _queue);
-}
-
-- (void)stopListening {
- // This releases the block on context.info.
- SCNetworkReachabilitySetCallback(_reachabilityRef, NULL, NULL);
- SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, NULL);
+ SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
+ if (!SCNetworkReachabilitySetCallback(reachability, ReachabilityCallback, &context) ||
+ !SCNetworkReachabilityScheduleWithRunLoop(
+ reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)) {
+ NSLog(@"gRPC connectivity monitor fail to set");
+ }
+ }
}
-- (void)setQueue:(dispatch_queue_t)queue {
- _queue = queue ?: dispatch_get_main_queue();
++ (void)registerObserver:(_Nonnull id)observer
+ selector:(SEL)selector {
+ [[NSNotificationCenter defaultCenter] addObserver:observer
+ selector:selector
+ name:kGRPCConnectivityNotification
+ object:nil];
}
-- (void)dealloc {
- if (_reachabilityRef) {
- [self stopListening];
- CFRelease(_reachabilityRef);
- }
++ (void)unregisterObserver:(_Nonnull id)observer {
+ [[NSNotificationCenter defaultCenter] removeObserver:observer];
}
@end
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index ceae9607d7..8568e334dd 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -21,6 +21,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#import <GRPCClient/GRPCCall.h>
+#import <GRPCClient/GRPCCall+MobileLog.h>
#ifdef GRPC_COMPILE_WITH_CRONET
#import <GRPCClient/GRPCCall+ChannelArg.h>
#import <GRPCClient/GRPCCall+Cronet.h>
@@ -36,12 +37,6 @@ NS_ASSUME_NONNULL_BEGIN
static NSMutableDictionary *kHostCache;
-// This connectivity monitor flushes the host cache when connectivity status
-// changes or when connection switch between Wifi and Cellular data, so that a
-// new call will use a new channel. Otherwise, a new call will still use the
-// cached channel which is no longer available and will cause gRPC to hang.
-static GRPCConnectivityMonitor *connectivityMonitor = nil;
-
@implementation GRPCHost {
// TODO(mlumish): Investigate whether caching channels with strong links is a good idea.
GRPCChannel *_channel;
@@ -89,17 +84,7 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
kHostCache[address] = self;
_compressAlgorithm = GRPC_COMPRESS_NONE;
}
- // Keep a single monitor to flush the cache if the connectivity status changes
- // Thread safety guarded by @synchronized(kHostCache)
- if (!connectivityMonitor) {
- connectivityMonitor =
- [GRPCConnectivityMonitor monitorWithHost:hostURL.host];
- void (^handler)(void) = ^{
- [GRPCHost flushChannelCache];
- };
- [connectivityMonitor handleLossWithHandler:handler
- wifiStatusChangeHandler:handler];
- }
+ [GRPCConnectivityMonitor registerObserver:self selector:@selector(connectivityChange:)];
}
return self;
}
@@ -231,6 +216,11 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
[NSNumber numberWithInt:_compressAlgorithm];
}
+ id logConfig = [GRPCCall logConfig];
+ if (logConfig != nil) {
+ args[@GRPC_ARG_MOBILE_LOG_CONFIG] = logConfig;
+ }
+
return args;
}
@@ -275,6 +265,13 @@ static GRPCConnectivityMonitor *connectivityMonitor = nil;
}
}
+// Flushes the host cache when connectivity status changes or when connection switch between Wifi
+// and Cellular data, so that a new call will use a new channel. Otherwise, a new call will still
+// use the cached channel which is no longer available and will cause gRPC to hang.
+- (void)connectivityChange:(NSNotification *)note {
+ [GRPCHost flushChannelCache];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index 5c134e3642..405c2fff9f 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -23,4 +23,4 @@
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.10.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.11.0-dev"
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
index d91b5cf99e..33ccdb5844 100644
--- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
+++ b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.mm
@@ -224,8 +224,7 @@ static char *roots_filename;
}
- (void)testBinaryMetadata {
- // NOT SUPPORTED
- //[self testIndividualCase:(char *)"binary_metadata"];
+ [self testIndividualCase:(char *)"binary_metadata"];
}
- (void)testCallCreds {
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index 5140aa23a6..6f6cd25007 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -23,5 +23,5 @@
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.10.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.11.0-dev"
#define GRPC_C_VERSION_STRING @"6.0.0-dev"
diff --git a/src/php/composer.json b/src/php/composer.json
index ea21417956..dbf0cc35fd 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.10.0",
+ "version": "1.11.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 408f2a4765..dd2a701ada 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.10.0dev"
+#define PHP_GRPC_VERSION "1.11.0dev"
#endif /* VERSION_H */
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 79793a710e..7fa7303691 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -173,7 +173,8 @@ class Future(six.with_metaclass(abc.ABCMeta)):
"""Adds a function to be called at completion of the computation.
The callback will be passed this Future object describing the outcome
- of the computation.
+ of the computation. Callbacks will be invoked after the future is
+ terimated, whether successfully or not.
If the computation has already completed, the callback will be called
immediately.
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 6032828c77..4a69d859fc 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.10.0.dev0"""
+__version__ = """1.11.0.dev0"""
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index ae77466c36..581bc0f011 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -158,7 +158,6 @@ CORE_SOURCE_FILES = [
'src/core/lib/slice/percent_encoding.cc',
'src/core/lib/slice/slice.cc',
'src/core/lib/slice/slice_buffer.cc',
- 'src/core/lib/slice/slice_hash_table.cc',
'src/core/lib/slice/slice_intern.cc',
'src/core/lib/slice/slice_string_helpers.cc',
'src/core/lib/surface/api_trace.cc',
@@ -189,6 +188,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/transport/service_config.cc',
'src/core/lib/transport/static_metadata.cc',
'src/core/lib/transport/status_conversion.cc',
+ 'src/core/lib/transport/status_metadata.cc',
'src/core/lib/transport/timeout_encoding.cc',
'src/core/lib/transport/transport.cc',
'src/core/lib/transport/transport_op_string.cc',
@@ -236,12 +236,12 @@ CORE_SOURCE_FILES = [
'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc',
'src/core/lib/security/credentials/plugin/plugin_credentials.cc',
'src/core/lib/security/credentials/ssl/ssl_credentials.cc',
+ 'src/core/lib/security/security_connector/security_connector.cc',
'src/core/lib/security/transport/client_auth_filter.cc',
- 'src/core/lib/security/transport/lb_targets_info.cc',
'src/core/lib/security/transport/secure_endpoint.cc',
- 'src/core/lib/security/transport/security_connector.cc',
'src/core/lib/security/transport/security_handshaker.cc',
'src/core/lib/security/transport/server_auth_filter.cc',
+ 'src/core/lib/security/transport/target_authority_table.cc',
'src/core/lib/security/transport/tsi_error.cc',
'src/core/lib/security/util/json_util.cc',
'src/core/lib/surface/init_secure.cc',
@@ -264,12 +264,14 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
+ 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/status_util.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/client_channel/uri_parser.cc',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index a654eb026a..32e82493f3 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION = '1.10.0.dev0'
+VERSION = '1.11.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index d3185c6972..ad4c85cc12 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION = '1.10.0.dev0'
+VERSION = '1.11.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index 7203d0d321..6322d847b1 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION = '1.10.0.dev0'
+VERSION = '1.11.0.dev0'
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index bf9e55e10e..1e75fea12e 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
-VERSION = '1.10.0.dev0'
+VERSION = '1.11.0.dev0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index 2583e42016..0cd7bd257f 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION = '1.10.0.dev0'
+VERSION = '1.11.0.dev0'
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 38e085ef25..c045480ff4 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -234,14 +234,7 @@ gpr_ref_is_unique_type gpr_ref_is_unique_import;
gpr_stats_init_type gpr_stats_init_import;
gpr_stats_inc_type gpr_stats_inc_import;
gpr_stats_read_type gpr_stats_read_import;
-gpr_thd_new_type gpr_thd_new_import;
-gpr_thd_options_default_type gpr_thd_options_default_import;
-gpr_thd_options_set_detached_type gpr_thd_options_set_detached_import;
-gpr_thd_options_set_joinable_type gpr_thd_options_set_joinable_import;
-gpr_thd_options_is_detached_type gpr_thd_options_is_detached_import;
-gpr_thd_options_is_joinable_type gpr_thd_options_is_joinable_import;
gpr_thd_currentid_type gpr_thd_currentid_import;
-gpr_thd_join_type gpr_thd_join_import;
gpr_time_0_type gpr_time_0_import;
gpr_inf_future_type gpr_inf_future_import;
gpr_inf_past_type gpr_inf_past_import;
@@ -477,14 +470,7 @@ void grpc_rb_load_imports(HMODULE library) {
gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
gpr_stats_inc_import = (gpr_stats_inc_type) GetProcAddress(library, "gpr_stats_inc");
gpr_stats_read_import = (gpr_stats_read_type) GetProcAddress(library, "gpr_stats_read");
- gpr_thd_new_import = (gpr_thd_new_type) GetProcAddress(library, "gpr_thd_new");
- gpr_thd_options_default_import = (gpr_thd_options_default_type) GetProcAddress(library, "gpr_thd_options_default");
- gpr_thd_options_set_detached_import = (gpr_thd_options_set_detached_type) GetProcAddress(library, "gpr_thd_options_set_detached");
- gpr_thd_options_set_joinable_import = (gpr_thd_options_set_joinable_type) GetProcAddress(library, "gpr_thd_options_set_joinable");
- gpr_thd_options_is_detached_import = (gpr_thd_options_is_detached_type) GetProcAddress(library, "gpr_thd_options_is_detached");
- gpr_thd_options_is_joinable_import = (gpr_thd_options_is_joinable_type) GetProcAddress(library, "gpr_thd_options_is_joinable");
gpr_thd_currentid_import = (gpr_thd_currentid_type) GetProcAddress(library, "gpr_thd_currentid");
- gpr_thd_join_import = (gpr_thd_join_type) GetProcAddress(library, "gpr_thd_join");
gpr_time_0_import = (gpr_time_0_type) GetProcAddress(library, "gpr_time_0");
gpr_inf_future_import = (gpr_inf_future_type) GetProcAddress(library, "gpr_inf_future");
gpr_inf_past_import = (gpr_inf_past_type) GetProcAddress(library, "gpr_inf_past");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 9eb0a3f372..4f07452c68 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -38,7 +38,7 @@
#include <grpc/support/log_windows.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
#include <grpc/support/time.h>
typedef int(*grpc_compression_algorithm_is_message_type)(grpc_compression_algorithm algorithm);
@@ -677,30 +677,9 @@ extern gpr_stats_inc_type gpr_stats_inc_import;
typedef intptr_t(*gpr_stats_read_type)(const gpr_stats_counter* c);
extern gpr_stats_read_type gpr_stats_read_import;
#define gpr_stats_read gpr_stats_read_import
-typedef int(*gpr_thd_new_type)(gpr_thd_id* t, const char* thd_name, void (*thd_body)(void* arg), void* arg, const gpr_thd_options* options);
-extern gpr_thd_new_type gpr_thd_new_import;
-#define gpr_thd_new gpr_thd_new_import
-typedef gpr_thd_options(*gpr_thd_options_default_type)(void);
-extern gpr_thd_options_default_type gpr_thd_options_default_import;
-#define gpr_thd_options_default gpr_thd_options_default_import
-typedef void(*gpr_thd_options_set_detached_type)(gpr_thd_options* options);
-extern gpr_thd_options_set_detached_type gpr_thd_options_set_detached_import;
-#define gpr_thd_options_set_detached gpr_thd_options_set_detached_import
-typedef void(*gpr_thd_options_set_joinable_type)(gpr_thd_options* options);
-extern gpr_thd_options_set_joinable_type gpr_thd_options_set_joinable_import;
-#define gpr_thd_options_set_joinable gpr_thd_options_set_joinable_import
-typedef int(*gpr_thd_options_is_detached_type)(const gpr_thd_options* options);
-extern gpr_thd_options_is_detached_type gpr_thd_options_is_detached_import;
-#define gpr_thd_options_is_detached gpr_thd_options_is_detached_import
-typedef int(*gpr_thd_options_is_joinable_type)(const gpr_thd_options* options);
-extern gpr_thd_options_is_joinable_type gpr_thd_options_is_joinable_import;
-#define gpr_thd_options_is_joinable gpr_thd_options_is_joinable_import
typedef gpr_thd_id(*gpr_thd_currentid_type)(void);
extern gpr_thd_currentid_type gpr_thd_currentid_import;
#define gpr_thd_currentid gpr_thd_currentid_import
-typedef void(*gpr_thd_join_type)(gpr_thd_id t);
-extern gpr_thd_join_type gpr_thd_join_import;
-#define gpr_thd_join gpr_thd_join_import
typedef gpr_timespec(*gpr_time_0_type)(gpr_clock_type type);
extern gpr_time_0_type gpr_time_0_import;
#define gpr_time_0 gpr_time_0_import
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 9d9f2f4968..256a543a9f 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.10.0.dev'
+ VERSION = '1.11.0.dev'
end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 2682294bd2..8dc1623d6f 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.10.0.dev'
+ VERSION = '1.11.0.dev'
end
end
diff --git a/summerofcode/ideas.md b/summerofcode/ideas.md
index d89bc372cc..de59be82c2 100644
--- a/summerofcode/ideas.md
+++ b/summerofcode/ideas.md
@@ -29,8 +29,8 @@ gRPC Python:
1. Support static type-checking of both gRPC Python itself and of code that uses gRPC Python. No one likes dynamic typing and Python is finally outgrowing it! There are probably errors in the implementation of gRPC Python that [pytype](https://github.com/google/pytype) or [mypy](http://mypy-lang.org/) could detect. There are certainly errors in other code that uses gRPC Python that they could detect.
* **Required skills:** Python programming language, open source development across multiple repositories and projects.
- * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Kailash Sethuraman](https://github.com/hsaliak), [Ken Payson](https://github.com/kpayson64), [Mehrdad Afshari](https://github.com/mehrdada).
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Kailash Sethuraman](https://github.com/hsaliak).
1. [Enable building of gRPC Python with Bazel](https://github.com/grpc/grpc/issues/8079). Bazel is the designated replacement for our constellation of crufty build scripts, but it's still under active development itself. Up for a challenge? gRPC Python could easily be the most complex codebase to be built with Bazel.
* **Required skills:** Python programming language, Bazel toolchain, Cython, open source development across multiple repositories and projects.
- * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Ken Payson](https://github.com/kpayson64), [Mehrdad Afshari](https://github.com/mehrdada).
+ * **Likely mentors:** [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle).
diff --git a/templates/Makefile.template b/templates/Makefile.template
index b8e26b646b..390847b4f2 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1378,6 +1378,11 @@
% endif
% endfor
+ install-grpc-cli: grpc_cli
+ $(E) "[INSTALL] Installing grpc cli"
+ $(Q) $(INSTALL) -d $(prefix)/bin
+ $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cli $(prefix)/bin/grpc_cli
+
install-pkg-config_c: pc_c pc_c_unsecure
$(E) "[INSTALL] Installing C pkg-config files"
$(Q) $(INSTALL) -d $(prefix)/lib/pkgconfig
diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template
index 78adb27915..12d5fc17d4 100644
--- a/templates/gRPC-C++.podspec.template
+++ b/templates/gRPC-C++.podspec.template
@@ -30,6 +30,9 @@
out += lib.get(group, [])
return out
+ def filter_grpcpp(files):
+ return [file for file in files if not file.startswith("include/grpc++")]
+
def grpc_private_files(libs):
out = grpc_lib_files(libs, ("grpc", "gpr"), ("headers", "src"))
return out
@@ -59,6 +62,9 @@
# Since some C++ source files directly included private headers in C core, we include all the
# C core headers in C++ Implementation subspec as well.
out += [file for file in grpc_private_headers(libs) if not file.startswith("third_party/nanopb/")]
+
+ out = filter_grpcpp(out)
+
return out
def grpcpp_private_headers(libs, filegroups):
@@ -71,6 +77,8 @@
# Since some C++ source files directly included private headers in C core, we intentionally
# keep the C core headers in \a out. But we should exclude nanopb headers.
out = [file for file in out if not file.startswith("third_party/nanopb/")]
+
+ out = filter_grpcpp(out)
return out
def grpcpp_public_headers(libs, filegroups):
@@ -81,6 +89,9 @@
excl_files += grpcpp_proto_files(filegroups)
out = [file for file in out if file not in excl_files]
+
+ out = filter_grpcpp(out)
+
return out
def grpc_test_util_files(libs):
@@ -91,6 +102,8 @@
out = grpc_lib_files(libs, ("grpc_test_util", "gpr_test_util"), ("headers",))
return out
+ # Tests subspec is currently disabled since the tests currently use `grpc++` include style instead of `grpcpp`.
+ # TODO (mxyan): enable Tests subspec after the inclusion style is updated in `test/` directory.
def grpcpp_test_util_files(libs, filegroups):
out = grpc_lib_files(libs, ("grpc++_test_util",), ("src", "headers"))
excl_files = grpc_test_util_files(libs) + grpcpp_private_files(libs, filegroups)
@@ -118,7 +131,7 @@
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '${settings.version}'
- version = '0.0.1'
+ version = '0.0.2'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
@@ -136,8 +149,14 @@
s.osx.deployment_target = '10.9'
s.requires_arc = false
- # Add include prefix `grpc++` (i.e. `#include <grpc++/xxx.h>`).
- s.header_dir = 'grpc++'
+ name = 'grpcpp'
+ # Use `grpcpp` as framework name so that `#include <grpcpp/xxx.h>` works when built as
+ # framework.
+ s.module_name = name
+
+ # Add include prefix `grpcpp` so that `#include <grpcpp/xxx.h>` works when built as static
+ # library.
+ s.header_dir = name
s.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => '"$(inherited)" "$(PODS_TARGET_SRCROOT)/include"',
@@ -157,8 +176,10 @@
s.default_subspecs = 'Interface', 'Implementation'
+ s.header_mappings_dir = 'include/grpcpp'
+
s.subspec 'Interface' do |ss|
- ss.header_mappings_dir = 'include/grpc++'
+ ss.header_mappings_dir = 'include/grpcpp'
ss.source_files = ${ruby_multiline_list(grpcpp_public_headers(libs, filegroups), 22)}
end
@@ -174,16 +195,6 @@
ss.private_header_files = ${ruby_multiline_list(grpcpp_private_headers(libs, filegroups), 30)}
end
- s.subspec 'Tests' do |ss|
- ss.header_mappings_dir = '.'
-
- ss.dependency "#{s.name}/Interface", version
- ss.dependency "#{s.name}/Implementation", version
- ss.dependency "gRPC-Core/Tests", grpc_version
-
- ss.source_files = ${ruby_multiline_list(grpcpp_test_util_files(libs, filegroups), 22)}
- end
-
s.prepare_command = <<-END_OF_COMMAND
find src/cpp/ -type f -exec sed -E -i'.back' 's;#include "third_party/nanopb/(.*)";#include <nanopb/\\1>;g' {} \\\;
find src/cpp/ -name "*.back" -type f -delete
diff --git a/templates/src/core/lib/surface/version.cc.template b/templates/src/core/lib/surface/version.cc.template
index d9fa4479db..0cb3154725 100644
--- a/templates/src/core/lib/surface/version.cc.template
+++ b/templates/src/core/lib/surface/version.cc.template
@@ -21,6 +21,8 @@
/* This file is autogenerated from:
templates/src/core/surface/version.c.template */
+ #include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
const char* grpc_version_string(void) { return "${settings.core_version}"; }
diff --git a/templates/src/core/plugin_registry.template b/templates/src/core/plugin_registry.template
index 805ae9049f..a00d204a46 100644
--- a/templates/src/core/plugin_registry.template
+++ b/templates/src/core/plugin_registry.template
@@ -22,6 +22,8 @@ template: |
*
*/
+ #include <grpc/support/port_platform.h>
+
#include <grpc/grpc.h>
%for plugin in selected.plugins:
diff --git a/templates/src/cpp/common/version_cc.cc.template b/templates/src/cpp/common/version_cc.cc.template
index 9882878727..a3b0cf69a5 100644
--- a/templates/src/cpp/common/version_cc.cc.template
+++ b/templates/src/cpp/common/version_cc.cc.template
@@ -21,7 +21,7 @@
/* This file is autogenerated from:
templates/src/core/surface/version.c.template */
- #include <grpc++/grpc++.h>
+ #include <grpcpp/grpcpp.h>
namespace grpc {
grpc::string Version() { return "${settings.cpp_version}"; }
diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template
index 7453e6c460..69bb7c4671 100644
--- a/templates/tools/dockerfile/test/sanity/Dockerfile.template
+++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template
@@ -46,12 +46,12 @@
RUN apt-get -y update
RUN apt-get -y install bazel
- # Pin Bazel to 0.4.4
- # Installing Bazel via apt-get first is required before installing 0.4.4 to
+ # Pin Bazel to 0.9.0
+ # Installing Bazel via apt-get first is required before installing 0.9.0 to
# allow gRPC to build without errors. See https://github.com/grpc/grpc/issues/10553
- RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.4.4/bazel-0.4.4-installer-linux-x86_64.sh
- RUN chmod +x ./bazel-0.4.4-installer-linux-x86_64.sh
- RUN ./bazel-0.4.4-installer-linux-x86_64.sh
+ RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.9.0/bazel-0.9.0-installer-linux-x86_64.sh
+ RUN chmod +x ./bazel-0.9.0-installer-linux-x86_64.sh
+ RUN ./bazel-0.9.0-installer-linux-x86_64.sh
<%include file="../../clang5.include"/>
<%include file="../../run_tests_addons.include"/>
diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc
index ee55a95e4e..6055ccbf4b 100644
--- a/test/core/bad_client/bad_client.cc
+++ b/test/core/bad_client/bad_client.cc
@@ -23,13 +23,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/gpr/murmur_hash.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/surface/completion_queue.h"
diff --git a/test/core/bad_ssl/generate_tests.bzl b/test/core/bad_ssl/generate_tests.bzl
index 3cf7fd7b4e..22e7d3a692 100755
--- a/test/core/bad_ssl/generate_tests.bzl
+++ b/test/core/bad_ssl/generate_tests.bzl
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary")
def test_options():
return struct()
@@ -22,7 +23,7 @@ def test_options():
BAD_SSL_TESTS = ['cert', 'alpn']
def grpc_bad_ssl_tests():
- native.cc_library(
+ grpc_cc_library(
name = 'bad_ssl_test_server',
srcs = ['server_common.cc'],
hdrs = ['server_common.h'],
@@ -31,12 +32,12 @@ def grpc_bad_ssl_tests():
'//test/core/end2end:ssl_test_data']
)
for t in BAD_SSL_TESTS:
- native.cc_binary(
+ grpc_cc_binary(
name = 'bad_ssl_%s_server' % t,
srcs = ['servers/%s.cc' % t],
deps = [':bad_ssl_test_server'],
)
- native.cc_test(
+ grpc_cc_test(
name = 'bad_ssl_%s_test' % t,
srcs = ['bad_ssl_test.cc'],
data = [':bad_ssl_%s_server' % t,
diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD
index c4d12fe3a1..d430b722df 100644
--- a/test/core/client_channel/BUILD
+++ b/test/core/client_channel/BUILD
@@ -54,3 +54,14 @@ grpc_cc_test(
],
)
+grpc_cc_test(
+ name = "status_util_test",
+ srcs = ["status_util_test.cc"],
+ language = "C++",
+ deps = [
+ "//:grpc",
+ ],
+ external_deps = [
+ "gtest",
+ ],
+)
diff --git a/test/core/client_channel/status_util_test.cc b/test/core/client_channel/status_util_test.cc
new file mode 100644
index 0000000000..f944990ad2
--- /dev/null
+++ b/test/core/client_channel/status_util_test.cc
@@ -0,0 +1,49 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/ext/filters/client_channel/status_util.h"
+
+#include <gtest/gtest.h>
+
+namespace grpc_core {
+namespace internal {
+namespace {
+
+TEST(StatusCodeSet, Basic) {
+ StatusCodeSet set;
+ EXPECT_TRUE(set.Empty());
+ EXPECT_FALSE(set.Contains(GRPC_STATUS_OK));
+ EXPECT_FALSE(set.Contains(GRPC_STATUS_UNAVAILABLE));
+ set.Add(GRPC_STATUS_OK);
+ EXPECT_FALSE(set.Empty());
+ EXPECT_TRUE(set.Contains(GRPC_STATUS_OK));
+ EXPECT_FALSE(set.Contains(GRPC_STATUS_UNAVAILABLE));
+ set.Add(GRPC_STATUS_UNAVAILABLE);
+ EXPECT_FALSE(set.Empty());
+ EXPECT_TRUE(set.Contains(GRPC_STATUS_OK));
+ EXPECT_TRUE(set.Contains(GRPC_STATUS_UNAVAILABLE));
+}
+
+} // namespace
+} // namespace internal
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index f8281bfe6f..952f3505fb 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -71,4 +71,95 @@ grpc_cc_library(
],
)
+grpc_cc_test(
+ name = "bad_server_response_test",
+ srcs = ["bad_server_response_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "connection_refused_test",
+ srcs = ["connection_refused_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "dualstack_socket_test",
+ srcs = ["dualstack_socket_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "goaway_server_test",
+ srcs = ["goaway_server_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "invalid_call_argument_test",
+ srcs = ["invalid_call_argument_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "multiple_server_queues_test",
+ srcs = ["multiple_server_queues_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "no_server_test",
+ srcs = ["no_server_test.cc"],
+ language = "C++",
+ deps = [
+ ":cq_verifier",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
grpc_end2end_tests()
diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc
index 79331bca6f..1af168e1f9 100644
--- a/test/core/end2end/bad_server_response_test.cc
+++ b/test/core/end2end/bad_server_response_test.cc
@@ -28,10 +28,10 @@
#include <grpc/slice.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc
index 411d0f2308..eb1d043fb2 100644
--- a/test/core/end2end/dualstack_socket_test.cc
+++ b/test/core/end2end/dualstack_socket_test.cc
@@ -166,7 +166,7 @@ void test_connect(const char* server_host, const char* client_host, int port,
} else {
/* Give up faster when failure is expected.
BUG: Setting this to 1000 reveals a memory leak (b/18608927). */
- deadline = grpc_timeout_milliseconds_to_deadline(3000);
+ deadline = grpc_timeout_milliseconds_to_deadline(8000);
}
/* Send a trivial request. */
diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc
index 6318550ad8..78ddcdb8f6 100644
--- a/test/core/end2end/end2end_nosec_tests.cc
+++ b/test/core/end2end/end2end_nosec_tests.cc
@@ -118,6 +118,36 @@ extern void request_with_payload(grpc_end2end_test_config config);
extern void request_with_payload_pre_init(void);
extern void resource_quota_server(grpc_end2end_test_config config);
extern void resource_quota_server_pre_init(void);
+extern void retry(grpc_end2end_test_config config);
+extern void retry_pre_init(void);
+extern void retry_cancellation(grpc_end2end_test_config config);
+extern void retry_cancellation_pre_init(void);
+extern void retry_disabled(grpc_end2end_test_config config);
+extern void retry_disabled_pre_init(void);
+extern void retry_exceeds_buffer_size_in_initial_batch(grpc_end2end_test_config config);
+extern void retry_exceeds_buffer_size_in_initial_batch_pre_init(void);
+extern void retry_exceeds_buffer_size_in_subsequent_batch(grpc_end2end_test_config config);
+extern void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void);
+extern void retry_non_retriable_status(grpc_end2end_test_config config);
+extern void retry_non_retriable_status_pre_init(void);
+extern void retry_recv_initial_metadata(grpc_end2end_test_config config);
+extern void retry_recv_initial_metadata_pre_init(void);
+extern void retry_recv_message(grpc_end2end_test_config config);
+extern void retry_recv_message_pre_init(void);
+extern void retry_server_pushback_delay(grpc_end2end_test_config config);
+extern void retry_server_pushback_delay_pre_init(void);
+extern void retry_server_pushback_disabled(grpc_end2end_test_config config);
+extern void retry_server_pushback_disabled_pre_init(void);
+extern void retry_streaming(grpc_end2end_test_config config);
+extern void retry_streaming_pre_init(void);
+extern void retry_streaming_after_commit(grpc_end2end_test_config config);
+extern void retry_streaming_after_commit_pre_init(void);
+extern void retry_streaming_succeeds_before_replay_finished(grpc_end2end_test_config config);
+extern void retry_streaming_succeeds_before_replay_finished_pre_init(void);
+extern void retry_throttled(grpc_end2end_test_config config);
+extern void retry_throttled_pre_init(void);
+extern void retry_too_many_attempts(grpc_end2end_test_config config);
+extern void retry_too_many_attempts_pre_init(void);
extern void server_finishes_request(grpc_end2end_test_config config);
extern void server_finishes_request_pre_init(void);
extern void shutdown_finishes_calls(grpc_end2end_test_config config);
@@ -197,6 +227,21 @@ void grpc_end2end_tests_pre_init(void) {
request_with_flags_pre_init();
request_with_payload_pre_init();
resource_quota_server_pre_init();
+ retry_pre_init();
+ retry_cancellation_pre_init();
+ retry_disabled_pre_init();
+ retry_exceeds_buffer_size_in_initial_batch_pre_init();
+ retry_exceeds_buffer_size_in_subsequent_batch_pre_init();
+ retry_non_retriable_status_pre_init();
+ retry_recv_initial_metadata_pre_init();
+ retry_recv_message_pre_init();
+ retry_server_pushback_delay_pre_init();
+ retry_server_pushback_disabled_pre_init();
+ retry_streaming_pre_init();
+ retry_streaming_after_commit_pre_init();
+ retry_streaming_succeeds_before_replay_finished_pre_init();
+ retry_throttled_pre_init();
+ retry_too_many_attempts_pre_init();
server_finishes_request_pre_init();
shutdown_finishes_calls_pre_init();
shutdown_finishes_tags_pre_init();
@@ -265,6 +310,21 @@ void grpc_end2end_tests(int argc, char **argv,
request_with_flags(config);
request_with_payload(config);
resource_quota_server(config);
+ retry(config);
+ retry_cancellation(config);
+ retry_disabled(config);
+ retry_exceeds_buffer_size_in_initial_batch(config);
+ retry_exceeds_buffer_size_in_subsequent_batch(config);
+ retry_non_retriable_status(config);
+ retry_recv_initial_metadata(config);
+ retry_recv_message(config);
+ retry_server_pushback_delay(config);
+ retry_server_pushback_disabled(config);
+ retry_streaming(config);
+ retry_streaming_after_commit(config);
+ retry_streaming_succeeds_before_replay_finished(config);
+ retry_throttled(config);
+ retry_too_many_attempts(config);
server_finishes_request(config);
shutdown_finishes_calls(config);
shutdown_finishes_tags(config);
@@ -460,6 +520,66 @@ void grpc_end2end_tests(int argc, char **argv,
resource_quota_server(config);
continue;
}
+ if (0 == strcmp("retry", argv[i])) {
+ retry(config);
+ continue;
+ }
+ if (0 == strcmp("retry_cancellation", argv[i])) {
+ retry_cancellation(config);
+ continue;
+ }
+ if (0 == strcmp("retry_disabled", argv[i])) {
+ retry_disabled(config);
+ continue;
+ }
+ if (0 == strcmp("retry_exceeds_buffer_size_in_initial_batch", argv[i])) {
+ retry_exceeds_buffer_size_in_initial_batch(config);
+ continue;
+ }
+ if (0 == strcmp("retry_exceeds_buffer_size_in_subsequent_batch", argv[i])) {
+ retry_exceeds_buffer_size_in_subsequent_batch(config);
+ continue;
+ }
+ if (0 == strcmp("retry_non_retriable_status", argv[i])) {
+ retry_non_retriable_status(config);
+ continue;
+ }
+ if (0 == strcmp("retry_recv_initial_metadata", argv[i])) {
+ retry_recv_initial_metadata(config);
+ continue;
+ }
+ if (0 == strcmp("retry_recv_message", argv[i])) {
+ retry_recv_message(config);
+ continue;
+ }
+ if (0 == strcmp("retry_server_pushback_delay", argv[i])) {
+ retry_server_pushback_delay(config);
+ continue;
+ }
+ if (0 == strcmp("retry_server_pushback_disabled", argv[i])) {
+ retry_server_pushback_disabled(config);
+ continue;
+ }
+ if (0 == strcmp("retry_streaming", argv[i])) {
+ retry_streaming(config);
+ continue;
+ }
+ if (0 == strcmp("retry_streaming_after_commit", argv[i])) {
+ retry_streaming_after_commit(config);
+ continue;
+ }
+ if (0 == strcmp("retry_streaming_succeeds_before_replay_finished", argv[i])) {
+ retry_streaming_succeeds_before_replay_finished(config);
+ continue;
+ }
+ if (0 == strcmp("retry_throttled", argv[i])) {
+ retry_throttled(config);
+ continue;
+ }
+ if (0 == strcmp("retry_too_many_attempts", argv[i])) {
+ retry_too_many_attempts(config);
+ continue;
+ }
if (0 == strcmp("server_finishes_request", argv[i])) {
server_finishes_request(config);
continue;
diff --git a/test/core/end2end/end2end_test.sh b/test/core/end2end/end2end_test.sh
index b1b9a65a1b..5bfb253090 100755
--- a/test/core/end2end/end2end_test.sh
+++ b/test/core/end2end/end2end_test.sh
@@ -15,4 +15,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+if [ -z "$3" ]
+ then
+ export GRPC_POLL_STRATEGY=$3
+fi
"$1" "$2"
diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc
index 9d8dfd6723..fb1e61b39f 100644
--- a/test/core/end2end/end2end_tests.cc
+++ b/test/core/end2end/end2end_tests.cc
@@ -120,6 +120,36 @@ extern void request_with_payload(grpc_end2end_test_config config);
extern void request_with_payload_pre_init(void);
extern void resource_quota_server(grpc_end2end_test_config config);
extern void resource_quota_server_pre_init(void);
+extern void retry(grpc_end2end_test_config config);
+extern void retry_pre_init(void);
+extern void retry_cancellation(grpc_end2end_test_config config);
+extern void retry_cancellation_pre_init(void);
+extern void retry_disabled(grpc_end2end_test_config config);
+extern void retry_disabled_pre_init(void);
+extern void retry_exceeds_buffer_size_in_initial_batch(grpc_end2end_test_config config);
+extern void retry_exceeds_buffer_size_in_initial_batch_pre_init(void);
+extern void retry_exceeds_buffer_size_in_subsequent_batch(grpc_end2end_test_config config);
+extern void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void);
+extern void retry_non_retriable_status(grpc_end2end_test_config config);
+extern void retry_non_retriable_status_pre_init(void);
+extern void retry_recv_initial_metadata(grpc_end2end_test_config config);
+extern void retry_recv_initial_metadata_pre_init(void);
+extern void retry_recv_message(grpc_end2end_test_config config);
+extern void retry_recv_message_pre_init(void);
+extern void retry_server_pushback_delay(grpc_end2end_test_config config);
+extern void retry_server_pushback_delay_pre_init(void);
+extern void retry_server_pushback_disabled(grpc_end2end_test_config config);
+extern void retry_server_pushback_disabled_pre_init(void);
+extern void retry_streaming(grpc_end2end_test_config config);
+extern void retry_streaming_pre_init(void);
+extern void retry_streaming_after_commit(grpc_end2end_test_config config);
+extern void retry_streaming_after_commit_pre_init(void);
+extern void retry_streaming_succeeds_before_replay_finished(grpc_end2end_test_config config);
+extern void retry_streaming_succeeds_before_replay_finished_pre_init(void);
+extern void retry_throttled(grpc_end2end_test_config config);
+extern void retry_throttled_pre_init(void);
+extern void retry_too_many_attempts(grpc_end2end_test_config config);
+extern void retry_too_many_attempts_pre_init(void);
extern void server_finishes_request(grpc_end2end_test_config config);
extern void server_finishes_request_pre_init(void);
extern void shutdown_finishes_calls(grpc_end2end_test_config config);
@@ -200,6 +230,21 @@ void grpc_end2end_tests_pre_init(void) {
request_with_flags_pre_init();
request_with_payload_pre_init();
resource_quota_server_pre_init();
+ retry_pre_init();
+ retry_cancellation_pre_init();
+ retry_disabled_pre_init();
+ retry_exceeds_buffer_size_in_initial_batch_pre_init();
+ retry_exceeds_buffer_size_in_subsequent_batch_pre_init();
+ retry_non_retriable_status_pre_init();
+ retry_recv_initial_metadata_pre_init();
+ retry_recv_message_pre_init();
+ retry_server_pushback_delay_pre_init();
+ retry_server_pushback_disabled_pre_init();
+ retry_streaming_pre_init();
+ retry_streaming_after_commit_pre_init();
+ retry_streaming_succeeds_before_replay_finished_pre_init();
+ retry_throttled_pre_init();
+ retry_too_many_attempts_pre_init();
server_finishes_request_pre_init();
shutdown_finishes_calls_pre_init();
shutdown_finishes_tags_pre_init();
@@ -269,6 +314,21 @@ void grpc_end2end_tests(int argc, char **argv,
request_with_flags(config);
request_with_payload(config);
resource_quota_server(config);
+ retry(config);
+ retry_cancellation(config);
+ retry_disabled(config);
+ retry_exceeds_buffer_size_in_initial_batch(config);
+ retry_exceeds_buffer_size_in_subsequent_batch(config);
+ retry_non_retriable_status(config);
+ retry_recv_initial_metadata(config);
+ retry_recv_message(config);
+ retry_server_pushback_delay(config);
+ retry_server_pushback_disabled(config);
+ retry_streaming(config);
+ retry_streaming_after_commit(config);
+ retry_streaming_succeeds_before_replay_finished(config);
+ retry_throttled(config);
+ retry_too_many_attempts(config);
server_finishes_request(config);
shutdown_finishes_calls(config);
shutdown_finishes_tags(config);
@@ -468,6 +528,66 @@ void grpc_end2end_tests(int argc, char **argv,
resource_quota_server(config);
continue;
}
+ if (0 == strcmp("retry", argv[i])) {
+ retry(config);
+ continue;
+ }
+ if (0 == strcmp("retry_cancellation", argv[i])) {
+ retry_cancellation(config);
+ continue;
+ }
+ if (0 == strcmp("retry_disabled", argv[i])) {
+ retry_disabled(config);
+ continue;
+ }
+ if (0 == strcmp("retry_exceeds_buffer_size_in_initial_batch", argv[i])) {
+ retry_exceeds_buffer_size_in_initial_batch(config);
+ continue;
+ }
+ if (0 == strcmp("retry_exceeds_buffer_size_in_subsequent_batch", argv[i])) {
+ retry_exceeds_buffer_size_in_subsequent_batch(config);
+ continue;
+ }
+ if (0 == strcmp("retry_non_retriable_status", argv[i])) {
+ retry_non_retriable_status(config);
+ continue;
+ }
+ if (0 == strcmp("retry_recv_initial_metadata", argv[i])) {
+ retry_recv_initial_metadata(config);
+ continue;
+ }
+ if (0 == strcmp("retry_recv_message", argv[i])) {
+ retry_recv_message(config);
+ continue;
+ }
+ if (0 == strcmp("retry_server_pushback_delay", argv[i])) {
+ retry_server_pushback_delay(config);
+ continue;
+ }
+ if (0 == strcmp("retry_server_pushback_disabled", argv[i])) {
+ retry_server_pushback_disabled(config);
+ continue;
+ }
+ if (0 == strcmp("retry_streaming", argv[i])) {
+ retry_streaming(config);
+ continue;
+ }
+ if (0 == strcmp("retry_streaming_after_commit", argv[i])) {
+ retry_streaming_after_commit(config);
+ continue;
+ }
+ if (0 == strcmp("retry_streaming_succeeds_before_replay_finished", argv[i])) {
+ retry_streaming_succeeds_before_replay_finished(config);
+ continue;
+ }
+ if (0 == strcmp("retry_throttled", argv[i])) {
+ retry_throttled(config);
+ continue;
+ }
+ if (0 == strcmp("retry_too_many_attempts", argv[i])) {
+ retry_too_many_attempts(config);
+ continue;
+ }
if (0 == strcmp("server_finishes_request", argv[i])) {
server_finishes_request(config);
continue;
diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc
index 423764ad07..27b897ce5a 100644
--- a/test/core/end2end/fixtures/h2_census.cc
+++ b/test/core/end2end/fixtures/h2_census.cc
@@ -23,7 +23,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
@@ -31,6 +30,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc
index af7ddecd00..b4ec78d710 100644
--- a/test/core/end2end/fixtures/h2_compress.cc
+++ b/test/core/end2end/fixtures/h2_compress.cc
@@ -23,7 +23,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
@@ -31,6 +30,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc
index 88f24b937c..e97d078d9c 100644
--- a/test/core/end2end/fixtures/h2_full+pipe.cc
+++ b/test/core/end2end/fixtures/h2_full+pipe.cc
@@ -28,13 +28,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc
index 4e0d66896b..12aa69bb17 100644
--- a/test/core/end2end/fixtures/h2_full+trace.cc
+++ b/test/core/end2end/fixtures/h2_full+trace.cc
@@ -28,7 +28,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
@@ -36,6 +35,7 @@
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc
index ce0fed6fee..c6b358dcc5 100644
--- a/test/core/end2end/fixtures/h2_full+workarounds.cc
+++ b/test/core/end2end/fixtures/h2_full+workarounds.cc
@@ -23,7 +23,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/workaround_list.h>
@@ -32,6 +31,7 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc
index 4b96fa268a..32e3e55128 100644
--- a/test/core/end2end/fixtures/h2_full.cc
+++ b/test/core/end2end/fixtures/h2_full.cc
@@ -23,13 +23,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc
index da63f46018..b990d7a763 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.cc
+++ b/test/core/end2end/fixtures/h2_http_proxy.cc
@@ -24,7 +24,6 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
@@ -32,6 +31,7 @@
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/end2end/fixtures/http_proxy_fixture.h"
@@ -72,11 +72,12 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f,
/* If testing for proxy auth, add credentials to proxy uri */
const grpc_arg* proxy_auth_arg =
grpc_channel_args_find(client_args, GRPC_ARG_HTTP_PROXY_AUTH_CREDS);
- if (proxy_auth_arg == nullptr || proxy_auth_arg->type != GRPC_ARG_STRING) {
+ const char* proxy_auth_str = grpc_channel_arg_get_string(proxy_auth_arg);
+ if (proxy_auth_str == nullptr) {
gpr_asprintf(&proxy_uri, "http://%s",
grpc_end2end_http_proxy_get_proxy_name(ffd->proxy));
} else {
- gpr_asprintf(&proxy_uri, "http://%s@%s", proxy_auth_arg->value.string,
+ gpr_asprintf(&proxy_uri, "http://%s@%s", proxy_auth_str,
grpc_end2end_http_proxy_get_proxy_name(ffd->proxy));
}
gpr_setenv("http_proxy", proxy_uri);
diff --git a/test/core/end2end/fixtures/h2_load_reporting.cc b/test/core/end2end/fixtures/h2_load_reporting.cc
index dddeef5862..6adc0c154e 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.cc
+++ b/test/core/end2end/fixtures/h2_load_reporting.cc
@@ -23,7 +23,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
@@ -32,6 +31,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc
index 4379cddf77..28a6eeeb78 100644
--- a/test/core/end2end/fixtures/h2_proxy.cc
+++ b/test/core/end2end/fixtures/h2_proxy.cc
@@ -23,13 +23,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/end2end/fixtures/proxy.h"
@@ -49,7 +49,17 @@ static grpc_server* create_proxy_server(const char* port,
static grpc_channel* create_proxy_client(const char* target,
grpc_channel_args* client_args) {
- return grpc_insecure_channel_create(target, client_args, nullptr);
+ // Disable retries in proxy client.
+ grpc_arg arg;
+ arg.type = GRPC_ARG_INTEGER;
+ arg.key = const_cast<char*>(GRPC_ARG_ENABLE_RETRIES);
+ arg.value.integer = 0;
+ grpc_channel_args* new_args =
+ grpc_channel_args_copy_and_add(client_args, &arg, 1);
+ grpc_channel* channel =
+ grpc_insecure_channel_create(target, new_args, nullptr);
+ grpc_channel_args_destroy(new_args);
+ return channel;
}
static const grpc_end2end_proxy_def proxy_def = {create_proxy_server,
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc
index 92b9a463c1..5dd5c2ad67 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.cc
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc
@@ -28,7 +28,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/client/http_client_filter.h"
@@ -37,6 +36,7 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/surface/channel.h"
diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc
index 46acf1f615..52a7b95c3a 100644
--- a/test/core/end2end/fixtures/h2_sockpair.cc
+++ b/test/core/end2end/fixtures/h2_sockpair.cc
@@ -23,7 +23,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/client/http_client_filter.h"
@@ -31,6 +30,7 @@
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/surface/channel.h"
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
index 6499c90271..0d3cb34724 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
@@ -23,7 +23,6 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/client/http_client_filter.h"
@@ -31,6 +30,7 @@
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/endpoint_pair.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/surface/channel.h"
diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc
index 41045c278c..a97b14f1d6 100644
--- a/test/core/end2end/fixtures/h2_uds.cc
+++ b/test/core/end2end/fixtures/h2_uds.cc
@@ -26,7 +26,6 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
@@ -34,6 +33,7 @@
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc
index 63a15753a4..18e8310251 100644
--- a/test/core/end2end/fixtures/http_proxy_fixture.cc
+++ b/test/core/end2end/fixtures/http_proxy_fixture.cc
@@ -29,11 +29,11 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -413,12 +413,13 @@ static void on_read_request_done(void* arg, grpc_error* error) {
// If proxy auth is being used, check if the header is present and as expected
const grpc_arg* proxy_auth_arg = grpc_channel_args_find(
conn->proxy->channel_args, GRPC_ARG_HTTP_PROXY_AUTH_CREDS);
- if (proxy_auth_arg != nullptr && proxy_auth_arg->type == GRPC_ARG_STRING) {
+ char* proxy_auth_str = grpc_channel_arg_get_string(proxy_auth_arg);
+ if (proxy_auth_str != nullptr) {
bool client_authenticated = false;
for (size_t i = 0; i < conn->http_request.hdr_count; i++) {
if (strcmp(conn->http_request.hdrs[i].key, "Proxy-Authorization") == 0) {
client_authenticated = proxy_auth_header_matches(
- conn->http_request.hdrs[i].value, proxy_auth_arg->value.string);
+ conn->http_request.hdrs[i].value, proxy_auth_str);
break;
}
}
diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc
index 796ef67ddb..4ddcc78495 100644
--- a/test/core/end2end/fixtures/inproc.cc
+++ b/test/core/end2end/fixtures/inproc.cc
@@ -23,13 +23,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/http/server/http_server_filter.h"
#include "src/core/ext/transport/inproc/inproc_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc
index 918988d9dc..bc3b0ca35c 100644
--- a/test/core/end2end/fixtures/proxy.cc
+++ b/test/core/end2end/fixtures/proxy.cc
@@ -23,9 +23,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "test/core/util/port.h"
diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc
index dc1183b9a0..b6347fb1db 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.cc
+++ b/test/core/end2end/fuzzers/api_fuzzer.cc
@@ -580,6 +580,7 @@ typedef struct call_state {
grpc_slice recv_status_details;
int cancelled;
int pending_ops;
+ bool sent_initial_metadata;
grpc_call_details call_details;
grpc_byte_buffer* send_message;
// starts at 0, individual flags from DONE_FLAG_xxx are set
@@ -1026,11 +1027,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
ok = false;
break;
case GRPC_OP_SEND_INITIAL_METADATA:
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA;
- read_metadata(&inp, &op->data.send_initial_metadata.count,
- &op->data.send_initial_metadata.metadata,
- g_active_call);
+ if (g_active_call->sent_initial_metadata) {
+ ok = false;
+ } else {
+ g_active_call->sent_initial_metadata = true;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ has_ops |= 1 << GRPC_OP_SEND_INITIAL_METADATA;
+ read_metadata(&inp, &op->data.send_initial_metadata.count,
+ &op->data.send_initial_metadata.metadata,
+ g_active_call);
+ }
break;
case GRPC_OP_SEND_MESSAGE:
op->op = GRPC_OP_SEND_MESSAGE;
@@ -1067,9 +1073,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
&g_active_call->recv_initial_metadata;
break;
case GRPC_OP_RECV_MESSAGE:
- op->op = GRPC_OP_RECV_MESSAGE;
- has_ops |= 1 << GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &g_active_call->recv_message;
+ if (g_active_call->done_flags & DONE_FLAG_CALL_CLOSED) {
+ ok = false;
+ } else {
+ op->op = GRPC_OP_RECV_MESSAGE;
+ has_ops |= 1 << GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message =
+ &g_active_call->recv_message;
+ }
break;
case GRPC_OP_RECV_STATUS_ON_CLIENT:
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696
new file mode 100644
index 0000000000..36103166b7
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680
new file mode 100644
index 0000000000..33bf2804b6
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080
new file mode 100644
index 0000000000..4f995ac8e1
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336
new file mode 100644
index 0000000000..07b4b33231
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336
Binary files differ
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 3ed82e19bd..c719d0fa84 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -21,7 +21,13 @@
"\x0Auser-agent"
"\x04host"
"\x08lb-token"
+"\x1Agrpc-previous-rpc-attempts"
+"\x16grpc-retry-pushback-ms"
"\x0Cgrpc-timeout"
+"\x011"
+"\x012"
+"\x013"
+"\x014"
"\x00"
"\x13grpc.wait_for_ready"
"\x0Cgrpc.timeout"
@@ -32,8 +38,6 @@
"\x04gzip"
"\x0Bstream/gzip"
"\x010"
-"\x011"
-"\x012"
"\x08identity"
"\x08trailers"
"\x10application/grpc"
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index e7cf97b2d0..4e20b0b334 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -24,15 +24,24 @@ import hashlib
FixtureOptions = collections.namedtuple(
'FixtureOptions',
- 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering')
+ 'fullstack includes_proxy dns_resolver name_resolution secure platforms ci_mac tracing exclude_configs exclude_iomgrs large_writes enables_compression supports_compression is_inproc is_http2 supports_proxy_auth supports_write_buffering client_channel')
default_unsecure_fixture_options = FixtureOptions(
- True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'], True, False, [], [], True, False, True, False, True, False, True)
-socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False)
-default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True)
-uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv'])
+ True, False, True, True, False, ['windows', 'linux', 'mac', 'posix'],
+ True, False, [], [], True, False, True, False, True, False, True, True)
+socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(
+ fullstack=False, dns_resolver=False, client_channel=False)
+default_secure_fixture_options = default_unsecure_fixture_options._replace(
+ secure=True)
+uds_fixture_options = default_unsecure_fixture_options._replace(
+ dns_resolver=False, platforms=['linux', 'mac', 'posix'],
+ exclude_iomgrs=['uv'])
fd_unsecure_fixture_options = default_unsecure_fixture_options._replace(
- dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv'])
-inproc_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, fullstack=False, name_resolution=False, supports_compression=False, is_inproc=True, is_http2=False, supports_write_buffering=False)
+ dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'],
+ exclude_iomgrs=['uv'], client_channel=False)
+inproc_fixture_options = default_unsecure_fixture_options._replace(
+ dns_resolver=False, fullstack=False, name_resolution=False,
+ supports_compression=False, is_inproc=True, is_http2=False,
+ supports_write_buffering=False, client_channel=False)
# maps fixture name to whether it requires the security library
END2END_FIXTURES = {
@@ -68,9 +77,12 @@ END2END_FIXTURES = {
TestOptions = collections.namedtuple(
'TestOptions',
- 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering')
-default_test_options = TestOptions(False, False, False, True, False, True, 1.0, [], False, False, True, False, False, False, False, False)
-connectivity_test_options = default_test_options._replace(needs_fullstack=True)
+ 'needs_fullstack needs_dns needs_names proxyable secure traceable cpu_cost exclude_iomgrs large_writes flaky allows_compression needs_compression exclude_inproc needs_http2 needs_proxy_auth needs_write_buffering needs_client_channel')
+default_test_options = TestOptions(
+ False, False, False, True, False, True, 1.0, [], False, False, True,
+ False, False, False, False, False, False)
+connectivity_test_options = default_test_options._replace(
+ needs_fullstack=True)
LOWCPU = 0.1
@@ -80,9 +92,8 @@ END2END_TESTS = {
'bad_hostname': default_test_options._replace(needs_names=True),
'bad_ping': connectivity_test_options._replace(proxyable=False),
'binary_metadata': default_test_options._replace(cpu_cost=LOWCPU),
- 'resource_quota_server': default_test_options._replace(large_writes=True,
- proxyable=False,
- allows_compression=False),
+ 'resource_quota_server': default_test_options._replace(
+ large_writes=True, proxyable=False, allows_compression=False),
'call_creds': default_test_options._replace(secure=True),
'cancel_after_accept': default_test_options._replace(cpu_cost=LOWCPU),
'cancel_after_client_done': default_test_options._replace(cpu_cost=LOWCPU),
@@ -91,18 +102,21 @@ END2END_TESTS = {
'cancel_before_invoke': default_test_options._replace(cpu_cost=LOWCPU),
'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU),
'cancel_with_status': default_test_options._replace(cpu_cost=LOWCPU),
- 'compressed_payload': default_test_options._replace(proxyable=False,needs_compression=True),
+ 'compressed_payload': default_test_options._replace(proxyable=False,
+ needs_compression=True),
'connectivity': connectivity_test_options._replace(needs_names=True,
proxyable=False, cpu_cost=LOWCPU, exclude_iomgrs=['uv']),
- 'default_host': default_test_options._replace(needs_fullstack=True,
- needs_dns=True,needs_names=True),
- 'disappearing_server': connectivity_test_options._replace(flaky=True,needs_names=True),
+ 'default_host': default_test_options._replace(
+ needs_fullstack=True, needs_dns=True, needs_names=True),
+ 'disappearing_server': connectivity_test_options._replace(flaky=True,
+ needs_names=True),
'empty_batch': default_test_options._replace(cpu_cost=LOWCPU),
'filter_causes_close': default_test_options._replace(cpu_cost=LOWCPU),
'filter_call_init_fails': default_test_options,
'filter_latency': default_test_options._replace(cpu_cost=LOWCPU),
'filter_status_code': default_test_options._replace(cpu_cost=LOWCPU),
- 'graceful_server_shutdown': default_test_options._replace(cpu_cost=LOWCPU,exclude_inproc=True),
+ 'graceful_server_shutdown': default_test_options._replace(
+ cpu_cost=LOWCPU, exclude_inproc=True),
'hpack_size': default_test_options._replace(proxyable=False,
traceable=False,
cpu_cost=LOWCPU),
@@ -127,30 +141,75 @@ END2END_TESTS = {
'payload': default_test_options,
'load_reporting_hook': default_test_options,
'ping_pong_streaming': default_test_options._replace(cpu_cost=LOWCPU),
- 'ping': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
+ 'ping': connectivity_test_options._replace(proxyable=False,
+ cpu_cost=LOWCPU),
'proxy_auth': default_test_options._replace(needs_proxy_auth=True),
'registered_call': default_test_options,
'request_with_flags': default_test_options._replace(
proxyable=False, cpu_cost=LOWCPU),
'request_with_payload': default_test_options._replace(cpu_cost=LOWCPU),
+ # TODO(roth): Remove proxyable=False for all retry tests once we
+ # have a way for the proxy to propagate the fact that trailing
+ # metadata is available when initial metadata is returned.
+ # See https://github.com/grpc/grpc/issues/14467 for context.
+ 'retry': default_test_options._replace(cpu_cost=LOWCPU,
+ needs_client_channel=True,
+ proxyable=False),
+ 'retry_cancellation': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_disabled': default_test_options._replace(cpu_cost=LOWCPU,
+ needs_client_channel=True,
+ proxyable=False),
+ 'retry_exceeds_buffer_size_in_initial_batch': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_exceeds_buffer_size_in_subsequent_batch':
+ default_test_options._replace(cpu_cost=LOWCPU,
+ needs_client_channel=True,
+ proxyable=False),
+ 'retry_non_retriable_status': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_recv_initial_metadata': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_recv_message': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_server_pushback_delay': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_server_pushback_disabled': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_streaming': default_test_options._replace(cpu_cost=LOWCPU,
+ needs_client_channel=True,
+ proxyable=False),
+ 'retry_streaming_after_commit': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
+ 'retry_streaming_succeeds_before_replay_finished':
+ default_test_options._replace(cpu_cost=LOWCPU,
+ needs_client_channel=True,
+ proxyable=False),
+ 'retry_throttled': default_test_options._replace(cpu_cost=LOWCPU,
+ needs_client_channel=True,
+ proxyable=False),
+ 'retry_too_many_attempts': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_client_channel=True, proxyable=False),
'server_finishes_request': default_test_options._replace(cpu_cost=LOWCPU),
'shutdown_finishes_calls': default_test_options._replace(cpu_cost=LOWCPU),
'shutdown_finishes_tags': default_test_options._replace(cpu_cost=LOWCPU),
'simple_cacheable_request': default_test_options._replace(cpu_cost=LOWCPU),
- 'stream_compression_compressed_payload': default_test_options._replace(proxyable=False,
- exclude_inproc=True),
- 'stream_compression_payload': default_test_options._replace(exclude_inproc=True),
- 'stream_compression_ping_pong_streaming': default_test_options._replace(exclude_inproc=True),
+ 'stream_compression_compressed_payload': default_test_options._replace(
+ proxyable=False, exclude_inproc=True),
+ 'stream_compression_payload': default_test_options._replace(
+ exclude_inproc=True),
+ 'stream_compression_ping_pong_streaming': default_test_options._replace(
+ exclude_inproc=True),
'simple_delayed_request': connectivity_test_options,
'simple_metadata': default_test_options,
'simple_request': default_test_options,
'streaming_error_response': default_test_options._replace(cpu_cost=LOWCPU),
'trailing_metadata': default_test_options,
'workaround_cronet_compression': default_test_options,
- 'write_buffering': default_test_options._replace(cpu_cost=LOWCPU,
- needs_write_buffering=True),
- 'write_buffering_at_end': default_test_options._replace(cpu_cost=LOWCPU,
- needs_write_buffering=True),
+ 'write_buffering': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_write_buffering=True),
+ 'write_buffering_at_end': default_test_options._replace(
+ cpu_cost=LOWCPU, needs_write_buffering=True),
}
@@ -191,6 +250,9 @@ def compatible(f, t):
if END2END_TESTS[t].needs_write_buffering:
if not END2END_FIXTURES[f].supports_write_buffering:
return False
+ if END2END_TESTS[t].needs_client_channel:
+ if not END2END_FIXTURES[f].client_channel:
+ return False
return True
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 1d759e1ecb..8e723fd609 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+POLLERS = ['epollex', 'epollsig', 'epoll1', 'poll', 'poll-cv']
+
load("//bazel:grpc_build_system.bzl", "grpc_sh_test", "grpc_cc_binary", "grpc_cc_library")
"""Generates the appropriate build.json data for all the end2end tests."""
@@ -22,7 +24,7 @@ def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True,
name_resolution=True, secure=True, tracing=False,
platforms=['windows', 'linux', 'mac', 'posix'],
is_inproc=False, is_http2=True, supports_proxy_auth=False,
- supports_write_buffering=True):
+ supports_write_buffering=True, client_channel=True):
return struct(
fullstack=fullstack,
includes_proxy=includes_proxy,
@@ -33,8 +35,9 @@ def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True,
is_inproc=is_inproc,
is_http2=is_http2,
supports_proxy_auth=supports_proxy_auth,
- supports_write_buffering=supports_write_buffering
- #platforms=platforms
+ supports_write_buffering=supports_write_buffering,
+ client_channel=client_channel,
+ #platforms=platforms,
)
@@ -45,6 +48,7 @@ END2END_FIXTURES = {
'h2_load_reporting': fixture_options(),
'h2_fakesec': fixture_options(),
'h2_fd': fixture_options(dns_resolver=False, fullstack=False,
+ client_channel=False,
platforms=['linux', 'mac', 'posix']),
'h2_full': fixture_options(),
'h2_full+pipe': fixture_options(platforms=['linux']),
@@ -53,24 +57,28 @@ END2END_FIXTURES = {
'h2_http_proxy': fixture_options(supports_proxy_auth=True),
'h2_oauth2': fixture_options(),
'h2_proxy': fixture_options(includes_proxy=True),
- 'h2_sockpair_1byte': fixture_options(fullstack=False, dns_resolver=False),
- 'h2_sockpair': fixture_options(fullstack=False, dns_resolver=False),
+ 'h2_sockpair_1byte': fixture_options(fullstack=False, dns_resolver=False,
+ client_channel=False),
+ 'h2_sockpair': fixture_options(fullstack=False, dns_resolver=False,
+ client_channel=False),
'h2_sockpair+trace': fixture_options(fullstack=False, dns_resolver=False,
- tracing=True),
+ tracing=True, client_channel=False),
'h2_ssl': fixture_options(secure=True),
'h2_ssl_proxy': fixture_options(includes_proxy=True, secure=True),
'h2_uds': fixture_options(dns_resolver=False,
platforms=['linux', 'mac', 'posix']),
'inproc': fixture_options(fullstack=False, dns_resolver=False,
name_resolution=False, is_inproc=True,
- is_http2=False, supports_write_buffering=False),
+ is_http2=False, supports_write_buffering=False,
+ client_channel=False),
}
def test_options(needs_fullstack=False, needs_dns=False, needs_names=False,
proxyable=True, secure=False, traceable=False,
exclude_inproc=False, needs_http2=False,
- needs_proxy_auth=False, needs_write_buffering=False):
+ needs_proxy_auth=False, needs_write_buffering=False,
+ needs_client_channel=False):
return struct(
needs_fullstack=needs_fullstack,
needs_dns=needs_dns,
@@ -81,7 +89,8 @@ def test_options(needs_fullstack=False, needs_dns=False, needs_names=False,
exclude_inproc=exclude_inproc,
needs_http2=needs_http2,
needs_proxy_auth=needs_proxy_auth,
- needs_write_buffering=needs_write_buffering
+ needs_write_buffering=needs_write_buffering,
+ needs_client_channel=needs_client_channel,
)
@@ -116,7 +125,8 @@ END2END_TESTS = {
'invoke_large_request': test_options(),
'keepalive_timeout': test_options(proxyable=False, needs_http2=True),
'large_metadata': test_options(),
- 'max_concurrent_streams': test_options(proxyable=False, exclude_inproc=True),
+ 'max_concurrent_streams': test_options(proxyable=False,
+ exclude_inproc=True),
'max_connection_age': test_options(exclude_inproc=True),
'max_connection_idle': test_options(needs_fullstack=True, proxyable=False),
'max_message_length': test_options(),
@@ -132,6 +142,37 @@ END2END_TESTS = {
'registered_call': test_options(),
'request_with_flags': test_options(proxyable=False),
'request_with_payload': test_options(),
+ # TODO(roth): Remove proxyable=False for all retry tests once we
+ # have a way for the proxy to propagate the fact that trailing
+ # metadata is available when initial metadata is returned.
+ # See https://github.com/grpc/grpc/issues/14467 for context.
+ 'retry': test_options(needs_client_channel=True, proxyable=False),
+ 'retry_cancellation': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_disabled': test_options(needs_client_channel=True, proxyable=False),
+ 'retry_exceeds_buffer_size_in_initial_batch': test_options(
+ needs_client_channel=True, proxyable=False),
+ 'retry_exceeds_buffer_size_in_subsequent_batch': test_options(
+ needs_client_channel=True, proxyable=False),
+ 'retry_non_retriable_status': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_recv_initial_metadata': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_recv_message': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_server_pushback_delay': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_server_pushback_disabled': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_streaming': test_options(needs_client_channel=True, proxyable=False),
+ 'retry_streaming_after_commit': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_streaming_succeeds_before_replay_finished': test_options(
+ needs_client_channel=True, proxyable=False),
+ 'retry_throttled': test_options(needs_client_channel=True,
+ proxyable=False),
+ 'retry_too_many_attempts': test_options(needs_client_channel=True,
+ proxyable=False),
'server_finishes_request': test_options(),
'shutdown_finishes_calls': test_options(),
'shutdown_finishes_tags': test_options(),
@@ -140,7 +181,8 @@ END2END_TESTS = {
'simple_metadata': test_options(),
'simple_request': test_options(),
'streaming_error_response': test_options(),
- 'stream_compression_compressed_payload': test_options(proxyable=False, exclude_inproc=True),
+ 'stream_compression_compressed_payload': test_options(proxyable=False,
+ exclude_inproc=True),
'stream_compression_payload': test_options(exclude_inproc=True),
'stream_compression_ping_pong_streaming': test_options(exclude_inproc=True),
'trailing_metadata': test_options(),
@@ -181,6 +223,9 @@ def compatible(fopt, topt):
if topt.needs_write_buffering:
if not fopt.supports_write_buffering:
return False
+ if topt.needs_client_channel:
+ if not fopt.client_channel:
+ return False
return True
@@ -219,9 +264,14 @@ def grpc_end2end_tests():
for t, topt in END2END_TESTS.items():
#print(compatible(fopt, topt), f, t, fopt, topt)
if not compatible(fopt, topt): continue
- grpc_sh_test(
- name = '%s_test@%s' % (f, t),
- srcs = ['end2end_test.sh'],
- args = ['$(location %s_test)' % f, t],
- data = [':%s_test' % f],
- )
+ for poller in POLLERS:
+ native.sh_test(
+ name = '%s_test@%s@poller=%s' % (f, t, poller),
+ data = [':%s_test' % f],
+ srcs = ['end2end_test.sh'],
+ args = [
+ '$(location %s_test)' % f,
+ t,
+ poller,
+ ],
+ )
diff --git a/test/core/end2end/tests/bad_ping.cc b/test/core/end2end/tests/bad_ping.cc
index ddab3faa27..9fff3bfb7d 100644
--- a/test/core/end2end/tests/bad_ping.cc
+++ b/test/core/end2end/tests/bad_ping.cc
@@ -23,9 +23,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "test/core/end2end/cq_verifier.h"
diff --git a/test/core/end2end/tests/connectivity.cc b/test/core/end2end/tests/connectivity.cc
index 56e5189a22..a517ffa686 100644
--- a/test/core/end2end/tests/connectivity.cc
+++ b/test/core/end2end/tests/connectivity.cc
@@ -20,9 +20,9 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "test/core/end2end/cq_verifier.h"
static void* tag(intptr_t t) { return (void*)t; }
diff --git a/test/core/end2end/tests/ping.cc b/test/core/end2end/tests/ping.cc
index c01dfa858f..8fce295f90 100644
--- a/test/core/end2end/tests/ping.cc
+++ b/test/core/end2end/tests/ping.cc
@@ -20,9 +20,9 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "test/core/end2end/cq_verifier.h"
diff --git a/test/core/end2end/tests/retry.cc b/test/core/end2end/tests/retry.cc
new file mode 100644
index 0000000000..38ecc6fbb1
--- /dev/null
+++ b/test/core/end2end/tests/retry.cc
@@ -0,0 +1,325 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests a basic retry scenario:
+// - 2 retries allowed for ABORTED status
+// - first attempt returns ABORTED
+// - second attempt returns OK
+static void test_retry(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ // Make sure the "grpc-previous-rpc-attempts" header was not sent in the
+ // initial attempt.
+ for (size_t i = 0; i < request_metadata_recv.count; ++i) {
+ GPR_ASSERT(!grpc_slice_eq(request_metadata_recv.metadata[i].key,
+ GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS));
+ }
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ // Make sure the "grpc-previous-rpc-attempts" header was sent in the retry.
+ bool found_retry_header = false;
+ for (size_t i = 0; i < request_metadata_recv.count; ++i) {
+ if (grpc_slice_eq(request_metadata_recv.metadata[i].key,
+ GRPC_MDSTR_GRPC_PREVIOUS_RPC_ATTEMPTS)) {
+ GPR_ASSERT(
+ grpc_slice_eq(request_metadata_recv.metadata[i].value, GRPC_MDSTR_1));
+ found_retry_header = true;
+ break;
+ }
+ }
+ GPR_ASSERT(found_retry_header);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = response_payload;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_OK;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(202), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_OK);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 0);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry(config);
+}
+
+void retry_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_cancellation.cc b/test/core/end2end/tests/retry_cancellation.cc
new file mode 100644
index 0000000000..0504092c4f
--- /dev/null
+++ b/test/core/end2end/tests/retry_cancellation.cc
@@ -0,0 +1,277 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests retry cancellation.
+static void test_retry_cancellation(grpc_end2end_test_config config,
+ cancellation_mode mode) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " },\n"
+ " \"timeout\": \"5s\"\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ char* name;
+ gpr_asprintf(&name, "retry_cancellation/%s", mode.name);
+ grpc_end2end_test_fixture f = begin_test(config, name, &client_args, nullptr);
+ gpr_free(name);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ // Client starts a batch with all 6 ops.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ // Server gets a call and fails with retryable status.
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+
+ // Server gets a second call (the retry).
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ // Initiate cancellation.
+ GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, nullptr));
+
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == mode.expect_status);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_cancellation(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(cancellation_modes); ++i) {
+ test_retry_cancellation(config, cancellation_modes[i]);
+ }
+}
+
+void retry_cancellation_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_disabled.cc b/test/core/end2end/tests/retry_disabled.cc
new file mode 100644
index 0000000000..cb30502aeb
--- /dev/null
+++ b/test/core/end2end/tests/retry_disabled.cc
@@ -0,0 +1,262 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we don't retry when retries are disabled via the
+// GRPC_ARG_ENABLE_RETRIES channel arg, even when there is retry
+// configuration in the service config.
+// - 1 retry allowed for ABORTED status
+// - first attempt returns ABORTED but does not retry
+static void test_retry_disabled(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg args[2];
+ args[0].type = GRPC_ARG_STRING;
+ args[0].key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ args[0].value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ args[1].type = GRPC_ARG_INTEGER;
+ args[1].key = const_cast<char*>(GRPC_ARG_ENABLE_RETRIES);
+ args[1].value.integer = 0;
+ grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_disabled", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_disabled(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_disabled(config);
+}
+
+void retry_disabled_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc b/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
new file mode 100644
index 0000000000..3908f29971
--- /dev/null
+++ b/test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc
@@ -0,0 +1,266 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we don't make any further attempts after we exceed the
+// max buffer size.
+// - 1 retry allowed for ABORTED status
+// - buffer size set to 2 bytes
+// - client sends a 3-byte message
+// - first attempt gets ABORTED but is not retried
+static void test_retry_exceeds_buffer_size_in_initial_batch(
+ grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg args[2];
+ args[0].type = GRPC_ARG_STRING;
+ args[0].key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ args[0].value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ args[1].type = GRPC_ARG_INTEGER;
+ args[1].key = const_cast<char*>(GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE);
+ args[1].value.integer = 2;
+ grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_exceeds_buffer_size_in_initial_batch",
+ &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_exceeds_buffer_size_in_initial_batch(
+ grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_exceeds_buffer_size_in_initial_batch(config);
+}
+
+void retry_exceeds_buffer_size_in_initial_batch_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc b/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
new file mode 100644
index 0000000000..409fac4888
--- /dev/null
+++ b/test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc
@@ -0,0 +1,279 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Similar to the retry_exceeds_buffer_size_in_initial_batch test, but we
+// don't exceed the buffer size until the second batch.
+// - 1 retry allowed for ABORTED status
+// - buffer size set to 100 KiB (larger than initial metadata)
+// - client sends a 100 KiB message
+// - first attempt gets ABORTED but is not retried
+static void test_retry_exceeds_buffer_size_in_subsequent_batch(
+ grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ const size_t buf_size = 102401;
+ char* buf = static_cast<char*>(gpr_malloc(buf_size * sizeof(*buf)));
+ memset(buf, 'a', buf_size - 1);
+ buf[buf_size - 1] = '\0';
+ // TODO(markdroth): buf is not a static string, so fix the next line
+ grpc_slice request_payload_slice = grpc_slice_from_static_string(buf);
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg args[2];
+ args[0].type = GRPC_ARG_STRING;
+ args[0].key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ args[0].value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ args[1].type = GRPC_ARG_INTEGER;
+ args[1].key = const_cast<char*>(GRPC_ARG_PER_RPC_RETRY_BUFFER_SIZE);
+ args[1].value.integer = 102400;
+ grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_exceeds_buffer_size_in_subsequent_batch",
+ &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+ gpr_free(buf);
+}
+
+void retry_exceeds_buffer_size_in_subsequent_batch(
+ grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_exceeds_buffer_size_in_subsequent_batch(config);
+}
+
+void retry_exceeds_buffer_size_in_subsequent_batch_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_non_retriable_status.cc b/test/core/end2end/tests/retry_non_retriable_status.cc
new file mode 100644
index 0000000000..6d59db0b04
--- /dev/null
+++ b/test/core/end2end/tests/retry_non_retriable_status.cc
@@ -0,0 +1,257 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we don't retry for non-retryable status codes.
+// - 1 retry allowed for ABORTED status
+// - first attempt gets INVALID_ARGUMENT, so no retry is done
+static void test_retry_non_retriable_status(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_non_retriable_status", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_INVALID_ARGUMENT;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_non_retriable_status(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_non_retriable_status(config);
+}
+
+void retry_non_retriable_status_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_recv_initial_metadata.cc b/test/core/end2end/tests/retry_recv_initial_metadata.cc
new file mode 100644
index 0000000000..14215e449c
--- /dev/null
+++ b/test/core/end2end/tests/retry_recv_initial_metadata.cc
@@ -0,0 +1,268 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that receiving initial metadata commits the call.
+// - 1 retry allowed for ABORTED status
+// - first attempt receives initial metadata before trailing metadata,
+// so no retry is done even though status was ABORTED
+static void test_retry_recv_initial_metadata(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_recv_initial_metadata", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ // Server sends initial metadata in its own batch, before sending
+ // trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_recv_initial_metadata(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_recv_initial_metadata(config);
+}
+
+void retry_recv_initial_metadata_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_recv_message.cc b/test/core/end2end/tests/retry_recv_message.cc
new file mode 100644
index 0000000000..86171fdc01
--- /dev/null
+++ b/test/core/end2end/tests/retry_recv_message.cc
@@ -0,0 +1,261 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that receiving a message commits the call.
+// - 1 retry allowed for ABORTED status
+// - first attempt receives a message and therefore does not retry even
+// though the final status is ABORTED
+static void test_retry_recv_message(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_recv_message", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = response_payload;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_recv_message(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_recv_message(config);
+}
+
+void retry_recv_message_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_server_pushback_delay.cc b/test/core/end2end/tests/retry_server_pushback_delay.cc
new file mode 100644
index 0000000000..1da986041f
--- /dev/null
+++ b/test/core/end2end/tests/retry_server_pushback_delay.cc
@@ -0,0 +1,318 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we honor server push-back delay.
+// - 2 retries allowed for ABORTED status
+// - first attempt gets ABORTED with a long delay
+// - second attempt succeeds
+static void test_retry_server_pushback_delay(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_metadata pushback_md;
+ memset(&pushback_md, 0, sizeof(pushback_md));
+ pushback_md.key = GRPC_MDSTR_GRPC_RETRY_PUSHBACK_MS;
+ pushback_md.value = grpc_slice_from_static_string("2000");
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_server_pushback_delay", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 1;
+ op->data.send_status_from_server.trailing_metadata = &pushback_md;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ gpr_timespec before_retry = gpr_now(GPR_CLOCK_MONOTONIC);
+
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ gpr_timespec after_retry = gpr_now(GPR_CLOCK_MONOTONIC);
+ gpr_timespec retry_delay = gpr_time_sub(after_retry, before_retry);
+ // Configured back-off was 1 second, server push-back said 2 seconds.
+ // To avoid flakiness, we allow some fudge factor here.
+ gpr_log(GPR_INFO, "retry delay was {.tv_sec=%" PRId64 ", .tv_nsec=%d}",
+ retry_delay.tv_sec, retry_delay.tv_nsec);
+ GPR_ASSERT(retry_delay.tv_sec >= 1);
+ if (retry_delay.tv_sec == 1) {
+ GPR_ASSERT(retry_delay.tv_nsec >= 900000000);
+ }
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_OK;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(202), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_OK);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 0);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_server_pushback_delay(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_server_pushback_delay(config);
+}
+
+void retry_server_pushback_delay_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_server_pushback_disabled.cc b/test/core/end2end/tests/retry_server_pushback_disabled.cc
new file mode 100644
index 0000000000..13d4f01eea
--- /dev/null
+++ b/test/core/end2end/tests/retry_server_pushback_disabled.cc
@@ -0,0 +1,306 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we don't retry when disabled by server push-back.
+// - 2 retries allowed for ABORTED status
+// - first attempt gets ABORTED
+// - second attempt gets ABORTED but server push back disables retrying
+static void test_retry_server_pushback_disabled(
+ grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_metadata pushback_md;
+ memset(&pushback_md, 0, sizeof(pushback_md));
+ pushback_md.key = GRPC_MDSTR_GRPC_RETRY_PUSHBACK_MS;
+ pushback_md.value = grpc_slice_from_static_string("-1");
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f = begin_test(
+ config, "retry_server_pushback_disabled", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 1;
+ op->data.send_status_from_server.trailing_metadata = &pushback_md;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(202), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_server_pushback_disabled(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_server_pushback_disabled(config);
+}
+
+void retry_server_pushback_disabled_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_streaming.cc b/test/core/end2end/tests/retry_streaming.cc
new file mode 100644
index 0000000000..e96e57e8bc
--- /dev/null
+++ b/test/core/end2end/tests/retry_streaming.cc
@@ -0,0 +1,424 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests retrying a streaming RPC. This is the same as
+// the basic retry test, except that the client sends two messages on the
+// call before the initial attempt fails.
+// FIXME: We should also test the case where the retry is committed after
+// replaying 1 of 2 previously-completed send_message ops. However,
+// there's no way to trigger that from an end2end test, because the
+// replayed ops happen under the hood -- they are not surfaced to the
+// C-core API, and therefore we have no way to inject the commit at the
+// right point.
+static void test_retry_streaming(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice request2_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_slice request3_payload_slice = grpc_slice_from_static_string("baz");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("quux");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* request2_payload =
+ grpc_raw_byte_buffer_create(&request2_payload_slice, 1);
+ grpc_byte_buffer* request3_payload =
+ grpc_raw_byte_buffer_create(&request3_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* request2_payload_recv = nullptr;
+ grpc_byte_buffer* request3_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_streaming", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ // Client starts a batch for receiving initial metadata, a message,
+ // and trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ // Client sends initial metadata and a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+ cq_verify(cqv);
+
+ // Server gets a call with received initial metadata.
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ // Server receives a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ // Client sends a second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request2_payload;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(3), true);
+ cq_verify(cqv);
+
+ // Server receives the second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request2_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+ cq_verify(cqv);
+
+ // Server sends both initial and trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(104), true);
+ cq_verify(cqv);
+
+ // Clean up from first attempt.
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+ GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
+ grpc_byte_buffer_destroy(request_payload_recv);
+ request_payload_recv = nullptr;
+ GPR_ASSERT(
+ byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice));
+ grpc_byte_buffer_destroy(request2_payload_recv);
+ request2_payload_recv = nullptr;
+
+ // Server gets a second call (the retry).
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ // Server receives a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(202), true);
+ cq_verify(cqv);
+
+ // Server receives a second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request2_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(203), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(203), true);
+ cq_verify(cqv);
+
+ // Client sends a third message and a close.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request3_payload;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(4), true);
+ cq_verify(cqv);
+
+ // Server receives a third message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request3_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(204), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(204), true);
+ cq_verify(cqv);
+
+ // Server receives a close and sends initial metadata, a message, and
+ // trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = response_payload;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ // Returning a retriable code, but because we are also sending a
+ // message, the client will commit instead of retrying again.
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(205), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(205), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(request2_payload);
+ grpc_byte_buffer_destroy(request3_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
+ grpc_byte_buffer_destroy(request_payload_recv);
+ GPR_ASSERT(
+ byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice));
+ grpc_byte_buffer_destroy(request2_payload_recv);
+ GPR_ASSERT(
+ byte_buffer_eq_slice(request3_payload_recv, request3_payload_slice));
+ grpc_byte_buffer_destroy(request3_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_streaming(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_streaming(config);
+}
+
+void retry_streaming_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_streaming_after_commit.cc b/test/core/end2end/tests/retry_streaming_after_commit.cc
new file mode 100644
index 0000000000..43eee86d95
--- /dev/null
+++ b/test/core/end2end/tests/retry_streaming_after_commit.cc
@@ -0,0 +1,354 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we can continue to send/recv messages on a streaming call
+// after retries are committed.
+static void test_retry_streaming_after_commit(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice request2_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("baz");
+ grpc_slice response2_payload_slice = grpc_slice_from_static_string("quux");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* request2_payload =
+ grpc_raw_byte_buffer_create(&request2_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* response2_payload =
+ grpc_raw_byte_buffer_create(&response2_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* request2_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_byte_buffer* response2_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_streaming_after_commit", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ // Client starts a batch for receiving initial metadata and a message.
+ // This will commit retries.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ // Client sends initial metadata and a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(3), true);
+ cq_verify(cqv);
+
+ // Server gets a call with received initial metadata.
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ // Server receives a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ // Server sends initial metadata and a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = response_payload;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+ // Client receives initial metadata and a message.
+ CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+ cq_verify(cqv);
+
+ // Client sends a second message and a close.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request2_payload;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(4), true);
+ cq_verify(cqv);
+
+ // Server receives a second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request2_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(104), true);
+ cq_verify(cqv);
+
+ // Server receives a close, sends a second message, and sends status.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = response2_payload;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ // Returning a retriable code, but because retries are already
+ // committed, the client will not retry.
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(105), true);
+ cq_verify(cqv);
+
+ // Client receives a second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response2_payload_recv;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(5), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(5), true);
+ cq_verify(cqv);
+
+ // Client receives status.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(request2_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(response2_payload);
+ GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
+ grpc_byte_buffer_destroy(request_payload_recv);
+ GPR_ASSERT(
+ byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice));
+ grpc_byte_buffer_destroy(request2_payload_recv);
+ GPR_ASSERT(
+ byte_buffer_eq_slice(response_payload_recv, response_payload_slice));
+ grpc_byte_buffer_destroy(response_payload_recv);
+ GPR_ASSERT(
+ byte_buffer_eq_slice(response2_payload_recv, response2_payload_slice));
+ grpc_byte_buffer_destroy(response2_payload_recv);
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_streaming_after_commit(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_streaming_after_commit(config);
+}
+
+void retry_streaming_after_commit_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc b/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
new file mode 100644
index 0000000000..5c92f64805
--- /dev/null
+++ b/test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc
@@ -0,0 +1,400 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we correctly clean up if the second attempt finishes
+// before we have finished replaying all of the send ops.
+static void test_retry_streaming_succeeds_before_replay_finished(
+ grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice request2_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_slice request3_payload_slice = grpc_slice_from_static_string("baz");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("quux");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* request2_payload =
+ grpc_raw_byte_buffer_create(&request2_payload_slice, 1);
+ grpc_byte_buffer* request3_payload =
+ grpc_raw_byte_buffer_create(&request3_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* request2_payload_recv = nullptr;
+ grpc_byte_buffer* request3_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 3,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_streaming", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ // Client starts a batch for receiving initial metadata, a message,
+ // and trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ // Client sends initial metadata and a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(2), true);
+ cq_verify(cqv);
+
+ // Server gets a call with received initial metadata.
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ // Server receives a message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ // Client sends a second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request2_payload;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(3), true);
+ cq_verify(cqv);
+
+ // Server receives the second message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request2_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(103), true);
+ cq_verify(cqv);
+
+ // Client sends a third message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request3_payload;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(4), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(4), true);
+ cq_verify(cqv);
+
+ // Server receives the third message.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request3_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(104), true);
+ cq_verify(cqv);
+
+ // Server sends both initial and trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(105), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(105), true);
+ cq_verify(cqv);
+
+ // Clean up from first attempt.
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+ GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
+ grpc_byte_buffer_destroy(request_payload_recv);
+ request_payload_recv = nullptr;
+ GPR_ASSERT(
+ byte_buffer_eq_slice(request2_payload_recv, request2_payload_slice));
+ grpc_byte_buffer_destroy(request2_payload_recv);
+ request2_payload_recv = nullptr;
+ GPR_ASSERT(
+ byte_buffer_eq_slice(request3_payload_recv, request3_payload_slice));
+ grpc_byte_buffer_destroy(request3_payload_recv);
+ request3_payload_recv = nullptr;
+
+ // Server gets a second call (the retry).
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ // Server receives the first message (and does not receive any others).
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &request_payload_recv;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(202), true);
+ cq_verify(cqv);
+
+ // Server sends initial metadata, a message, and trailing metadata.
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = response_payload;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ // Returning a retriable code, but because we are also sending a
+ // message, the client will commit instead of retrying again.
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(205), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(205), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(request2_payload);
+ grpc_byte_buffer_destroy(request3_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ GPR_ASSERT(byte_buffer_eq_slice(request_payload_recv, request_payload_slice));
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_streaming_succeeds_before_replay_finished(
+ grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_streaming_succeeds_before_replay_finished(config);
+}
+
+void retry_streaming_succeeds_before_replay_finished_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_throttled.cc b/test/core/end2end/tests/retry_throttled.cc
new file mode 100644
index 0000000000..8cd08487ea
--- /dev/null
+++ b/test/core/end2end/tests/retry_throttled.cc
@@ -0,0 +1,264 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we don't retry when throttled.
+// - 1 retry allowed for ABORTED status
+// - first attempt gets ABORTED but is over limit, so no retry is done
+static void test_retry_throttled(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ],\n"
+ // A single failure will cause us to be throttled.
+ // (This is not a very realistic config, but it works for the
+ // purposes of this test.)
+ " \"retryThrottling\": {\n"
+ " \"maxTokens\": 2,\n"
+ " \"tokenRatio\": 1.0,\n"
+ " }\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_throttled", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_throttled(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_throttled(config);
+}
+
+void retry_throttled_pre_init(void) {}
diff --git a/test/core/end2end/tests/retry_too_many_attempts.cc b/test/core/end2end/tests/retry_too_many_attempts.cc
new file mode 100644
index 0000000000..5225c9b229
--- /dev/null
+++ b/test/core/end2end/tests/retry_too_many_attempts.cc
@@ -0,0 +1,299 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/tests/cancel_test_helpers.h"
+
+static void* tag(intptr_t t) { return (void*)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+ const char* test_name,
+ grpc_channel_args* client_args,
+ grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f;
+ gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
+ f = config.create_fixture(client_args, server_args);
+ config.init_server(&f, server_args);
+ config.init_client(&f, client_args);
+ return f;
+}
+
+static gpr_timespec n_seconds_from_now(int n) {
+ return grpc_timeout_seconds_to_deadline(n);
+}
+
+static gpr_timespec five_seconds_from_now(void) {
+ return n_seconds_from_now(5);
+}
+
+static void drain_cq(grpc_completion_queue* cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture* f) {
+ if (!f->server) return;
+ grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
+ GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
+ grpc_timeout_seconds_to_deadline(5),
+ nullptr)
+ .type == GRPC_OP_COMPLETE);
+ grpc_server_destroy(f->server);
+ f->server = nullptr;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture* f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = nullptr;
+}
+
+static void end_test(grpc_end2end_test_fixture* f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+ grpc_completion_queue_destroy(f->shutdown_cq);
+}
+
+// Tests that we stop retrying after the configured number of attempts.
+// - 1 retry allowed for ABORTED status
+// - first attempt gets ABORTED
+// - second attempt gets ABORTED but does not retry
+static void test_retry_too_many_attempts(grpc_end2end_test_config config) {
+ grpc_call* c;
+ grpc_call* s;
+ grpc_op ops[6];
+ grpc_op* op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_slice request_payload_slice = grpc_slice_from_static_string("foo");
+ grpc_slice response_payload_slice = grpc_slice_from_static_string("bar");
+ grpc_byte_buffer* request_payload =
+ grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+ grpc_byte_buffer* response_payload =
+ grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+ grpc_byte_buffer* request_payload_recv = nullptr;
+ grpc_byte_buffer* response_payload_recv = nullptr;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+ char* peer;
+
+ grpc_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
+ arg.value.string = const_cast<char*>(
+ "{\n"
+ " \"methodConfig\": [ {\n"
+ " \"name\": [\n"
+ " { \"service\": \"service\", \"method\": \"method\" }\n"
+ " ],\n"
+ " \"retryPolicy\": {\n"
+ " \"maxAttempts\": 2,\n"
+ " \"initialBackoff\": \"1s\",\n"
+ " \"maxBackoff\": \"120s\",\n"
+ " \"backoffMultiplier\": 1.6,\n"
+ " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
+ " }\n"
+ " } ]\n"
+ "}");
+ grpc_channel_args client_args = {1, &arg};
+ grpc_end2end_test_fixture f =
+ begin_test(config, "retry_too_many_attempts", &client_args, nullptr);
+
+ cq_verifier* cqv = cq_verifier_create(f.cq);
+
+ gpr_timespec deadline = five_seconds_from_now();
+ c = grpc_channel_create_call(
+ f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/service/method"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ nullptr);
+ GPR_ASSERT(c);
+
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer);
+ gpr_free(peer);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_MESSAGE;
+ op->data.send_message.send_message = request_payload;
+ op++;
+ op->op = GRPC_OP_RECV_MESSAGE;
+ op->data.recv_message.recv_message = &response_payload_recv;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ grpc_call_unref(s);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_details_init(&call_details);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(201));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(201), true);
+ cq_verify(cqv);
+
+ peer = grpc_call_get_peer(s);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "server_peer=%s", peer);
+ gpr_free(peer);
+ peer = grpc_call_get_peer(c);
+ GPR_ASSERT(peer != nullptr);
+ gpr_log(GPR_DEBUG, "client_peer=%s", peer);
+ gpr_free(peer);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_ABORTED;
+ op->data.send_status_from_server.status_details = &status_details;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), nullptr);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(202), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ GPR_ASSERT(status == GRPC_STATUS_ABORTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/service/method"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(0 == call_details.flags);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_byte_buffer_destroy(request_payload);
+ grpc_byte_buffer_destroy(response_payload);
+ grpc_byte_buffer_destroy(request_payload_recv);
+ grpc_byte_buffer_destroy(response_payload_recv);
+
+ grpc_call_unref(c);
+ grpc_call_unref(s);
+
+ cq_verifier_destroy(cqv);
+
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void retry_too_many_attempts(grpc_end2end_test_config config) {
+ GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL);
+ test_retry_too_many_attempts(config);
+}
+
+void retry_too_many_attempts_pre_init(void) {}
diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD
index 9aa74cc132..4032664b59 100644
--- a/test/core/gpr/BUILD
+++ b/test/core/gpr/BUILD
@@ -29,6 +29,16 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "arena_test",
+ srcs = ["arena_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//test/core/util:gpr_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "cpu_test",
srcs = ["cpu_test.cc"],
language = "C++",
diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc
index c10d7eaff7..9eaf57b631 100644
--- a/test/core/gpr/arena_test.cc
+++ b/test/core/gpr/arena_test.cc
@@ -22,11 +22,11 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <inttypes.h>
#include <string.h>
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/gpr/cpu_test.cc b/test/core/gpr/cpu_test.cc
index 46a168665c..9f2c3f1923 100644
--- a/test/core/gpr/cpu_test.cc
+++ b/test/core/gpr/cpu_test.cc
@@ -25,10 +25,11 @@
#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <string.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/test_config.h"
/* Test structure is essentially:
diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc
index 333390e928..96813466c9 100644
--- a/test/core/gpr/mpscq_test.cc
+++ b/test/core/gpr/mpscq_test.cc
@@ -23,8 +23,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/gpr/spinlock_test.cc b/test/core/gpr/spinlock_test.cc
index cd6de69126..9f182bc154 100644
--- a/test/core/gpr/spinlock_test.cc
+++ b/test/core/gpr/spinlock_test.cc
@@ -22,10 +22,11 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <stdlib.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/test_config.h"
/* ------------------------------------------------- */
diff --git a/test/core/gpr/sync_test.cc b/test/core/gpr/sync_test.cc
index 39ff8852b6..bafd91020b 100644
--- a/test/core/gpr/sync_test.cc
+++ b/test/core/gpr/sync_test.cc
@@ -21,10 +21,11 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <stdlib.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/test_config.h"
/* ==================Example use of interface===================
diff --git a/test/core/gpr/thd_test.cc b/test/core/gpr/thd_test.cc
index b755bf18f3..18bbaae6c9 100644
--- a/test/core/gpr/thd_test.cc
+++ b/test/core/gpr/thd_test.cc
@@ -18,12 +18,14 @@
/* Test of gpr thread support. */
+#include "src/core/lib/gpr/thd.h"
+
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <stdio.h>
#include <stdlib.h>
+
#include "test/core/util/test_config.h"
#define NUM_THREADS 300
diff --git a/test/core/gpr/time_test.cc b/test/core/gpr/time_test.cc
index ef7a961d0a..e6bcc1247d 100644
--- a/test/core/gpr/time_test.cc
+++ b/test/core/gpr/time_test.cc
@@ -20,12 +20,13 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/test_config.h"
static void to_fp(void* arg, const char* buf, size_t len) {
diff --git a/test/core/gpr/tls_test.cc b/test/core/gpr/tls_test.cc
index 1ef253ed6f..1e4534dc5a 100644
--- a/test/core/gpr/tls_test.cc
+++ b/test/core/gpr/tls_test.cc
@@ -20,10 +20,10 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <stdio.h>
#include <stdlib.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/tls.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/gprpp/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc
index f06c3cab06..74777fe11c 100644
--- a/test/core/gprpp/manual_constructor_test.cc
+++ b/test/core/gprpp/manual_constructor_test.cc
@@ -22,10 +22,11 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gprpp/abstract.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/handshake/client_ssl.cc b/test/core/handshake/client_ssl.cc
index 088df3845e..fe2ab251e3 100644
--- a/test/core/handshake/client_ssl.cc
+++ b/test/core/handshake/client_ssl.cc
@@ -34,7 +34,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/handshake/readahead_handshaker_server_ssl.cc b/test/core/handshake/readahead_handshaker_server_ssl.cc
index fa3ee0bc1e..80000ca8d3 100644
--- a/test/core/handshake/readahead_handshaker_server_ssl.cc
+++ b/test/core/handshake/readahead_handshaker_server_ssl.cc
@@ -29,7 +29,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/handshake/server_ssl.cc b/test/core/handshake/server_ssl.cc
index 736d3e578e..f0465c8e3e 100644
--- a/test/core/handshake/server_ssl.cc
+++ b/test/core/handshake/server_ssl.cc
@@ -29,7 +29,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/handshake/server_ssl_common.cc b/test/core/handshake/server_ssl_common.cc
index 6f1a097dbd..d202a7cfd6 100644
--- a/test/core/handshake/server_ssl_common.cc
+++ b/test/core/handshake/server_ssl_common.cc
@@ -31,7 +31,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/handshake/server_ssl_common.h b/test/core/handshake/server_ssl_common.h
index 77865a408f..f726a1cd3a 100644
--- a/test/core/handshake/server_ssl_common.h
+++ b/test/core/handshake/server_ssl_common.h
@@ -25,7 +25,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD
index 41e2607646..349a06d578 100644
--- a/test/core/iomgr/BUILD
+++ b/test/core/iomgr/BUILD
@@ -60,6 +60,19 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "error_test",
+ srcs = ["error_test.cc"],
+ language = "C++",
+ deps = [
+ ":endpoint_tests",
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "ev_epollsig_linux_test",
srcs = ["ev_epollsig_linux_test.cc"],
deps = [
diff --git a/test/core/iomgr/combiner_test.cc b/test/core/iomgr/combiner_test.cc
index eb926cc620..8426b3d233 100644
--- a/test/core/iomgr/combiner_test.cc
+++ b/test/core/iomgr/combiner_test.cc
@@ -21,8 +21,8 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc
index 064ce0a6b2..f6292b72a9 100644
--- a/test/core/iomgr/error_test.cc
+++ b/test/core/iomgr/error_test.cc
@@ -21,10 +21,10 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <string.h>
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/test_config.h"
static void test_set_get_int() {
diff --git a/test/core/iomgr/ev_epollsig_linux_test.cc b/test/core/iomgr/ev_epollsig_linux_test.cc
index 5ae68d2e47..02d11271ec 100644
--- a/test/core/iomgr/ev_epollsig_linux_test.cc
+++ b/test/core/iomgr/ev_epollsig_linux_test.cc
@@ -29,8 +29,8 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc
index 92d2338a02..341579f178 100644
--- a/test/core/iomgr/resolve_address_posix_test.cc
+++ b/test/core/iomgr/resolve_address_posix_test.cc
@@ -25,9 +25,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr.h"
diff --git a/test/core/iomgr/wakeup_fd_cv_test.cc b/test/core/iomgr/wakeup_fd_cv_test.cc
index a3f3f2008b..68dcb50aa6 100644
--- a/test/core/iomgr/wakeup_fd_cv_test.cc
+++ b/test/core/iomgr/wakeup_fd_cv_test.cc
@@ -23,10 +23,10 @@
#include <pthread.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr_posix.h"
diff --git a/test/core/network_benchmarks/low_level_ping_pong.cc b/test/core/network_benchmarks/low_level_ping_pong.cc
index 52c423b14a..33716b9d4a 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.cc
+++ b/test/core/network_benchmarks/low_level_ping_pong.cc
@@ -36,9 +36,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/socket_utils_posix.h"
diff --git a/test/core/security/BUILD b/test/core/security/BUILD
index 425c617fd1..9776e6d5fd 100644
--- a/test/core/security/BUILD
+++ b/test/core/security/BUILD
@@ -24,7 +24,7 @@ grpc_fuzzer(
name = "ssl_server_fuzzer",
srcs = ["ssl_server_fuzzer.cc"],
language = "C++",
- corpus = "corpus",
+ corpus = "corpus/ssl_server_corpus",
deps = [
"//:gpr",
"//:grpc",
@@ -67,6 +67,31 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "json_token_test",
+ srcs = ["json_token_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "jwt_verifier_test",
+ srcs = ["jwt_verifier_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+
+grpc_cc_test(
name = "secure_endpoint_test",
srcs = ["secure_endpoint_test.cc"],
language = "C++",
diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc
index e4731fb039..ed3849bfc8 100644
--- a/test/core/security/security_connector_test.cc
+++ b/test/core/security/security_connector_test.cc
@@ -28,7 +28,7 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/tmpfile.h"
#include "src/core/lib/security/context/security_context.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security.h"
diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc
index 6e30698562..cb74e3bae1 100644
--- a/test/core/security/ssl_server_fuzzer.cc
+++ b/test/core/security/ssl_server_fuzzer.cc
@@ -22,7 +22,7 @@
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/memory_counters.h"
#include "test/core/util/mock_endpoint.h"
diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD
index ba2b553e0b..9a1a506a43 100644
--- a/test/core/slice/BUILD
+++ b/test/core/slice/BUILD
@@ -23,8 +23,8 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
grpc_fuzzer(
name = "percent_encode_fuzzer",
srcs = ["percent_encode_fuzzer.cc"],
- language = "C++",
corpus = "percent_encode_corpus",
+ language = "C++",
deps = [
"//:gpr",
"//:grpc",
@@ -35,8 +35,8 @@ grpc_fuzzer(
grpc_fuzzer(
name = "percent_decode_fuzzer",
srcs = ["percent_decode_fuzzer.cc"],
- language = "C++",
corpus = "percent_decode_corpus",
+ language = "C++",
deps = [
"//:gpr",
"//:grpc",
@@ -59,8 +59,13 @@ grpc_cc_test(
grpc_cc_test(
name = "slice_test",
srcs = ["slice_test.cc"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_cc_test(
@@ -78,15 +83,43 @@ grpc_cc_test(
grpc_cc_test(
name = "slice_buffer_test",
srcs = ["slice_buffer_test.cc"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_cc_test(
name = "slice_hash_table_test",
srcs = ["slice_hash_table_test.cc"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+ external_deps = [
+ "gtest",
+ ],
language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
+ name = "slice_weak_hash_table_test",
+ srcs = ["slice_weak_hash_table_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_cc_test(
diff --git a/test/core/slice/slice_hash_table_test.cc b/test/core/slice/slice_hash_table_test.cc
index 9fad9a614e..279b543098 100644
--- a/test/core/slice/slice_hash_table_test.cc
+++ b/test/core/slice/slice_hash_table_test.cc
@@ -20,6 +20,10 @@
#include <string.h>
+#include <vector>
+
+#include <gtest/gtest.h>
+
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -27,56 +31,55 @@
#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
-typedef struct {
- const char* key;
- const char* value;
-} test_entry;
+namespace grpc_core {
+namespace {
-static void populate_entries(const test_entry* input, size_t num_entries,
- grpc_slice_hash_table_entry* output) {
- for (size_t i = 0; i < num_entries; ++i) {
- output[i].key = grpc_slice_from_copied_string(input[i].key);
- output[i].value = gpr_strdup(input[i].value);
- }
-}
+typedef SliceHashTable<UniquePtr<char>> TestHashTable;
-static void check_values(const test_entry* input, size_t num_entries,
- grpc_slice_hash_table* table) {
- for (size_t i = 0; i < num_entries; ++i) {
- grpc_slice key = grpc_slice_from_static_string(input[i].key);
- const char* actual =
- static_cast<const char*>(grpc_slice_hash_table_get(table, key));
- GPR_ASSERT(actual != nullptr);
- GPR_ASSERT(strcmp(actual, input[i].value) == 0);
+struct TestEntry {
+ const char* key;
+ const char* value;
+};
+
+void CheckValues(const std::vector<TestEntry>& input,
+ const TestHashTable& table) {
+ for (const TestEntry& expected : input) {
+ grpc_slice key = grpc_slice_from_static_string(expected.key);
+ const UniquePtr<char>* actual = table.Get(key);
+ ASSERT_NE(actual, nullptr);
+ EXPECT_STREQ(expected.value, actual->get());
grpc_slice_unref(key);
}
}
-static void check_non_existent_value(const char* key_string,
- grpc_slice_hash_table* table) {
+void CheckNonExistentValue(const char* key_string, const TestHashTable& table) {
grpc_slice key = grpc_slice_from_static_string(key_string);
- GPR_ASSERT(grpc_slice_hash_table_get(table, key) == nullptr);
+ ASSERT_EQ(nullptr, table.Get(key));
grpc_slice_unref(key);
}
-static void destroy_string(void* value) { gpr_free(value); }
-
-static grpc_slice_hash_table* create_table_from_entries(
- const test_entry* test_entries, size_t num_test_entries,
- int (*value_cmp_fn)(void*, void*)) {
- // Construct table.
- grpc_slice_hash_table_entry* entries =
- static_cast<grpc_slice_hash_table_entry*>(
- gpr_zalloc(sizeof(*entries) * num_test_entries));
- populate_entries(test_entries, num_test_entries, entries);
- grpc_slice_hash_table* table = grpc_slice_hash_table_create(
- num_test_entries, entries, destroy_string, value_cmp_fn);
+void PopulateEntries(const std::vector<TestEntry>& input,
+ TestHashTable::Entry* output) {
+ for (size_t i = 0; i < input.size(); ++i) {
+ output[i].key = grpc_slice_from_copied_string(input[i].key);
+ output[i].value = UniquePtr<char>(gpr_strdup(input[i].value));
+ }
+}
+
+RefCountedPtr<TestHashTable> CreateTableFromEntries(
+ const std::vector<TestEntry>& test_entries,
+ TestHashTable::ValueCmp value_cmp) {
+ TestHashTable::Entry* entries = static_cast<TestHashTable::Entry*>(
+ gpr_zalloc(sizeof(*entries) * test_entries.size()));
+ PopulateEntries(test_entries, entries);
+ RefCountedPtr<TestHashTable> table =
+ TestHashTable::Create(test_entries.size(), entries, value_cmp);
gpr_free(entries);
return table;
}
-static void test_slice_hash_table() {
- const test_entry test_entries[] = {
+TEST(SliceHashTable, Basic) {
+ const std::vector<TestEntry> test_entries = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"},
{"key_3", "value_3"}, {"key_4", "value_4"}, {"key_5", "value_5"},
{"key_6", "value_6"}, {"key_7", "value_7"}, {"key_8", "value_8"},
@@ -112,129 +115,110 @@ static void test_slice_hash_table() {
{"key_96", "value_96"}, {"key_97", "value_97"}, {"key_98", "value_98"},
{"key_99", "value_99"},
};
- const size_t num_entries = GPR_ARRAY_SIZE(test_entries);
- grpc_slice_hash_table* table =
- create_table_from_entries(test_entries, num_entries, nullptr);
+ RefCountedPtr<TestHashTable> table =
+ CreateTableFromEntries(test_entries, nullptr);
// Check contents of table.
- check_values(test_entries, num_entries, table);
- check_non_existent_value("XX", table);
- // Clean up.
- grpc_core::ExecCtx exec_ctx;
- grpc_slice_hash_table_unref(table);
+ CheckValues(test_entries, *table);
+ CheckNonExistentValue("XX", *table);
}
-static int value_cmp_fn(void* a, void* b) {
- const char* a_str = static_cast<const char*>(a);
- const char* b_str = static_cast<const char*>(b);
- return strcmp(a_str, b_str);
+int StringCmp(const UniquePtr<char>& a, const UniquePtr<char>& b) {
+ return strcmp(a.get(), b.get());
}
-static int pointer_cmp_fn(void* a, void* b) { return GPR_ICMP(a, b); }
+int PointerCmp(const UniquePtr<char>& a, const UniquePtr<char>& b) {
+ return GPR_ICMP(a.get(), b.get());
+}
-static void test_slice_hash_table_eq() {
- const test_entry test_entries_a[] = {
+TEST(SliceHashTable, CmpEqual) {
+ const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_a = GPR_ARRAY_SIZE(test_entries_a);
- grpc_slice_hash_table* table_a =
- create_table_from_entries(test_entries_a, num_entries_a, value_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_a) == 0);
-
- const test_entry test_entries_b[] = {
+ RefCountedPtr<TestHashTable> table_a =
+ CreateTableFromEntries(test_entries_a, StringCmp);
+ const std::vector<TestEntry> test_entries_b = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_b = GPR_ARRAY_SIZE(test_entries_b);
- grpc_slice_hash_table* table_b =
- create_table_from_entries(test_entries_b, num_entries_b, value_cmp_fn);
-
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b) == 0);
- grpc_core::ExecCtx exec_ctx;
- grpc_slice_hash_table_unref(table_a);
- grpc_slice_hash_table_unref(table_b);
+ RefCountedPtr<TestHashTable> table_b =
+ CreateTableFromEntries(test_entries_b, StringCmp);
+ // table_a equals itself.
+ EXPECT_EQ(0, TestHashTable::Cmp(*table_a, *table_a));
+ // table_a equals table_b.
+ EXPECT_EQ(0, TestHashTable::Cmp(*table_a, *table_b));
}
-static void test_slice_hash_table_not_eq() {
- const test_entry test_entries_a[] = {
+TEST(SliceHashTable, CmpDifferentSizes) {
+ // table_a has 3 entries, table_b has only 2.
+ const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_a = GPR_ARRAY_SIZE(test_entries_a);
- grpc_slice_hash_table* table_a =
- create_table_from_entries(test_entries_a, num_entries_a, value_cmp_fn);
-
- // Different sizes.
- const test_entry test_entries_b_smaller[] = {{"key_0", "value_0"},
- {"key_1", "value_1"}};
- const size_t num_entries_b_smaller = GPR_ARRAY_SIZE(test_entries_b_smaller);
- grpc_slice_hash_table* table_b_smaller = create_table_from_entries(
- test_entries_b_smaller, num_entries_b_smaller, value_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b_smaller) > 0);
-
- const test_entry test_entries_b_larger[] = {{"key_0", "value_0"},
- {"key_1", "value_1"},
- {"key_2", "value_2"},
- {"key_3", "value_3"}};
- const size_t num_entries_b_larger = GPR_ARRAY_SIZE(test_entries_b_larger);
- grpc_slice_hash_table* table_b_larger = create_table_from_entries(
- test_entries_b_larger, num_entries_b_larger, value_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_b_larger) < 0);
+ RefCountedPtr<TestHashTable> table_a =
+ CreateTableFromEntries(test_entries_a, StringCmp);
+ const std::vector<TestEntry> test_entries_b = {{"key_0", "value_0"},
+ {"key_1", "value_1"}};
+ RefCountedPtr<TestHashTable> table_b =
+ CreateTableFromEntries(test_entries_b, StringCmp);
+ EXPECT_GT(TestHashTable::Cmp(*table_a, *table_b), 0);
+ EXPECT_LT(TestHashTable::Cmp(*table_b, *table_a), 0);
+}
+TEST(SliceHashTable, CmpDifferentKey) {
// One key doesn't match and is lexicographically "smaller".
- const test_entry test_entries_c[] = {
+ const std::vector<TestEntry> test_entries_a = {
+ {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
+ RefCountedPtr<TestHashTable> table_a =
+ CreateTableFromEntries(test_entries_a, StringCmp);
+ const std::vector<TestEntry> test_entries_b = {
{"key_zz", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_c = GPR_ARRAY_SIZE(test_entries_c);
- grpc_slice_hash_table* table_c =
- create_table_from_entries(test_entries_c, num_entries_c, value_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_c) > 0);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_c, table_a) < 0);
+ RefCountedPtr<TestHashTable> table_b =
+ CreateTableFromEntries(test_entries_b, StringCmp);
+ EXPECT_GT(TestHashTable::Cmp(*table_a, *table_b), 0);
+ EXPECT_LT(TestHashTable::Cmp(*table_b, *table_a), 0);
+}
+TEST(SliceHashTable, CmpDifferentValue) {
// One value doesn't match.
- const test_entry test_entries_d[] = {
+ const std::vector<TestEntry> test_entries_a = {
+ {"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
+ RefCountedPtr<TestHashTable> table_a =
+ CreateTableFromEntries(test_entries_a, StringCmp);
+ const std::vector<TestEntry> test_entries_b = {
{"key_0", "value_z"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_d = GPR_ARRAY_SIZE(test_entries_d);
- grpc_slice_hash_table* table_d =
- create_table_from_entries(test_entries_d, num_entries_d, value_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_a, table_d) < 0);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_d, table_a) > 0);
+ RefCountedPtr<TestHashTable> table_b =
+ CreateTableFromEntries(test_entries_b, StringCmp);
+ EXPECT_LT(TestHashTable::Cmp(*table_a, *table_b), 0);
+ EXPECT_GT(TestHashTable::Cmp(*table_b, *table_a), 0);
+}
+TEST(SliceHashTable, CmpDifferentCmpFunctions) {
// Same values but different "equals" functions.
- const test_entry test_entries_e[] = {
+ const std::vector<TestEntry> test_entries_a = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_e = GPR_ARRAY_SIZE(test_entries_e);
- grpc_slice_hash_table* table_e =
- create_table_from_entries(test_entries_e, num_entries_e, value_cmp_fn);
- const test_entry test_entries_f[] = {
+ RefCountedPtr<TestHashTable> table_a =
+ CreateTableFromEntries(test_entries_a, StringCmp);
+ const std::vector<TestEntry> test_entries_b = {
{"key_0", "value_0"}, {"key_1", "value_1"}, {"key_2", "value_2"}};
- const size_t num_entries_f = GPR_ARRAY_SIZE(test_entries_f);
- grpc_slice_hash_table* table_f =
- create_table_from_entries(test_entries_f, num_entries_f, pointer_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_e, table_f) != 0);
+ RefCountedPtr<TestHashTable> table_b =
+ CreateTableFromEntries(test_entries_b, PointerCmp);
+ EXPECT_NE(TestHashTable::Cmp(*table_a, *table_b), 0);
+}
+TEST(SliceHashTable, CmpEmptyKeysDifferentValue) {
// Same (empty) key, different values.
- const test_entry test_entries_g[] = {{"", "value_0"}};
- const size_t num_entries_g = GPR_ARRAY_SIZE(test_entries_g);
- grpc_slice_hash_table* table_g =
- create_table_from_entries(test_entries_g, num_entries_g, value_cmp_fn);
- const test_entry test_entries_h[] = {{"", "value_1"}};
- const size_t num_entries_h = GPR_ARRAY_SIZE(test_entries_h);
- grpc_slice_hash_table* table_h =
- create_table_from_entries(test_entries_h, num_entries_h, pointer_cmp_fn);
- GPR_ASSERT(grpc_slice_hash_table_cmp(table_g, table_h) != 0);
-
- grpc_core::ExecCtx exec_ctx;
- grpc_slice_hash_table_unref(table_a);
- grpc_slice_hash_table_unref(table_b_larger);
- grpc_slice_hash_table_unref(table_b_smaller);
- grpc_slice_hash_table_unref(table_c);
- grpc_slice_hash_table_unref(table_d);
- grpc_slice_hash_table_unref(table_e);
- grpc_slice_hash_table_unref(table_f);
- grpc_slice_hash_table_unref(table_g);
- grpc_slice_hash_table_unref(table_h);
+ const std::vector<TestEntry> test_entries_a = {{"", "value_0"}};
+ RefCountedPtr<TestHashTable> table_a =
+ CreateTableFromEntries(test_entries_a, StringCmp);
+ const std::vector<TestEntry> test_entries_b = {{"", "value_1"}};
+ RefCountedPtr<TestHashTable> table_b =
+ CreateTableFromEntries(test_entries_b, PointerCmp);
+ EXPECT_NE(TestHashTable::Cmp(*table_a, *table_b), 0);
}
+} // namespace
+} // namespace grpc_core
+
int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
grpc_test_init(argc, argv);
grpc_core::ExecCtx::GlobalInit();
- test_slice_hash_table();
- test_slice_hash_table_eq();
- test_slice_hash_table_not_eq();
+ int result = RUN_ALL_TESTS();
grpc_core::ExecCtx::GlobalShutdown();
- return 0;
+ return result;
}
diff --git a/test/core/slice/slice_weak_hash_table_test.cc b/test/core/slice/slice_weak_hash_table_test.cc
new file mode 100644
index 0000000000..4711d2fd26
--- /dev/null
+++ b/test/core/slice/slice_weak_hash_table_test.cc
@@ -0,0 +1,105 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/slice/slice_weak_hash_table.h"
+
+#include <cstring>
+#include <sstream>
+
+#include <gtest/gtest.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/gpr/useful.h"
+#include "src/core/lib/slice/slice_internal.h"
+#include "test/core/util/test_config.h"
+
+namespace grpc_core {
+namespace {
+
+grpc_slice BuildRefCountedKey(const char* key_str) {
+ const size_t key_length = strlen(key_str);
+ grpc_slice key = grpc_slice_malloc_large(key_length);
+ memcpy(GRPC_SLICE_START_PTR(key), key_str, key_length);
+ return key;
+}
+
+TEST(SliceWeakHashTable, Basic) {
+ auto table = SliceWeakHashTable<UniquePtr<char>, 10>::Create();
+ // Single key-value insertion.
+ grpc_slice key = BuildRefCountedKey("key");
+ grpc_slice_ref(key); // Get doesn't own.
+ table->Add(key, UniquePtr<char>(gpr_strdup("value")));
+ ASSERT_NE(table->Get(key), nullptr);
+ ASSERT_STREQ(table->Get(key)->get(), "value");
+ grpc_slice_unref(key);
+ // Unknown key.
+ ASSERT_EQ(table->Get(grpc_slice_from_static_string("unknown_key")), nullptr);
+}
+
+TEST(SliceWeakHashTable, ValueTypeConstructor) {
+ struct Value {
+ Value() : a(123) {}
+ int a;
+ };
+ auto table = SliceWeakHashTable<Value, 1>::Create();
+ grpc_slice key = BuildRefCountedKey("key");
+ grpc_slice_ref(key); // Get doesn't own.
+ table->Add(key, Value());
+ ASSERT_EQ(table->Get(key)->a, 123);
+ grpc_slice_unref(key);
+}
+
+TEST(SliceWeakHashTable, ForceOverload) {
+ constexpr int kTableSize = 10;
+ auto table = SliceWeakHashTable<UniquePtr<char>, kTableSize>::Create();
+ // Insert a multiple of the maximum size table.
+ for (int i = 0; i < kTableSize * 2; ++i) {
+ std::ostringstream oss;
+ oss << "key-" << i;
+ grpc_slice key = BuildRefCountedKey(oss.str().c_str());
+ oss.clear();
+ oss << "value-" << i;
+ table->Add(key, UniquePtr<char>(gpr_strdup(oss.str().c_str())));
+ }
+ // Verify that some will have been replaced.
+ int num_missing = 0;
+ for (int i = 0; i < kTableSize * 2; ++i) {
+ std::ostringstream oss;
+ oss << "key-" << i;
+ grpc_slice key = BuildRefCountedKey(oss.str().c_str());
+ if (table->Get(key) == nullptr) num_missing++;
+ grpc_slice_unref(key);
+ }
+ // At least kTableSize elements will be missing.
+ ASSERT_GE(num_missing, kTableSize);
+}
+
+} // namespace
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ grpc_test_init(argc, argv);
+ grpc_core::ExecCtx::GlobalInit();
+ int result = RUN_ALL_TESTS();
+ grpc_core::ExecCtx::GlobalShutdown();
+ return result;
+}
diff --git a/test/core/statistics/rpc_stats_test.cc b/test/core/statistics/rpc_stats_test.cc
index aead5cfdca..ff48075365 100644
--- a/test/core/statistics/rpc_stats_test.cc
+++ b/test/core/statistics/rpc_stats_test.cc
@@ -22,11 +22,12 @@
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/string.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+
#include "src/core/ext/census/census_interface.h"
#include "src/core/ext/census/census_rpc_stats.h"
#include "src/core/ext/census/census_tracing.h"
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/test_config.h"
/* Ensure all possible state transitions are called without causing problem */
diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD
index d27123d1a3..e848dded13 100644
--- a/test/core/surface/BUILD
+++ b/test/core/surface/BUILD
@@ -55,6 +55,18 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "completion_queue_threading_test",
+ srcs = ["completion_queue_threading_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "concurrent_connectivity_test",
srcs = ["concurrent_connectivity_test.cc"],
language = "C++",
@@ -104,6 +116,19 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "num_external_connectivity_watchers_test",
+ srcs = ["num_external_connectivity_watchers_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/end2end:ssl_test_data",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+grpc_cc_test(
name = "public_headers_must_be_c89",
srcs = ["public_headers_must_be_c89.c"],
language = "C",
diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc
index 648a9d6986..861ed5d1a8 100644
--- a/test/core/surface/byte_buffer_reader_test.cc
+++ b/test/core/surface/byte_buffer_reader_test.cc
@@ -23,10 +23,10 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/compression/message_compress.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/surface/completion_queue_threading_test.cc b/test/core/surface/completion_queue_threading_test.cc
index e5015723f7..81319f4df4 100644
--- a/test/core/surface/completion_queue_threading_test.cc
+++ b/test/core/surface/completion_queue_threading_test.cc
@@ -20,9 +20,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc
index bbee073c71..95af4abd48 100644
--- a/test/core/surface/concurrent_connectivity_test.cc
+++ b/test/core/surface/concurrent_connectivity_test.cc
@@ -29,8 +29,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/resolve_address.h"
diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc
index e48fd7fcf2..49d28ad1c7 100644
--- a/test/core/surface/num_external_connectivity_watchers_test.cc
+++ b/test/core/surface/num_external_connectivity_watchers_test.cc
@@ -20,10 +20,10 @@
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index 14267c1214..bd4dc0b60e 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -53,7 +53,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/sync_custom.h>
#include <grpc/support/sync_generic.h>
-#include <grpc/support/thd.h>
+#include <grpc/support/thd_id.h>
#include <grpc/support/time.h>
#include <grpc/support/workaround_list.h>
@@ -268,14 +268,7 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) gpr_stats_init);
printf("%lx", (unsigned long) gpr_stats_inc);
printf("%lx", (unsigned long) gpr_stats_read);
- printf("%lx", (unsigned long) gpr_thd_new);
- printf("%lx", (unsigned long) gpr_thd_options_default);
- printf("%lx", (unsigned long) gpr_thd_options_set_detached);
- printf("%lx", (unsigned long) gpr_thd_options_set_joinable);
- printf("%lx", (unsigned long) gpr_thd_options_is_detached);
- printf("%lx", (unsigned long) gpr_thd_options_is_joinable);
printf("%lx", (unsigned long) gpr_thd_currentid);
- printf("%lx", (unsigned long) gpr_thd_join);
printf("%lx", (unsigned long) gpr_time_0);
printf("%lx", (unsigned long) gpr_inf_future);
printf("%lx", (unsigned long) gpr_inf_past);
diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc
index c10d6796a7..06962179a2 100644
--- a/test/core/surface/secure_channel_create_test.cc
+++ b/test/core/surface/secure_channel_create_test.cc
@@ -23,7 +23,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/surface/channel.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc
index 1ac0a5ee13..428d17ff1b 100644
--- a/test/core/surface/sequential_connectivity_test.cc
+++ b/test/core/surface/sequential_connectivity_test.cc
@@ -20,10 +20,10 @@
#include <grpc/grpc_security.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD
index b31d4ff899..2c2d05b9ae 100644
--- a/test/core/transport/BUILD
+++ b/test/core/transport/BUILD
@@ -119,3 +119,15 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
+
+grpc_cc_test(
+ name = "status_metadata_test",
+ srcs = ["status_metadata_test.cc"],
+ language = "C++",
+ deps = [
+ "//:grpc",
+ ],
+ external_deps = [
+ "gtest",
+ ],
+)
diff --git a/test/core/transport/chttp2/bin_decoder_test.cc b/test/core/transport/chttp2/bin_decoder_test.cc
index 283eebbacf..751dd90c8c 100644
--- a/test/core/transport/chttp2/bin_decoder_test.cc
+++ b/test/core/transport/chttp2/bin_decoder_test.cc
@@ -67,6 +67,16 @@ static grpc_slice base64_decode_with_length(const char* s,
return out;
}
+static size_t base64_infer_length(const char* s) {
+ grpc_slice ss = grpc_slice_from_copied_string(s);
+ size_t out = grpc_chttp2_base64_infer_length_after_decode(ss);
+ grpc_slice_unref_internal(ss);
+ return out;
+}
+
+#define EXPECT_DECODED_LENGTH(s, expected) \
+ GPR_ASSERT((expected) == base64_infer_length((s)));
+
#define EXPECT_SLICE_EQ(expected, slice) \
expect_slice_eq( \
grpc_slice_from_copied_buffer(expected, sizeof(expected) - 1), slice, \
@@ -131,6 +141,26 @@ int main(int argc, char** argv) {
// Test illegal charactors in grpc_chttp2_base64_decode_with_length
EXPECT_SLICE_EQ("", base64_decode_with_length("Zm:v", 3));
EXPECT_SLICE_EQ("", base64_decode_with_length("Zm=v", 3));
+
+ EXPECT_DECODED_LENGTH("", 0);
+ EXPECT_DECODED_LENGTH("ab", 1);
+ EXPECT_DECODED_LENGTH("abc", 2);
+ EXPECT_DECODED_LENGTH("abcd", 3);
+ EXPECT_DECODED_LENGTH("abcdef", 4);
+ EXPECT_DECODED_LENGTH("abcdefg", 5);
+ EXPECT_DECODED_LENGTH("abcdefgh", 6);
+
+ EXPECT_DECODED_LENGTH("ab==", 1);
+ EXPECT_DECODED_LENGTH("abc=", 2);
+ EXPECT_DECODED_LENGTH("abcd", 3);
+ EXPECT_DECODED_LENGTH("abcdef==", 4);
+ EXPECT_DECODED_LENGTH("abcdefg=", 5);
+ EXPECT_DECODED_LENGTH("abcdefgh", 6);
+
+ EXPECT_DECODED_LENGTH("a", 0);
+ EXPECT_DECODED_LENGTH("a===", 0);
+ EXPECT_DECODED_LENGTH("abcde", 0);
+ EXPECT_DECODED_LENGTH("abcde===", 0);
}
grpc_shutdown();
return all_ok ? 0 : 1;
diff --git a/test/core/transport/status_metadata_test.cc b/test/core/transport/status_metadata_test.cc
new file mode 100644
index 0000000000..a96f11c1ea
--- /dev/null
+++ b/test/core/transport/status_metadata_test.cc
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/transport/status_metadata.h"
+
+#include <gtest/gtest.h>
+
+#include "src/core/lib/transport/static_metadata.h"
+
+namespace {
+
+TEST(GetStatusCodeFromMetadata, OK) {
+ EXPECT_EQ(GRPC_STATUS_OK,
+ grpc_get_status_code_from_metadata(GRPC_MDELEM_GRPC_STATUS_0));
+}
+
+TEST(GetStatusCodeFromMetadata, CANCELLED) {
+ EXPECT_EQ(GRPC_STATUS_CANCELLED,
+ grpc_get_status_code_from_metadata(GRPC_MDELEM_GRPC_STATUS_1));
+}
+
+TEST(GetStatusCodeFromMetadata, UNKNOWN) {
+ EXPECT_EQ(GRPC_STATUS_UNKNOWN,
+ grpc_get_status_code_from_metadata(GRPC_MDELEM_GRPC_STATUS_2));
+}
+
+TEST(GetStatusCodeFromMetadata, Other) {
+ grpc_mdelem status_md = grpc_mdelem_from_slices(
+ GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_static_string("10"));
+ EXPECT_EQ(GRPC_STATUS_ABORTED, grpc_get_status_code_from_metadata(status_md));
+ GRPC_MDELEM_UNREF(status_md);
+}
+
+TEST(GetStatusCodeFromMetadata, Unparseable) {
+ grpc_mdelem status_md = grpc_mdelem_from_slices(
+ GRPC_MDSTR_GRPC_STATUS, grpc_slice_from_static_string("NaN"));
+ EXPECT_EQ(GRPC_STATUS_UNKNOWN, grpc_get_status_code_from_metadata(status_md));
+ GRPC_MDELEM_UNREF(status_md);
+}
+
+} // namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc
index ea392d347d..bec81ed42f 100644
--- a/test/core/tsi/fake_transport_security_test.cc
+++ b/test/core/tsi/fake_transport_security_test.cc
@@ -20,7 +20,7 @@
#include <stdio.h>
#include <string.h>
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/tsi/fake_transport_security.h"
#include "test/core/tsi/transport_security_test_lib.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc
index d7a4d747e1..8f255a3d35 100644
--- a/test/core/tsi/ssl_transport_security_test.cc
+++ b/test/core/tsi/ssl_transport_security_test.cc
@@ -21,7 +21,7 @@
#include <string.h>
#include "src/core/lib/iomgr/load_file.h"
-#include "src/core/lib/security/transport/security_connector.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security.h"
#include "src/core/tsi/transport_security_adapter.h"
@@ -681,15 +681,12 @@ int main(int argc, char** argv) {
ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain();
ssl_tsi_test_do_handshake_with_bad_server_cert();
ssl_tsi_test_do_handshake_with_bad_client_cert();
- // TODO: BoringSSL and OpenSSL have different behaviors on handling mismatched
- // ALPN. Re-enable this test if we can detect in the runtime which SSL library
- // is used.
- // ssl_tsi_test_do_handshake_alpn_client_no_server();
+#ifdef OPENSSL_IS_BORINGSSL
+ // BoringSSL and OpenSSL have different behaviors on mismatched ALPN.
+ ssl_tsi_test_do_handshake_alpn_client_no_server();
+ ssl_tsi_test_do_handshake_alpn_client_server_mismatch();
+#endif
ssl_tsi_test_do_handshake_alpn_server_no_client();
- // TODO: BoringSSL and OpenSSL have different behaviors on handling mismatched
- // ALPN. Re-enable this test if we can detect in the runtime which SSL library
- // is used.
- // ssl_tsi_test_do_handshake_alpn_client_server_mismatch();
ssl_tsi_test_do_handshake_alpn_client_server_ok();
ssl_tsi_test_do_round_trip_for_all_configs();
ssl_tsi_test_do_round_trip_odd_buffer_size();
diff --git a/test/core/tsi/transport_security_test_lib.cc b/test/core/tsi/transport_security_test_lib.cc
index 080585365f..7af6431c66 100644
--- a/test/core/tsi/transport_security_test_lib.cc
+++ b/test/core/tsi/transport_security_test_lib.cc
@@ -23,7 +23,8 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
+
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/security/transport/tsi_error.h"
#include "test/core/tsi/transport_security_test_lib.h"
diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc
index 7849321257..18bc0ad69e 100644
--- a/test/core/util/fuzzer_corpus_test.cc
+++ b/test/core/util/fuzzer_corpus_test.cc
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <sys/types.h>
+#include "src/core/lib/gpr/env.h"
#include "src/core/lib/iomgr/load_file.h"
#include "test/core/util/test_config.h"
@@ -68,6 +69,12 @@ class ExampleGenerator
if (examples_.empty()) {
if (!FLAGS_file.empty()) examples_.push_back(FLAGS_file);
if (!FLAGS_directory.empty()) {
+ char* test_srcdir = gpr_getenv("TEST_SRCDIR");
+ if (test_srcdir != nullptr) {
+ FLAGS_directory = test_srcdir +
+ std::string("/com_github_grpc_grpc/") +
+ FLAGS_directory;
+ }
DIR* dp;
struct dirent* ep;
dp = opendir(FLAGS_directory.c_str());
diff --git a/test/core/util/grpc_fuzzer.bzl b/test/core/util/grpc_fuzzer.bzl
index b8b270ecd0..cece023fc0 100644
--- a/test/core/util/grpc_fuzzer.bzl
+++ b/test/core/util/grpc_fuzzer.bzl
@@ -23,5 +23,6 @@ def grpc_fuzzer(name, corpus, srcs = [], deps = [], **kwargs):
external_deps = [
'gtest',
],
+ args = ["--directory=" + native.package_name() + "/" + corpus,],
**kwargs
)
diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc
index bb8553f56a..1d2dcae94b 100644
--- a/test/cpp/client/client_channel_stress_test.cc
+++ b/test/cpp/client/client_channel_stress_test.cc
@@ -32,10 +32,10 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr.h"
diff --git a/test/cpp/cocoapods/generic/generic.mm b/test/cpp/cocoapods/generic/generic.mm
index 30b43ec375..5ca34f195c 100644
--- a/test/cpp/cocoapods/generic/generic.mm
+++ b/test/cpp/cocoapods/generic/generic.mm
@@ -30,9 +30,9 @@
#include <grpc++/server_context.h>
#include <grpc++/support/slice.h>
#include <grpc/grpc.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index 026a94112a..ca7db5db32 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -26,15 +26,15 @@
#include "src/proto/grpc/testing/compiler_test.pb.h"
-#include <grpc++/impl/codegen/async_stream.h>
-#include <grpc++/impl/codegen/async_unary_call.h>
-#include <grpc++/impl/codegen/method_handler_impl.h>
-#include <grpc++/impl/codegen/proto_utils.h>
-#include <grpc++/impl/codegen/rpc_method.h>
-#include <grpc++/impl/codegen/service_type.h>
-#include <grpc++/impl/codegen/status.h>
-#include <grpc++/impl/codegen/stub_options.h>
-#include <grpc++/impl/codegen/sync_stream.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/method_handler_impl.h>
+#include <grpcpp/impl/codegen/proto_utils.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
+#include <grpcpp/impl/codegen/service_type.h>
+#include <grpcpp/impl/codegen/status.h>
+#include <grpcpp/impl/codegen/stub_options.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
namespace grpc {
class CompletionQueue;
diff --git a/test/cpp/codegen/compiler_test_mock_golden b/test/cpp/codegen/compiler_test_mock_golden
index f97c2dd83a..65a7cb0f85 100644
--- a/test/cpp/codegen/compiler_test_mock_golden
+++ b/test/cpp/codegen/compiler_test_mock_golden
@@ -5,8 +5,8 @@
#include "src/proto/grpc/testing/compiler_test.pb.h"
#include "src/proto/grpc/testing/compiler_test.grpc.pb.h"
-#include <grpc++/impl/codegen/async_stream.h>
-#include <grpc++/impl/codegen/sync_stream.h>
+#include <grpcpp/impl/codegen/async_stream.h>
+#include <grpcpp/impl/codegen/sync_stream.h>
#include <gmock/gmock.h>
namespace grpc {
namespace testing {
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index afa054ae10..8ab0811ffa 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -201,6 +201,27 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "health_service_end2end_test",
+ srcs = ["health_service_end2end_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ ":test_service_impl",
+ "//:gpr",
+ "//:grpc",
+ "//:grpc++",
+ "//src/proto/grpc/health/v1:health_proto",
+ "//src/proto/grpc/testing:echo_messages_proto",
+ "//src/proto/grpc/testing:echo_proto",
+ "//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
+
+grpc_cc_test(
name = "hybrid_end2end_test",
srcs = ["hybrid_end2end_test.cc"],
external_deps = [
diff --git a/test/cpp/end2end/OWNERS b/test/cpp/end2end/OWNERS
deleted file mode 100644
index d87b3286a5..0000000000
--- a/test/cpp/end2end/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-set noparent
-@vjpai
-@yang-g
-@y-zeng
-
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 219561868f..df706a2237 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -30,10 +30,10 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gpr/tls.h"
#include "src/core/lib/iomgr/port.h"
#include "src/proto/grpc/health/v1/health.grpc.pb.h"
diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc
index f34b27511b..c28ffea79c 100644
--- a/test/cpp/end2end/client_crash_test.cc
+++ b/test/cpp/end2end/client_crash_test.cc
@@ -24,9 +24,9 @@
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index f1816af3ce..16600d12b0 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -32,13 +32,13 @@
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index cd8321771a..38fdde990f 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -32,10 +32,10 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index d11df3a143..ae6c6c7d11 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -31,9 +31,9 @@
#include <grpc++/support/config.h>
#include <grpc++/support/slice.h>
#include <grpc/grpc.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/cpp/common/channel_filter.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index c778b205e0..86a41fc585 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -29,9 +29,9 @@
#include <grpc++/server_context.h>
#include <grpc++/support/slice.h>
#include <grpc/grpc.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 21cad11a71..ce06ac83e9 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -30,13 +30,17 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+#include "src/cpp/server/secure_server_credentials.h"
+
+#include "src/cpp/client/secure_credentials.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
@@ -58,6 +62,8 @@
// - Test handling of creation of faulty RR instance by having the LB return a
// serverlist with non-existent backends after having initially returned a
// valid one.
+// - test using secure credentials and make sure we don't send call
+// credentials to the balancer
//
// Findings from end to end testing to be covered here:
// - Handling of LB servers restart, including reconnection after backing-off
@@ -187,9 +193,13 @@ class BalancerServiceImpl : public BalancerService {
Status BalanceLoad(ServerContext* context, Stream* stream) override {
gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this);
LoadBalanceRequest request;
- stream->Read(&request);
+ std::vector<ResponseDelayPair> responses_and_delays;
+
+ if (!stream->Read(&request)) {
+ goto done;
+ }
IncreaseRequestCount();
- gpr_log(GPR_INFO, "LB[%p]: recv msg '%s'", this,
+ gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this,
request.DebugString().c_str());
// TODO(juanlishen): Initial response should always be the first response.
@@ -201,7 +211,6 @@ class BalancerServiceImpl : public BalancerService {
stream->Write(initial_response);
}
- std::vector<ResponseDelayPair> responses_and_delays;
{
std::unique_lock<std::mutex> lock(mu_);
responses_and_delays = responses_and_delays_;
@@ -217,14 +226,13 @@ class BalancerServiceImpl : public BalancerService {
std::unique_lock<std::mutex> lock(mu_);
if (shutdown_) goto done;
serverlist_cond_.wait(lock, [this] { return serverlist_ready_; });
- serverlist_ready_ = false;
}
if (client_load_reporting_interval_seconds_ > 0) {
request.Clear();
if (stream->Read(&request)) {
- gpr_log(GPR_INFO, "LB[%p]: recv client load report msg: '%s'", this,
- request.DebugString().c_str());
+ gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'",
+ this, request.DebugString().c_str());
GPR_ASSERT(request.has_client_stats());
// We need to acquire the lock here in order to prevent the notify_one
// below from firing before its corresponding wait is executed.
@@ -297,7 +305,7 @@ class BalancerServiceImpl : public BalancerService {
void NotifyDoneWithServerlists() {
std::lock_guard<std::mutex> lock(mu_);
serverlist_ready_ = true;
- serverlist_cond_.notify_one();
+ serverlist_cond_.notify_all();
}
private:
@@ -305,9 +313,7 @@ class BalancerServiceImpl : public BalancerService {
int delay_ms) {
gpr_log(GPR_INFO, "LB[%p]: sleeping for %d ms...", this, delay_ms);
if (delay_ms > 0) {
- gpr_sleep_until(
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_millis(delay_ms, GPR_TIMESPAN)));
+ gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(delay_ms));
}
gpr_log(GPR_INFO, "LB[%p]: Woke up! Sending response '%s'", this,
response.DebugString().c_str());
@@ -376,15 +382,22 @@ class GrpclbEnd2endTest : public ::testing::Test {
SetNextResolution(addresses);
}
- void ResetStub(int fallback_timeout = 0) {
+ void ResetStub(int fallback_timeout = 0,
+ const grpc::string& expected_targets = "") {
ChannelArguments args;
args.SetGrpclbFallbackTimeout(fallback_timeout);
args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
response_generator_.get());
+ if (!expected_targets.empty()) {
+ args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets);
+ }
std::ostringstream uri;
- uri << "fake:///servername_not_used";
- channel_ =
- CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args);
+ uri << "fake:///" << kApplicationTargetName_;
+ // TODO(dgq): templatize tests to run everything using both secure and
+ // insecure channel credentials.
+ std::shared_ptr<ChannelCredentials> creds(new SecureChannelCredentials(
+ grpc_fake_transport_security_credentials_create()));
+ channel_ = CreateCustomChannel(uri.str(), creds, args);
stub_ = grpc::testing::EchoTestService::NewStub(channel_);
}
@@ -445,7 +458,7 @@ class GrpclbEnd2endTest : public ::testing::Test {
void WaitForBackend(size_t backend_idx) {
do {
- SendRpc();
+ (void)SendRpc();
} while (backends_[backend_idx]->request_count() == 0);
ResetBackendCounters();
}
@@ -521,10 +534,10 @@ class GrpclbEnd2endTest : public ::testing::Test {
return status;
}
- void CheckRpcSendOk(const size_t times = 1) {
+ void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) {
for (size_t i = 0; i < times; ++i) {
EchoResponse response;
- const Status status = SendRpc(&response);
+ const Status status = SendRpc(&response, timeout_ms);
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
EXPECT_EQ(response.message(), kRequestMessage_);
@@ -562,8 +575,9 @@ class GrpclbEnd2endTest : public ::testing::Test {
std::ostringstream server_address;
server_address << server_host << ":" << port_;
ServerBuilder builder;
- builder.AddListeningPort(server_address.str(),
- InsecureServerCredentials());
+ std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials(
+ grpc_fake_transport_security_server_credentials_create()));
+ builder.AddListeningPort(server_address.str(), creds);
builder.RegisterService(service_);
server_ = builder.BuildAndStart();
cond->notify_one();
@@ -596,6 +610,7 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
response_generator_;
const grpc::string kRequestMessage_ = "Live long and prosper.";
+ const grpc::string kApplicationTargetName_ = "application_target_name";
};
class SingleBalancerTest : public GrpclbEnd2endTest {
@@ -631,11 +646,52 @@ TEST_F(SingleBalancerTest, Vanilla) {
EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
}
+TEST_F(SingleBalancerTest, SecureNaming) {
+ ResetStub(0, kApplicationTargetName_ + ";lb");
+ SetNextResolution({AddressData{balancer_servers_[0].port_, true, "lb"}});
+ const size_t kNumRpcsPerAddress = 100;
+ ScheduleResponseForBalancer(
+ 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}),
+ 0);
+ // Make sure that trying to connect works without a call.
+ channel_->GetState(true /* try_to_connect */);
+ // We need to wait for all backends to come online.
+ WaitForAllBackends();
+ // Send kNumRpcsPerAddress RPCs per server.
+ CheckRpcSendOk(kNumRpcsPerAddress * num_backends_);
+
+ // Each backend should have gotten 100 requests.
+ for (size_t i = 0; i < backends_.size(); ++i) {
+ EXPECT_EQ(kNumRpcsPerAddress,
+ backend_servers_[i].service_->request_count());
+ }
+ balancers_[0]->NotifyDoneWithServerlists();
+ // The balancer got a single request.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
+ // and sent a single response.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
+ // Check LB policy name for the channel.
+ EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName());
+}
+
+TEST_F(SingleBalancerTest, SecureNamingDeathTest) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ // Make sure that we blow up (via abort() from the security connector) when
+ // the name from the balancer doesn't match expectations.
+ ASSERT_DEATH(
+ {
+ ResetStub(0, kApplicationTargetName_ + ";lb");
+ SetNextResolution(
+ {AddressData{balancer_servers_[0].port_, true, "woops"}});
+ channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1));
+ },
+ "");
+}
+
TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
SetNextResolutionAllBalancers();
const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor();
- const int kCallDeadlineMs = 1000 * grpc_test_slowdown_factor();
-
+ const int kCallDeadlineMs = kServerlistDelayMs * 2;
// First response is an empty serverlist, sent right away.
ScheduleResponseForBalancer(0, LoadBalanceResponse(), 0);
// Send non-empty serverlist only after kServerlistDelayMs
@@ -645,20 +701,15 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
const auto t0 = system_clock::now();
// Client will block: LB will initially send empty serverlist.
- CheckRpcSendOk(num_backends_);
+ CheckRpcSendOk(1, kCallDeadlineMs);
const auto ellapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
system_clock::now() - t0);
// but eventually, the LB sends a serverlist update that allows the call to
// proceed. The call delay must be larger than the delay in sending the
- // populated serverlist but under the call's deadline.
+ // populated serverlist but under the call's deadline (which is enforced by
+ // the call's deadline).
EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs);
- EXPECT_LT(ellapsed_ms.count(), kCallDeadlineMs);
-
- // Each backend should have gotten 1 request.
- for (size_t i = 0; i < backends_.size(); ++i) {
- EXPECT_EQ(1U, backend_servers_[i].service_->request_count());
- }
balancers_[0]->NotifyDoneWithServerlists();
// The balancer got a single request.
EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
@@ -888,7 +939,10 @@ TEST_F(UpdatesTest, UpdateBalancers) {
ScheduleResponseForBalancer(
1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0);
- // Start servers and send 10 RPCs per server.
+ // Wait until the first backend is ready.
+ WaitForBackend(0);
+
+ // Send 10 requests.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
@@ -950,7 +1004,10 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) {
ScheduleResponseForBalancer(
1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0);
- // Start servers and send 10 RPCs per server.
+ // Wait until the first backend is ready.
+ WaitForBackend(0);
+
+ // Send 10 requests.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
@@ -1090,26 +1147,26 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) {
EXPECT_EQ(0U, balancer_servers_[2].service_->response_count());
}
-TEST_F(UpdatesTest, ReresolveDeadBalancer) {
+TEST_F(UpdatesTest, ReresolveDeadBackend) {
+ ResetStub(500);
+ // The first resolution contains the addresses of a balancer that never
+ // responds, and a fallback backend.
std::vector<AddressData> addresses;
addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
+ addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""});
SetNextResolution(addresses);
+ // The re-resolution result will contain the addresses of the same balancer
+ // and a new fallback backend.
addresses.clear();
- addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""});
+ addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
+ addresses.emplace_back(AddressData{backend_servers_[1].port_, false, ""});
SetNextReresolutionResponse(addresses);
- const std::vector<int> first_backend{GetBackendPorts()[0]};
- const std::vector<int> second_backend{GetBackendPorts()[1]};
-
- ScheduleResponseForBalancer(
- 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0);
- ScheduleResponseForBalancer(
- 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0);
// Start servers and send 10 RPCs per server.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
- // All 10 requests should have gone to the first backend.
+ // All 10 requests should have gone to the fallback backend.
EXPECT_EQ(10U, backend_servers_[0].service_->request_count());
// Kill backend 0.
@@ -1117,42 +1174,10 @@ TEST_F(UpdatesTest, ReresolveDeadBalancer) {
if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown();
gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************");
- CheckRpcSendFailure();
-
- balancers_[1]->NotifyDoneWithServerlists();
- balancers_[2]->NotifyDoneWithServerlists();
- EXPECT_EQ(0U, balancer_servers_[1].service_->request_count());
- EXPECT_EQ(0U, balancer_servers_[1].service_->response_count());
- EXPECT_EQ(0U, balancer_servers_[2].service_->request_count());
- EXPECT_EQ(0U, balancer_servers_[2].service_->response_count());
-
- // Kill balancer 0.
- gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************");
- balancers_[0]->NotifyDoneWithServerlists();
- if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown();
- gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************");
-
- balancers_[0]->NotifyDoneWithServerlists();
- balancers_[1]->NotifyDoneWithServerlists();
- balancers_[2]->NotifyDoneWithServerlists();
- // Balancer 0 got a single request.
- EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
- // and sent a single response.
- EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
- // Balancer 1 may have received a request if re-resolution is done quickly
- // enough.
- EXPECT_GE(balancer_servers_[1].service_->request_count(), 0U);
- EXPECT_GE(balancer_servers_[1].service_->response_count(), 0U);
- EXPECT_LE(balancer_servers_[1].service_->request_count(), 1U);
- EXPECT_LE(balancer_servers_[1].service_->response_count(), 1U);
- EXPECT_EQ(0U, balancer_servers_[2].service_->request_count());
- EXPECT_EQ(0U, balancer_servers_[2].service_->response_count());
-
// Wait until re-resolution has finished, as signaled by the second backend
// receiving a request.
WaitForBackend(1);
- // This is serviced by the new serverlist.
gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH ==========");
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH ==========");
@@ -1163,33 +1188,43 @@ TEST_F(UpdatesTest, ReresolveDeadBalancer) {
balancers_[1]->NotifyDoneWithServerlists();
balancers_[2]->NotifyDoneWithServerlists();
EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
- EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
- EXPECT_EQ(1U, balancer_servers_[1].service_->request_count());
- EXPECT_EQ(1U, balancer_servers_[1].service_->response_count());
+ EXPECT_EQ(0U, balancer_servers_[0].service_->response_count());
+ EXPECT_EQ(0U, balancer_servers_[1].service_->request_count());
+ EXPECT_EQ(0U, balancer_servers_[1].service_->response_count());
EXPECT_EQ(0U, balancer_servers_[2].service_->request_count());
EXPECT_EQ(0U, balancer_servers_[2].service_->response_count());
}
-TEST_F(UpdatesTest, ReresolveDeadBackend) {
- ResetStub(500);
- // The first resolution contains the addresses of a balancer that never
- // responds, and a fallback backend.
+// TODO(juanlishen): Should be removed when the first response is always the
+// initial response. Currently, if client load reporting is not enabled, the
+// balancer doesn't send initial response. When the backend shuts down, an
+// unexpected re-resolution will happen. This test configuration is a workaround
+// for test ReresolveDeadBalancer.
+class UpdatesWithClientLoadReportingTest : public GrpclbEnd2endTest {
+ public:
+ UpdatesWithClientLoadReportingTest() : GrpclbEnd2endTest(4, 3, 2) {}
+};
+
+TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) {
std::vector<AddressData> addresses;
addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
- addresses.emplace_back(AddressData{backend_servers_[0].port_, false, ""});
SetNextResolution(addresses);
- // The re-resolution result will contain the addresses of the same balancer
- // and a new fallback backend.
addresses.clear();
- addresses.emplace_back(AddressData{balancer_servers_[0].port_, true, ""});
- addresses.emplace_back(AddressData{backend_servers_[1].port_, false, ""});
+ addresses.emplace_back(AddressData{balancer_servers_[1].port_, true, ""});
SetNextReresolutionResponse(addresses);
+ const std::vector<int> first_backend{GetBackendPorts()[0]};
+ const std::vector<int> second_backend{GetBackendPorts()[1]};
+
+ ScheduleResponseForBalancer(
+ 0, BalancerServiceImpl::BuildResponseForBackends(first_backend, {}), 0);
+ ScheduleResponseForBalancer(
+ 1, BalancerServiceImpl::BuildResponseForBackends(second_backend, {}), 0);
// Start servers and send 10 RPCs per server.
gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH ==========");
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH ==========");
- // All 10 requests should have gone to the fallback backend.
+ // All 10 requests should have gone to the first backend.
EXPECT_EQ(10U, backend_servers_[0].service_->request_count());
// Kill backend 0.
@@ -1197,23 +1232,45 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) {
if (backends_[0]->Shutdown()) backend_servers_[0].Shutdown();
gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************");
+ CheckRpcSendFailure();
+
+ // Balancer 0 got a single request.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
+ // and sent a single response.
+ EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
+ EXPECT_EQ(0U, balancer_servers_[1].service_->request_count());
+ EXPECT_EQ(0U, balancer_servers_[1].service_->response_count());
+ EXPECT_EQ(0U, balancer_servers_[2].service_->request_count());
+ EXPECT_EQ(0U, balancer_servers_[2].service_->response_count());
+
+ // Kill balancer 0.
+ gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************");
+ if (balancers_[0]->Shutdown()) balancer_servers_[0].Shutdown();
+ gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************");
+
// Wait until re-resolution has finished, as signaled by the second backend
// receiving a request.
WaitForBackend(1);
+ // This is serviced by the new serverlist.
gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH ==========");
CheckRpcSendOk(10);
gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH ==========");
// All 10 requests should have gone to the second backend.
EXPECT_EQ(10U, backend_servers_[1].service_->request_count());
- balancers_[0]->NotifyDoneWithServerlists();
- balancers_[1]->NotifyDoneWithServerlists();
- balancers_[2]->NotifyDoneWithServerlists();
EXPECT_EQ(1U, balancer_servers_[0].service_->request_count());
- EXPECT_EQ(0U, balancer_servers_[0].service_->response_count());
- EXPECT_EQ(0U, balancer_servers_[1].service_->request_count());
- EXPECT_EQ(0U, balancer_servers_[1].service_->response_count());
+ EXPECT_EQ(1U, balancer_servers_[0].service_->response_count());
+ // After balancer 0 is killed, we restart an LB call immediately (because we
+ // disconnect to a previously connected balancer). Although we will cancel
+ // this call when the re-resolution update is done and another LB call restart
+ // is needed, this old call may still succeed reaching the LB server if
+ // re-resolution is slow. So balancer 1 may have received 2 requests and sent
+ // 2 responses.
+ EXPECT_GE(balancer_servers_[1].service_->request_count(), 1U);
+ EXPECT_GE(balancer_servers_[1].service_->response_count(), 1U);
+ EXPECT_LE(balancer_servers_[1].service_->request_count(), 2U);
+ EXPECT_LE(balancer_servers_[1].service_->response_count(), 2U);
EXPECT_EQ(0U, balancer_servers_[2].service_->request_count());
EXPECT_EQ(0U, balancer_servers_[2].service_->response_count());
}
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index 175ecea2b3..fe530432ea 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -27,9 +27,9 @@
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "src/proto/grpc/testing/echo_mock.grpc.pb.h"
diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc
index 528951bb9b..574d357bef 100644
--- a/test/cpp/end2end/server_crash_test.cc
+++ b/test/cpp/end2end/server_crash_test.cc
@@ -24,9 +24,9 @@
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc
index 6fd26fcdb6..38f9b6755c 100644
--- a/test/cpp/end2end/server_early_return_test.cc
+++ b/test/cpp/end2end/server_early_return_test.cc
@@ -27,9 +27,9 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc
index 8fcb8b1d48..2c8928151a 100644
--- a/test/cpp/end2end/streaming_throughput_test.cc
+++ b/test/cpp/end2end/streaming_throughput_test.cc
@@ -31,9 +31,9 @@
#include <grpc/grpc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index 79074d8e70..0842d8e64a 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -26,9 +26,9 @@
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
#include <grpc/grpc.h>
-#include <grpc/support/thd.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/thd.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
diff --git a/test/cpp/grpclb/BUILD b/test/cpp/grpclb/BUILD
new file mode 100644
index 0000000000..8319eb5142
--- /dev/null
+++ b/test/cpp/grpclb/BUILD
@@ -0,0 +1,39 @@
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+licenses(["notice"]) # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary")
+
+grpc_package(
+ name = "test/cpp/grpclb",
+ visibility = "public",
+) # Allows external users to implement grpclb tests.
+
+grpc_cc_test(
+ name = "grpclb_api_test",
+ srcs = ["grpclb_api_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//:grpc++",
+ "//src/proto/grpc/lb/v1:load_balancer_proto",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
deleted file mode 100644
index d17c2957a2..0000000000
--- a/test/cpp/grpclb/grpclb_test.cc
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- *
- * Copyright 2016 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <cinttypes>
-#include <cstdarg>
-#include <cstdint>
-#include <cstring>
-#include <string>
-
-#include <gtest/gtest.h>
-
-#include <grpc/grpc.h>
-#include <grpc/impl/codegen/byte_buffer_reader.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
-#include <grpc/support/thd.h>
-#include <grpc/support/time.h>
-
-#include <grpc++/impl/codegen/config.h>
-
-#include "src/core/ext/filters/client_channel/client_channel.h"
-#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/gpr/env.h"
-#include "src/core/lib/gpr/host_port.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/gpr/tmpfile.h"
-#include "src/core/lib/gprpp/ref_counted_ptr.h"
-#include "src/core/lib/iomgr/sockaddr.h"
-#include "src/core/lib/security/credentials/fake/fake_credentials.h"
-#include "src/core/lib/surface/channel.h"
-#include "src/core/lib/surface/server.h"
-#include "test/core/end2end/cq_verifier.h"
-#include "test/core/util/port.h"
-#include "test/core/util/test_config.h"
-
-#include "src/proto/grpc/lb/v1/load_balancer.pb.h"
-
-#define NUM_BACKENDS 4
-#define PAYLOAD "hello you"
-
-// TODO(dgq): Other scenarios in need of testing:
-// - Send an empty serverlist update and verify that the client request blocks
-// until a new serverlist with actual contents is available.
-// - Send identical serverlist update
-// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc).
-// - Test reception of invalid serverlist
-// - Test pinging
-// - Test against a non-LB server.
-// - Random LB server closing the stream unexpectedly.
-// - Test using DNS-resolvable names (localhost?)
-// - Test handling of creation of faulty RR instance by having the LB return a
-// serverlist with non-existent backends after having initially returned a
-// valid one.
-//
-// Findings from end to end testing to be covered here:
-// - Handling of LB servers restart, including reconnection after backing-off
-// retries.
-// - Destruction of load balanced channel (and therefore of grpclb instance)
-// while:
-// 1) the internal LB call is still active. This should work by virtue
-// of the weak reference the LB call holds. The call should be terminated as
-// part of the grpclb shutdown process.
-// 2) the retry timer is active. Again, the weak reference it holds should
-// prevent a premature call to \a glb_destroy.
-// - Restart of backend servers with no changes to serverlist. This exercises
-// the RR handover mechanism.
-
-namespace grpc {
-namespace {
-
-typedef struct client_fixture {
- grpc_channel* client;
- char* server_uri;
- grpc_completion_queue* cq;
-} client_fixture;
-
-typedef struct server_fixture {
- grpc_server* server;
- grpc_call* server_call;
- grpc_completion_queue* cq;
- char* servers_hostport;
- const char* balancer_name;
- int port;
- const char* lb_token_prefix;
- gpr_thd_id tid;
- int num_calls_serviced;
-} server_fixture;
-
-typedef struct test_fixture {
- server_fixture lb_server;
- server_fixture lb_backends[NUM_BACKENDS];
- client_fixture client;
- int lb_server_update_delay_ms;
-} test_fixture;
-
-static void* tag(intptr_t t) { return (void*)t; }
-
-static grpc_slice build_response_payload_slice(const char* host, int* ports,
- size_t nports,
- const char* token_prefix) {
- // server_list {
- // servers {
- // ip_address: <in_addr/6 bytes of an IP>
- // port: <16 bit uint>
- // load_balance_token: "token..."
- // }
- // ...
- // }
- grpc::lb::v1::LoadBalanceResponse response;
- auto* serverlist = response.mutable_server_list();
-
- for (size_t i = 0; i < nports; i++) {
- auto* server = serverlist->add_servers();
- // TODO(dgq): test ipv6
- struct in_addr ip4;
- GPR_ASSERT(inet_pton(AF_INET, host, &ip4) == 1);
- server->set_ip_address(
- string(reinterpret_cast<const char*>(&ip4), sizeof(ip4)));
- server->set_port(ports[i]);
- // Missing tokens are acceptable. Test that path.
- if (strlen(token_prefix) > 0) {
- string token_data = token_prefix + std::to_string(ports[i]);
- server->set_load_balance_token(token_data);
- }
- }
- const string& enc_resp = response.SerializeAsString();
- return grpc_slice_from_copied_buffer(enc_resp.data(), enc_resp.size());
-}
-
-static void drain_cq(grpc_completion_queue* cq) {
- grpc_event ev;
- do {
- ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
- nullptr);
- } while (ev.type != GRPC_QUEUE_SHUTDOWN);
-}
-
-static void sleep_ms(int delay_ms) {
- gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_millis(delay_ms, GPR_TIMESPAN)));
-}
-
-static void start_lb_server(server_fixture* sf, int* ports, size_t nports,
- int update_delay_ms) {
- grpc_call* s;
- cq_verifier* cqv = cq_verifier_create(sf->cq);
- grpc_op ops[6];
- grpc_op* op;
- grpc_metadata_array request_metadata_recv;
- grpc_call_details call_details;
- grpc_call_error error;
- int was_cancelled = 2;
- grpc_byte_buffer* request_payload_recv;
- grpc_byte_buffer* response_payload;
-
- memset(ops, 0, sizeof(ops));
- grpc_metadata_array_init(&request_metadata_recv);
- grpc_call_details_init(&call_details);
-
- error = grpc_server_request_call(sf->server, &s, &call_details,
- &request_metadata_recv, sf->cq, sf->cq,
- tag(200));
- GPR_ASSERT(GRPC_CALL_OK == error);
- gpr_log(GPR_INFO, "LB Server[%s](%s) up", sf->servers_hostport,
- sf->balancer_name);
- CQ_EXPECT_COMPLETION(cqv, tag(200), 1);
- cq_verify(cqv);
- gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 200", sf->servers_hostport,
- sf->balancer_name);
-
- // make sure we've received the initial metadata from the grpclb request.
- GPR_ASSERT(request_metadata_recv.count > 0);
- GPR_ASSERT(request_metadata_recv.metadata != nullptr);
-
- // receive request for backends
- op = ops;
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &request_payload_recv;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(202),
- nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
- CQ_EXPECT_COMPLETION(cqv, tag(202), 1);
- cq_verify(cqv);
- gpr_log(GPR_INFO, "LB Server[%s](%s) after RECV_MSG", sf->servers_hostport,
- sf->balancer_name);
-
- // validate initial request.
- grpc_byte_buffer_reader bbr;
- grpc_byte_buffer_reader_init(&bbr, request_payload_recv);
- grpc_slice request_payload_slice = grpc_byte_buffer_reader_readall(&bbr);
- grpc::lb::v1::LoadBalanceRequest request;
- request.ParseFromArray(GRPC_SLICE_START_PTR(request_payload_slice),
- GRPC_SLICE_LENGTH(request_payload_slice));
- GPR_ASSERT(request.has_initial_request());
- GPR_ASSERT(request.initial_request().name() == sf->servers_hostport);
- grpc_slice_unref(request_payload_slice);
- grpc_byte_buffer_reader_destroy(&bbr);
- grpc_byte_buffer_destroy(request_payload_recv);
-
- grpc_slice response_payload_slice;
- op = ops;
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- op->data.send_initial_metadata.count = 0;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
- op->data.recv_close_on_server.cancelled = &was_cancelled;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(201),
- nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
- gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 201", sf->servers_hostport,
- sf->balancer_name);
-
- for (int i = 0; i < 2; i++) {
- if (i == 0) {
- // First half of the ports.
- response_payload_slice = build_response_payload_slice(
- "127.0.0.1", ports, nports / 2, sf->lb_token_prefix);
- } else {
- // Second half of the ports.
- sleep_ms(update_delay_ms);
- response_payload_slice = build_response_payload_slice(
- "127.0.0.1", ports + (nports / 2), (nports + 1) / 2 /* ceil */,
- "" /* this half doesn't get to receive an LB token */);
- }
-
- response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
- op = ops;
- op->op = GRPC_OP_SEND_MESSAGE;
- op->data.send_message.send_message = response_payload;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
- tag(203), nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
- CQ_EXPECT_COMPLETION(cqv, tag(203), 1);
- cq_verify(cqv);
- gpr_log(GPR_INFO, "LB Server[%s](%s) after SEND_MESSAGE, iter %d",
- sf->servers_hostport, sf->balancer_name, i);
-
- grpc_byte_buffer_destroy(response_payload);
- grpc_slice_unref(response_payload_slice);
- }
- gpr_log(GPR_INFO, "LB Server[%s](%s) shutting down", sf->servers_hostport,
- sf->balancer_name);
-
- op = ops;
- op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
- op->data.send_status_from_server.trailing_metadata_count = 0;
- op->data.send_status_from_server.status = GRPC_STATUS_OK;
- grpc_slice status_details = grpc_slice_from_static_string("xyz");
- op->data.send_status_from_server.status_details = &status_details;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(204),
- nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- CQ_EXPECT_COMPLETION(cqv, tag(201), 1);
- CQ_EXPECT_COMPLETION(cqv, tag(204), 1);
- cq_verify(cqv);
- gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 204. All done. LB server out",
- sf->servers_hostport, sf->balancer_name);
-
- grpc_call_unref(s);
-
- cq_verifier_destroy(cqv);
-
- grpc_metadata_array_destroy(&request_metadata_recv);
- grpc_call_details_destroy(&call_details);
-}
-
-static void start_backend_server(server_fixture* sf) {
- grpc_call* s;
- cq_verifier* cqv;
- grpc_op ops[6];
- grpc_op* op;
- grpc_metadata_array request_metadata_recv;
- grpc_call_details call_details;
- grpc_call_error error;
- int was_cancelled;
- grpc_byte_buffer* request_payload_recv;
- grpc_byte_buffer* response_payload;
- grpc_event ev;
-
- while (true) {
- memset(ops, 0, sizeof(ops));
- cqv = cq_verifier_create(sf->cq);
- was_cancelled = 2;
- grpc_metadata_array_init(&request_metadata_recv);
- grpc_call_details_init(&call_details);
-
- error = grpc_server_request_call(sf->server, &s, &call_details,
- &request_metadata_recv, sf->cq, sf->cq,
- tag(100));
- GPR_ASSERT(GRPC_CALL_OK == error);
- gpr_log(GPR_INFO, "Server[%s] up", sf->servers_hostport);
- ev = grpc_completion_queue_next(
- sf->cq, grpc_timeout_seconds_to_deadline(60), nullptr);
- if (!ev.success) {
- gpr_log(GPR_INFO, "Server[%s] being torn down", sf->servers_hostport);
- cq_verifier_destroy(cqv);
- grpc_metadata_array_destroy(&request_metadata_recv);
- grpc_call_details_destroy(&call_details);
- return;
- }
- GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
- const string expected_token =
- strlen(sf->lb_token_prefix) == 0
- ? ""
- : sf->lb_token_prefix + std::to_string(sf->port);
- GPR_ASSERT(contains_metadata(&request_metadata_recv, "lb-token",
- expected_token.c_str()));
-
- gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport);
-
- op = ops;
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- op->data.send_initial_metadata.count = 0;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
- op->data.recv_close_on_server.cancelled = &was_cancelled;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
- tag(101), nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
- gpr_log(GPR_INFO, "Server[%s] after tag 101", sf->servers_hostport);
-
- bool exit = false;
- grpc_slice response_payload_slice = grpc_slice_from_copied_string(PAYLOAD);
- while (!exit) {
- op = ops;
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &request_payload_recv;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
- tag(102), nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
- ev = grpc_completion_queue_next(
- sf->cq, grpc_timeout_seconds_to_deadline(3), nullptr);
- if (ev.type == GRPC_OP_COMPLETE && ev.success) {
- GPR_ASSERT(ev.tag = tag(102));
- if (request_payload_recv == nullptr) {
- exit = true;
- gpr_log(GPR_INFO,
- "Server[%s] recv \"close\" from client, exiting. Call #%d",
- sf->servers_hostport, sf->num_calls_serviced);
- }
- } else {
- gpr_log(GPR_INFO, "Server[%s] forced to shutdown. Call #%d",
- sf->servers_hostport, sf->num_calls_serviced);
- exit = true;
- }
- gpr_log(GPR_INFO, "Server[%s] after tag 102. Call #%d",
- sf->servers_hostport, sf->num_calls_serviced);
-
- if (!exit) {
- response_payload =
- grpc_raw_byte_buffer_create(&response_payload_slice, 1);
- op = ops;
- op->op = GRPC_OP_SEND_MESSAGE;
- op->data.send_message.send_message = response_payload;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
- tag(103), nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
- ev = grpc_completion_queue_next(
- sf->cq, grpc_timeout_seconds_to_deadline(3), nullptr);
- if (ev.type == GRPC_OP_COMPLETE && ev.success) {
- GPR_ASSERT(ev.tag = tag(103));
- } else {
- gpr_log(GPR_INFO, "Server[%s] forced to shutdown. Call #%d",
- sf->servers_hostport, sf->num_calls_serviced);
- exit = true;
- }
- gpr_log(GPR_INFO, "Server[%s] after tag 103. Call #%d",
- sf->servers_hostport, sf->num_calls_serviced);
- grpc_byte_buffer_destroy(response_payload);
- }
-
- grpc_byte_buffer_destroy(request_payload_recv);
- }
- ++sf->num_calls_serviced;
-
- gpr_log(GPR_INFO, "Server[%s] OUT OF THE LOOP", sf->servers_hostport);
- grpc_slice_unref(response_payload_slice);
-
- op = ops;
- op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
- op->data.send_status_from_server.trailing_metadata_count = 0;
- op->data.send_status_from_server.status = GRPC_STATUS_OK;
- grpc_slice status_details =
- grpc_slice_from_static_string("Backend server out a-ok");
- op->data.send_status_from_server.status_details = &status_details;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
- tag(104), nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
- CQ_EXPECT_COMPLETION(cqv, tag(104), 1);
- cq_verify(cqv);
- gpr_log(GPR_INFO, "Server[%s] DONE. After servicing %d calls",
- sf->servers_hostport, sf->num_calls_serviced);
-
- grpc_call_unref(s);
- cq_verifier_destroy(cqv);
- grpc_metadata_array_destroy(&request_metadata_recv);
- grpc_call_details_destroy(&call_details);
- }
-}
-
-static void perform_request(client_fixture* cf) {
- grpc_call* c;
- cq_verifier* cqv = cq_verifier_create(cf->cq);
- grpc_op ops[6];
- grpc_op* op;
- grpc_metadata_array initial_metadata_recv;
- grpc_metadata_array trailing_metadata_recv;
- grpc_status_code status;
- grpc_call_error error;
- grpc_slice details;
- grpc_byte_buffer* request_payload;
- grpc_byte_buffer* response_payload_recv;
- int i;
-
- memset(ops, 0, sizeof(ops));
- grpc_slice request_payload_slice =
- grpc_slice_from_copied_string("hello world");
-
- grpc_slice host = grpc_slice_from_static_string("foo.test.google.fr:1234");
- c = grpc_channel_create_call(cf->client, nullptr, GRPC_PROPAGATE_DEFAULTS,
- cf->cq, grpc_slice_from_static_string("/foo"),
- &host, grpc_timeout_seconds_to_deadline(5),
- nullptr);
- gpr_log(GPR_INFO, "Call 0x%" PRIxPTR " created", (intptr_t)c);
- GPR_ASSERT(c);
- char* peer;
-
- grpc_metadata_array_init(&initial_metadata_recv);
- grpc_metadata_array_init(&trailing_metadata_recv);
-
- op = ops;
- op->op = GRPC_OP_SEND_INITIAL_METADATA;
- op->data.send_initial_metadata.count = 0;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- op->op = GRPC_OP_RECV_INITIAL_METADATA;
- op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
- op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
- op->data.recv_status_on_client.status = &status;
- op->data.recv_status_on_client.status_details = &details;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
- nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- for (i = 0; i < 4; i++) {
- request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-
- op = ops;
- op->op = GRPC_OP_SEND_MESSAGE;
- op->data.send_message.send_message = request_payload;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- op->op = GRPC_OP_RECV_MESSAGE;
- op->data.recv_message.recv_message = &response_payload_recv;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
- nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
- cq_verify(cqv);
- gpr_log(GPR_INFO, "Client after sending msg %d / 4", i + 1);
- GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, PAYLOAD));
-
- grpc_byte_buffer_destroy(request_payload);
- grpc_byte_buffer_destroy(response_payload_recv);
- }
-
- grpc_slice_unref(request_payload_slice);
-
- op = ops;
- op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
- op->flags = 0;
- op->reserved = nullptr;
- op++;
- error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
- nullptr);
- GPR_ASSERT(GRPC_CALL_OK == error);
-
- CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
- CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
- cq_verify(cqv);
- peer = grpc_call_get_peer(c);
- gpr_log(GPR_INFO, "Client DONE WITH SERVER %s ", peer);
-
- grpc_call_unref(c);
-
- cq_verify_empty_timeout(cqv, 1 /* seconds */);
- cq_verifier_destroy(cqv);
-
- grpc_metadata_array_destroy(&initial_metadata_recv);
- grpc_metadata_array_destroy(&trailing_metadata_recv);
- grpc_slice_unref(details);
- gpr_log(GPR_INFO, "Client call (peer %s) DESTROYED.", peer);
- gpr_free(peer);
-}
-
-#define BALANCERS_NAME "lb.name"
-static void setup_client(const server_fixture* lb_server,
- const server_fixture* backends, client_fixture* cf) {
- grpc_core::ExecCtx exec_ctx;
-
- char* expected_target_names = nullptr;
- const char* backends_name = lb_server->servers_hostport;
- gpr_asprintf(&expected_target_names, "%s;%s", backends_name, BALANCERS_NAME);
-
- auto response_generator =
- grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>();
-
- grpc_lb_addresses* addresses = grpc_lb_addresses_create(1, nullptr);
- char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:%s", lb_server->servers_hostport);
- grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
- GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(addresses, 0, lb_uri, true,
- lb_server->balancer_name, nullptr);
- grpc_uri_destroy(lb_uri);
- gpr_free(lb_uri_str);
-
- gpr_asprintf(&cf->server_uri, "fake:///%s", lb_server->servers_hostport);
- const grpc_arg fake_addresses =
- grpc_lb_addresses_create_channel_arg(addresses);
- grpc_channel_args* fake_result =
- grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1);
- grpc_lb_addresses_destroy(addresses);
-
- grpc_arg new_args[] = {
- grpc_fake_transport_expected_targets_arg(expected_target_names),
- grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
- response_generator.get())};
-
- grpc_channel_args args = {GPR_ARRAY_SIZE(new_args), new_args};
-
- cf->cq = grpc_completion_queue_create_for_next(nullptr);
- grpc_channel_credentials* fake_creds =
- grpc_fake_transport_security_credentials_create();
- cf->client =
- grpc_secure_channel_create(fake_creds, cf->server_uri, &args, nullptr);
- response_generator->SetResponse(fake_result);
- grpc_channel_args_destroy(fake_result);
- grpc_channel_credentials_unref(fake_creds);
- gpr_free(expected_target_names);
-}
-
-static void teardown_client(client_fixture* cf) {
- grpc_completion_queue_shutdown(cf->cq);
- drain_cq(cf->cq);
- grpc_completion_queue_destroy(cf->cq);
- cf->cq = nullptr;
- grpc_channel_destroy(cf->client);
- cf->client = nullptr;
- gpr_free(cf->server_uri);
-}
-
-static void setup_server(const char* host, server_fixture* sf) {
- int assigned_port;
-
- sf->cq = grpc_completion_queue_create_for_next(nullptr);
- const char* colon_idx = strchr(host, ':');
- if (colon_idx) {
- const char* port_str = colon_idx + 1;
- sf->port = atoi(port_str);
- sf->servers_hostport = gpr_strdup(host);
- } else {
- sf->port = grpc_pick_unused_port_or_die();
- gpr_join_host_port(&sf->servers_hostport, host, sf->port);
- }
-
- grpc_server_credentials* server_creds =
- grpc_fake_transport_security_server_credentials_create();
-
- sf->server = grpc_server_create(nullptr, nullptr);
- grpc_server_register_completion_queue(sf->server, sf->cq, nullptr);
- GPR_ASSERT((assigned_port = grpc_server_add_secure_http2_port(
- sf->server, sf->servers_hostport, server_creds)) > 0);
- grpc_server_credentials_release(server_creds);
- GPR_ASSERT(sf->port == assigned_port);
- grpc_server_start(sf->server);
-}
-
-static void teardown_server(server_fixture* sf) {
- if (!sf->server) return;
-
- gpr_log(GPR_INFO, "Server[%s] shutting down", sf->servers_hostport);
-
- grpc_completion_queue* shutdown_cq =
- grpc_completion_queue_create_for_pluck(nullptr);
- grpc_server_shutdown_and_notify(sf->server, shutdown_cq, tag(1000));
- GPR_ASSERT(grpc_completion_queue_pluck(shutdown_cq, tag(1000),
- grpc_timeout_seconds_to_deadline(5),
- nullptr)
- .type == GRPC_OP_COMPLETE);
- grpc_completion_queue_destroy(shutdown_cq);
- grpc_server_destroy(sf->server);
- gpr_thd_join(sf->tid);
-
- sf->server = nullptr;
- grpc_completion_queue_shutdown(sf->cq);
- drain_cq(sf->cq);
- grpc_completion_queue_destroy(sf->cq);
-
- gpr_log(GPR_INFO, "Server[%s] bye bye", sf->servers_hostport);
- gpr_free(sf->servers_hostport);
-}
-
-static void fork_backend_server(void* arg) {
- server_fixture* sf = static_cast<server_fixture*>(arg);
- start_backend_server(sf);
-}
-
-static void fork_lb_server(void* arg) {
- test_fixture* tf = static_cast<test_fixture*>(arg);
- int ports[NUM_BACKENDS];
- for (int i = 0; i < NUM_BACKENDS; i++) {
- ports[i] = tf->lb_backends[i].port;
- }
- start_lb_server(&tf->lb_server, ports, NUM_BACKENDS,
- tf->lb_server_update_delay_ms);
-}
-
-#define LB_TOKEN_PREFIX "token"
-static test_fixture setup_test_fixture(int lb_server_update_delay_ms) {
- test_fixture tf;
- memset(&tf, 0, sizeof(tf));
- tf.lb_server_update_delay_ms = lb_server_update_delay_ms;
-
- gpr_thd_options options = gpr_thd_options_default();
- gpr_thd_options_set_joinable(&options);
-
- for (int i = 0; i < NUM_BACKENDS; ++i) {
- // Only the first half of the servers expect an LB token.
- if (i < NUM_BACKENDS / 2) {
- tf.lb_backends[i].lb_token_prefix = LB_TOKEN_PREFIX;
- } else {
- tf.lb_backends[i].lb_token_prefix = "";
- }
- setup_server("127.0.0.1", &tf.lb_backends[i]);
- gpr_thd_new(&tf.lb_backends[i].tid, "grpclb_backend", fork_backend_server,
- &tf.lb_backends[i], &options);
- }
-
- tf.lb_server.lb_token_prefix = LB_TOKEN_PREFIX;
- tf.lb_server.balancer_name = BALANCERS_NAME;
- setup_server("127.0.0.1", &tf.lb_server);
- gpr_thd_new(&tf.lb_server.tid, "grpclb_server", fork_lb_server, &tf.lb_server,
- &options);
- setup_client(&tf.lb_server, tf.lb_backends, &tf.client);
- return tf;
-}
-
-static void teardown_test_fixture(test_fixture* tf) {
- teardown_client(&tf->client);
- for (int i = 0; i < NUM_BACKENDS; ++i) {
- teardown_server(&tf->lb_backends[i]);
- }
- teardown_server(&tf->lb_server);
-}
-
-// The LB server will send two updates: batch 1 and batch 2. Each batch contains
-// two addresses, both of a valid and running backend server. Batch 1 is readily
-// available and provided as soon as the client establishes the streaming call.
-// Batch 2 is sent after a delay of \a lb_server_update_delay_ms milliseconds.
-static test_fixture test_update(int lb_server_update_delay_ms) {
- gpr_log(GPR_INFO, "start %s(%d)", __func__, lb_server_update_delay_ms);
- test_fixture tf = setup_test_fixture(lb_server_update_delay_ms);
- perform_request(
- &tf.client); // "consumes" 1st backend server of 1st serverlist
- perform_request(
- &tf.client); // "consumes" 2nd backend server of 1st serverlist
-
- perform_request(
- &tf.client); // "consumes" 1st backend server of 2nd serverlist
- perform_request(
- &tf.client); // "consumes" 2nd backend server of 2nd serverlist
-
- teardown_test_fixture(&tf);
- gpr_log(GPR_INFO, "end %s(%d)", __func__, lb_server_update_delay_ms);
- return tf;
-}
-
-TEST(GrpclbTest, Updates) {
- grpc::test_fixture tf_result;
- // Clients take at least one second to complete a call (the last part of the
- // call sleeps for 1 second while verifying the client's completion queue is
- // empty), more if the system is under load. Therefore:
- //
- // If the LB server waits 800ms before sending an update, it will arrive
- // before the first client request finishes, skipping the second server from
- // batch 1. All subsequent picks will come from the second half of the
- // backends, those coming in the LB update.
- tf_result = grpc::test_update(800);
- GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced +
- tf_result.lb_backends[1].num_calls_serviced ==
- 1);
- GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced +
- tf_result.lb_backends[3].num_calls_serviced >
- 0);
- int num_serviced_calls = 0;
- for (int i = 0; i < 4; i++) {
- num_serviced_calls += tf_result.lb_backends[i].num_calls_serviced;
- }
- GPR_ASSERT(num_serviced_calls == 4);
-
- // If the LB server waits 2500ms, the update arrives after two calls and three
- // picks. The third pick will be the 1st server of the 1st update (RR policy
- // going around). The fourth and final pick will come from the second LB
- // update. In any case, the total number of serviced calls must again be equal
- // to four across all the backends.
- tf_result = grpc::test_update(2500);
- GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced +
- tf_result.lb_backends[1].num_calls_serviced >=
- 2);
- GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced +
- tf_result.lb_backends[3].num_calls_serviced >
- 0);
- num_serviced_calls = 0;
- for (int i = 0; i < 4; i++) {
- num_serviced_calls += tf_result.lb_backends[i].num_calls_serviced;
- }
- GPR_ASSERT(num_serviced_calls == 4);
-}
-
-TEST(GrpclbTest, InvalidAddressInServerlist) {}
-
-} // namespace
-} // namespace grpc
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- grpc_test_init(argc, argv);
- // Make the backup poller poll very frequently in order to pick up
- // updates from all the subchannels's FDs.
- gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1");
- grpc_init();
- const auto result = RUN_ALL_TESTS();
- grpc_shutdown();
- return result;
-}
diff --git a/test/cpp/test/BUILD b/test/cpp/test/BUILD
new file mode 100644
index 0000000000..c549478919
--- /dev/null
+++ b/test/cpp/test/BUILD
@@ -0,0 +1,39 @@
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+licenses(["notice"]) # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary")
+
+grpc_package(
+ name = "test/cpp/test",
+ visibility = "public",
+)
+
+grpc_cc_test(
+ name = "server_context_test_spouse_test",
+ srcs = ["server_context_test_spouse_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//:grpc++",
+ "//:grpc++_test",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
diff --git a/test/cpp/thread_manager/BUILD b/test/cpp/thread_manager/BUILD
new file mode 100644
index 0000000000..093e51e3fa
--- /dev/null
+++ b/test/cpp/thread_manager/BUILD
@@ -0,0 +1,40 @@
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+licenses(["notice"]) # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_library", "grpc_cc_test", "grpc_package", "grpc_cc_binary")
+
+grpc_package(
+ name = "test/cpp/thread_manager",
+ visibility = "public",
+)
+
+grpc_cc_test(
+ name = "thread_manager_test",
+ srcs = ["thread_manager_test.cc"],
+ external_deps = [
+ "gflags",
+ "gtest",
+ ],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//:grpc++",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_config",
+ "//test/cpp/util:test_util",
+ ],
+)
diff --git a/third_party/BUILD b/third_party/BUILD
index dea1229684..f06c5e9c67 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -3,4 +3,9 @@ exports_files([
"gtest.BUILD",
"objective_c/Cronet/bidirectional_stream_c.h",
"zlib.BUILD",
+ "twisted.BUILD",
+ "yaml.BUILD",
+ "incremental.BUILD",
+ "zope_interface.BUILD",
+ "constantly.BUILD",
])
diff --git a/third_party/constantly.BUILD b/third_party/constantly.BUILD
new file mode 100644
index 0000000000..f1f93cb79f
--- /dev/null
+++ b/third_party/constantly.BUILD
@@ -0,0 +1,7 @@
+py_library(
+ name = "constantly",
+ srcs = glob(["constantly/*.py"]),
+ visibility = [
+ "//visibility:public",
+ ],
+)
diff --git a/third_party/incremental.BUILD b/third_party/incremental.BUILD
new file mode 100644
index 0000000000..f2a06b49dc
--- /dev/null
+++ b/third_party/incremental.BUILD
@@ -0,0 +1,10 @@
+py_library(
+ name = "incremental",
+ srcs = glob(["src/incremental/*.py"]),
+ imports = [
+ "src",
+ ],
+ visibility = [
+ "//visibility:public",
+ ],
+)
diff --git a/third_party/twisted.BUILD b/third_party/twisted.BUILD
new file mode 100644
index 0000000000..5005c5a3f8
--- /dev/null
+++ b/third_party/twisted.BUILD
@@ -0,0 +1,15 @@
+py_library(
+ name = "twisted",
+ srcs = glob(["src/twisted/**/*.py"]),
+ imports = [
+ "src",
+ ],
+ visibility = [
+ "//visibility:public",
+ ],
+ deps = [
+ "@com_github_twisted_incremental//:incremental",
+ "@com_github_twisted_constantly//:constantly",
+ "@com_github_zopefoundation_zope_interface//:zope_interface",
+ ],
+)
diff --git a/third_party/yaml.BUILD b/third_party/yaml.BUILD
new file mode 100644
index 0000000000..f88854c571
--- /dev/null
+++ b/third_party/yaml.BUILD
@@ -0,0 +1,10 @@
+py_library(
+ name = "yaml",
+ srcs = glob(["lib/yaml/*.py"]),
+ imports = [
+ "lib",
+ ],
+ visibility = [
+ "//visibility:public",
+ ],
+)
diff --git a/third_party/zope_interface.BUILD b/third_party/zope_interface.BUILD
new file mode 100644
index 0000000000..b7b8d1e6cf
--- /dev/null
+++ b/third_party/zope_interface.BUILD
@@ -0,0 +1,13 @@
+py_library(
+ name = "zope_interface",
+ srcs = glob([
+ "src/zope/interface/*.py",
+ "src/zope/interface/common/*.py",
+ ]),
+ imports = [
+ "src",
+ ],
+ visibility = [
+ "//visibility:public",
+ ],
+)
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index 066f28416d..25da3fdd5f 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -45,6 +45,12 @@ CONFIG = [
'grpc-server-stats-bin',
'grpc-tags-bin',
'grpc-trace-bin',
+ 'grpc-previous-rpc-attempts',
+ 'grpc-retry-pushback-ms',
+ '1',
+ '2',
+ '3',
+ '4',
'',
# channel arg keys
'grpc.wait_for_ready',
@@ -163,6 +169,8 @@ METADATA_BATCH_CALLOUTS = [
('user-agent', True),
('host', True),
('lb-token', True),
+ ('grpc-previous-rpc-attempts', True),
+ ('grpc-retry-pushback-ms', True),
]
COMPRESSION_ALGORITHMS = [
diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py
index 6fc606f2ef..05d34c2b28 100755
--- a/tools/distrib/check_include_guards.py
+++ b/tools/distrib/check_include_guards.py
@@ -49,7 +49,7 @@ class GuardValidator(object):
self.failed = False
def fail(self, fpath, regexp, fcontents, match_txt, correct, fix):
- cpp_header = 'grpc++' in fpath
+ cpp_header = 'grpc++' in fpath or 'grpcpp' in fpath
self.failed = True
invalid_guards_msg_template = (
'{0}: Missing preprocessor guards (RE {1}). '
@@ -78,7 +78,7 @@ class GuardValidator(object):
return fcontents
def check(self, fpath, fix):
- cpp_header = 'grpc++' in fpath
+ cpp_header = 'grpc++' in fpath or 'grpcpp' in fpath
valid_guard = build_valid_guard(fpath)
fcontents = load(fpath)
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 5caa1d1078..e8ca6851eb 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.10.0.dev0'
+VERSION = '1.11.0.dev0'
diff --git a/tools/dockerfile/test/bazel/Dockerfile b/tools/dockerfile/test/bazel/Dockerfile
index ba668eafc7..e5e81136cb 100644
--- a/tools/dockerfile/test/bazel/Dockerfile
+++ b/tools/dockerfile/test/bazel/Dockerfile
@@ -33,12 +33,12 @@ RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
RUN apt-get -y update
RUN apt-get -y install bazel
-# Pin Bazel to 0.4.4
-# Installing Bazel via apt-get first is required before installing 0.4.4 to
+# Pin Bazel to 0.9.0
+# Installing Bazel via apt-get first is required before installing 0.9.0 to
# allow gRPC to build without errors. See https://github.com/grpc/grpc/issues/10553
-RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.4.4/bazel-0.4.4-installer-linux-x86_64.sh
-RUN chmod +x ./bazel-0.4.4-installer-linux-x86_64.sh
-RUN ./bazel-0.4.4-installer-linux-x86_64.sh
+RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.9.0/bazel-0.9.0-installer-linux-x86_64.sh
+RUN chmod +x ./bazel-0.9.0-installer-linux-x86_64.sh
+RUN ./bazel-0.9.0-installer-linux-x86_64.sh
RUN mkdir -p /var/local/jenkins
diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile
index 7a8e1c09b1..f65adf589d 100644
--- a/tools/dockerfile/test/sanity/Dockerfile
+++ b/tools/dockerfile/test/sanity/Dockerfile
@@ -98,12 +98,12 @@ RUN curl https://bazel.build/bazel-release.pub.gpg | apt-key add -
RUN apt-get -y update
RUN apt-get -y install bazel
-# Pin Bazel to 0.4.4
-# Installing Bazel via apt-get first is required before installing 0.4.4 to
+# Pin Bazel to 0.9.0
+# Installing Bazel via apt-get first is required before installing 0.9.0 to
# allow gRPC to build without errors. See https://github.com/grpc/grpc/issues/10553
-RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.4.4/bazel-0.4.4-installer-linux-x86_64.sh
-RUN chmod +x ./bazel-0.4.4-installer-linux-x86_64.sh
-RUN ./bazel-0.4.4-installer-linux-x86_64.sh
+RUN curl -fSsL -O https://github.com/bazelbuild/bazel/releases/download/0.9.0/bazel-0.9.0-installer-linux-x86_64.sh
+RUN chmod +x ./bazel-0.9.0-installer-linux-x86_64.sh
+RUN ./bazel-0.9.0-installer-linux-x86_64.sh
RUN apt-get update && apt-get -y install wget xz-utils
RUN wget http://releases.llvm.org/5.0.0/clang+llvm-5.0.0-linux-x86_64-ubuntu14.04.tar.xz
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 487753585b..eb6700d529 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.10.0-dev
+PROJECT_NUMBER = 1.11.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -919,9 +919,86 @@ include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
-include/grpc/support/thd.h \
+include/grpc/support/thd_id.h \
include/grpc/support/time.h \
-include/grpc/support/workaround_list.h
+include/grpc/support/workaround_list.h \
+include/grpcpp/alarm.h \
+include/grpcpp/channel.h \
+include/grpcpp/client_context.h \
+include/grpcpp/completion_queue.h \
+include/grpcpp/create_channel.h \
+include/grpcpp/create_channel_posix.h \
+include/grpcpp/ext/health_check_service_server_builder_option.h \
+include/grpcpp/generic/async_generic_service.h \
+include/grpcpp/generic/generic_stub.h \
+include/grpcpp/grpcpp.h \
+include/grpcpp/health_check_service_interface.h \
+include/grpcpp/impl/call.h \
+include/grpcpp/impl/channel_argument_option.h \
+include/grpcpp/impl/client_unary_call.h \
+include/grpcpp/impl/codegen/async_stream.h \
+include/grpcpp/impl/codegen/async_unary_call.h \
+include/grpcpp/impl/codegen/byte_buffer.h \
+include/grpcpp/impl/codegen/call.h \
+include/grpcpp/impl/codegen/call_hook.h \
+include/grpcpp/impl/codegen/channel_interface.h \
+include/grpcpp/impl/codegen/client_context.h \
+include/grpcpp/impl/codegen/client_unary_call.h \
+include/grpcpp/impl/codegen/completion_queue.h \
+include/grpcpp/impl/codegen/completion_queue_tag.h \
+include/grpcpp/impl/codegen/config.h \
+include/grpcpp/impl/codegen/config_protobuf.h \
+include/grpcpp/impl/codegen/core_codegen.h \
+include/grpcpp/impl/codegen/core_codegen_interface.h \
+include/grpcpp/impl/codegen/create_auth_context.h \
+include/grpcpp/impl/codegen/grpc_library.h \
+include/grpcpp/impl/codegen/metadata_map.h \
+include/grpcpp/impl/codegen/method_handler_impl.h \
+include/grpcpp/impl/codegen/proto_utils.h \
+include/grpcpp/impl/codegen/rpc_method.h \
+include/grpcpp/impl/codegen/rpc_service_method.h \
+include/grpcpp/impl/codegen/security/auth_context.h \
+include/grpcpp/impl/codegen/serialization_traits.h \
+include/grpcpp/impl/codegen/server_context.h \
+include/grpcpp/impl/codegen/server_interface.h \
+include/grpcpp/impl/codegen/service_type.h \
+include/grpcpp/impl/codegen/slice.h \
+include/grpcpp/impl/codegen/status.h \
+include/grpcpp/impl/codegen/status_code_enum.h \
+include/grpcpp/impl/codegen/string_ref.h \
+include/grpcpp/impl/codegen/stub_options.h \
+include/grpcpp/impl/codegen/sync_stream.h \
+include/grpcpp/impl/codegen/time.h \
+include/grpcpp/impl/grpc_library.h \
+include/grpcpp/impl/method_handler_impl.h \
+include/grpcpp/impl/rpc_method.h \
+include/grpcpp/impl/rpc_service_method.h \
+include/grpcpp/impl/serialization_traits.h \
+include/grpcpp/impl/server_builder_option.h \
+include/grpcpp/impl/server_builder_plugin.h \
+include/grpcpp/impl/server_initializer.h \
+include/grpcpp/impl/service_type.h \
+include/grpcpp/resource_quota.h \
+include/grpcpp/security/auth_context.h \
+include/grpcpp/security/auth_metadata_processor.h \
+include/grpcpp/security/credentials.h \
+include/grpcpp/security/server_credentials.h \
+include/grpcpp/server.h \
+include/grpcpp/server_builder.h \
+include/grpcpp/server_context.h \
+include/grpcpp/server_posix.h \
+include/grpcpp/support/async_stream.h \
+include/grpcpp/support/async_unary_call.h \
+include/grpcpp/support/byte_buffer.h \
+include/grpcpp/support/channel_arguments.h \
+include/grpcpp/support/config.h \
+include/grpcpp/support/slice.h \
+include/grpcpp/support/status.h \
+include/grpcpp/support/status_code_enum.h \
+include/grpcpp/support/string_ref.h \
+include/grpcpp/support/stub_options.h \
+include/grpcpp/support/sync_stream.h \
+include/grpcpp/support/time.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 2cbc032d8d..c352a0a6c4 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.10.0-dev
+PROJECT_NUMBER = 1.11.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -920,9 +920,87 @@ include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
-include/grpc/support/thd.h \
+include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/support/workaround_list.h \
+include/grpcpp/alarm.h \
+include/grpcpp/channel.h \
+include/grpcpp/client_context.h \
+include/grpcpp/completion_queue.h \
+include/grpcpp/create_channel.h \
+include/grpcpp/create_channel_posix.h \
+include/grpcpp/ext/health_check_service_server_builder_option.h \
+include/grpcpp/generic/async_generic_service.h \
+include/grpcpp/generic/generic_stub.h \
+include/grpcpp/grpcpp.h \
+include/grpcpp/health_check_service_interface.h \
+include/grpcpp/impl/call.h \
+include/grpcpp/impl/channel_argument_option.h \
+include/grpcpp/impl/client_unary_call.h \
+include/grpcpp/impl/codegen/async_stream.h \
+include/grpcpp/impl/codegen/async_unary_call.h \
+include/grpcpp/impl/codegen/byte_buffer.h \
+include/grpcpp/impl/codegen/call.h \
+include/grpcpp/impl/codegen/call_hook.h \
+include/grpcpp/impl/codegen/channel_interface.h \
+include/grpcpp/impl/codegen/client_context.h \
+include/grpcpp/impl/codegen/client_unary_call.h \
+include/grpcpp/impl/codegen/completion_queue.h \
+include/grpcpp/impl/codegen/completion_queue_tag.h \
+include/grpcpp/impl/codegen/config.h \
+include/grpcpp/impl/codegen/config_protobuf.h \
+include/grpcpp/impl/codegen/core_codegen.h \
+include/grpcpp/impl/codegen/core_codegen.h \
+include/grpcpp/impl/codegen/core_codegen_interface.h \
+include/grpcpp/impl/codegen/create_auth_context.h \
+include/grpcpp/impl/codegen/grpc_library.h \
+include/grpcpp/impl/codegen/metadata_map.h \
+include/grpcpp/impl/codegen/method_handler_impl.h \
+include/grpcpp/impl/codegen/proto_utils.h \
+include/grpcpp/impl/codegen/rpc_method.h \
+include/grpcpp/impl/codegen/rpc_service_method.h \
+include/grpcpp/impl/codegen/security/auth_context.h \
+include/grpcpp/impl/codegen/serialization_traits.h \
+include/grpcpp/impl/codegen/server_context.h \
+include/grpcpp/impl/codegen/server_interface.h \
+include/grpcpp/impl/codegen/service_type.h \
+include/grpcpp/impl/codegen/slice.h \
+include/grpcpp/impl/codegen/status.h \
+include/grpcpp/impl/codegen/status_code_enum.h \
+include/grpcpp/impl/codegen/string_ref.h \
+include/grpcpp/impl/codegen/stub_options.h \
+include/grpcpp/impl/codegen/sync_stream.h \
+include/grpcpp/impl/codegen/time.h \
+include/grpcpp/impl/grpc_library.h \
+include/grpcpp/impl/method_handler_impl.h \
+include/grpcpp/impl/rpc_method.h \
+include/grpcpp/impl/rpc_service_method.h \
+include/grpcpp/impl/serialization_traits.h \
+include/grpcpp/impl/server_builder_option.h \
+include/grpcpp/impl/server_builder_plugin.h \
+include/grpcpp/impl/server_initializer.h \
+include/grpcpp/impl/service_type.h \
+include/grpcpp/resource_quota.h \
+include/grpcpp/security/auth_context.h \
+include/grpcpp/security/auth_metadata_processor.h \
+include/grpcpp/security/credentials.h \
+include/grpcpp/security/server_credentials.h \
+include/grpcpp/server.h \
+include/grpcpp/server_builder.h \
+include/grpcpp/server_context.h \
+include/grpcpp/server_posix.h \
+include/grpcpp/support/async_stream.h \
+include/grpcpp/support/async_unary_call.h \
+include/grpcpp/support/byte_buffer.h \
+include/grpcpp/support/channel_arguments.h \
+include/grpcpp/support/config.h \
+include/grpcpp/support/slice.h \
+include/grpcpp/support/status.h \
+include/grpcpp/support/status_code_enum.h \
+include/grpcpp/support/string_ref.h \
+include/grpcpp/support/stub_options.h \
+include/grpcpp/support/sync_stream.h \
+include/grpcpp/support/time.h \
src/core/ext/transport/inproc/inproc_transport.h \
src/core/lib/avl/avl.h \
src/core/lib/backoff/backoff.h \
@@ -954,7 +1032,7 @@ src/core/lib/gpr/murmur_hash.h \
src/core/lib/gpr/spinlock.h \
src/core/lib/gpr/string.h \
src/core/lib/gpr/string_windows.h \
-src/core/lib/gpr/thd_internal.h \
+src/core/lib/gpr/thd.h \
src/core/lib/gpr/time_precise.h \
src/core/lib/gpr/tls.h \
src/core/lib/gpr/tls_gcc.h \
@@ -1049,6 +1127,7 @@ src/core/lib/slice/percent_encoding.h \
src/core/lib/slice/slice_hash_table.h \
src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/slice/slice_weak_hash_table.h \
src/core/lib/surface/api_trace.h \
src/core/lib/surface/call.h \
src/core/lib/surface/call_test_only.h \
@@ -1073,6 +1152,7 @@ src/core/lib/transport/pid_controller.h \
src/core/lib/transport/service_config.h \
src/core/lib/transport/static_metadata.h \
src/core/lib/transport/status_conversion.h \
+src/core/lib/transport/status_metadata.h \
src/core/lib/transport/timeout_encoding.h \
src/core/lib/transport/transport.h \
src/core/lib/transport/transport_impl.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index d398783637..04f9d78850 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -859,7 +859,7 @@ include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
-include/grpc/support/thd.h \
+include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/support/workaround_list.h
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index b973f27629..cd235c0d77 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -859,7 +859,7 @@ include/grpc/support/sync_custom.h \
include/grpc/support/sync_generic.h \
include/grpc/support/sync_posix.h \
include/grpc/support/sync_windows.h \
-include/grpc/support/thd.h \
+include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/support/workaround_list.h \
src/core/README.md \
@@ -885,7 +885,6 @@ src/core/ext/filters/client_channel/lb_policy.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \
-src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \
src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \
@@ -902,6 +901,8 @@ src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_factory.h \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/lb_policy_registry.h \
+src/core/ext/filters/client_channel/method_params.cc \
+src/core/ext/filters/client_channel/method_params.h \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/parse_address.h \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -928,6 +929,8 @@ src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_registry.h \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/retry_throttle.h \
+src/core/ext/filters/client_channel/status_util.cc \
+src/core/ext/filters/client_channel/status_util.h \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel.h \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -1099,7 +1102,7 @@ src/core/lib/gpr/sync.cc \
src/core/lib/gpr/sync_posix.cc \
src/core/lib/gpr/sync_windows.cc \
src/core/lib/gpr/thd.cc \
-src/core/lib/gpr/thd_internal.h \
+src/core/lib/gpr/thd.h \
src/core/lib/gpr/thd_posix.cc \
src/core/lib/gpr/thd_windows.cc \
src/core/lib/gpr/time.cc \
@@ -1310,17 +1313,17 @@ src/core/lib/security/credentials/plugin/plugin_credentials.cc \
src/core/lib/security/credentials/plugin/plugin_credentials.h \
src/core/lib/security/credentials/ssl/ssl_credentials.cc \
src/core/lib/security/credentials/ssl/ssl_credentials.h \
+src/core/lib/security/security_connector/security_connector.cc \
+src/core/lib/security/security_connector/security_connector.h \
src/core/lib/security/transport/auth_filters.h \
src/core/lib/security/transport/client_auth_filter.cc \
-src/core/lib/security/transport/lb_targets_info.cc \
-src/core/lib/security/transport/lb_targets_info.h \
src/core/lib/security/transport/secure_endpoint.cc \
src/core/lib/security/transport/secure_endpoint.h \
-src/core/lib/security/transport/security_connector.cc \
-src/core/lib/security/transport/security_connector.h \
src/core/lib/security/transport/security_handshaker.cc \
src/core/lib/security/transport/security_handshaker.h \
src/core/lib/security/transport/server_auth_filter.cc \
+src/core/lib/security/transport/target_authority_table.cc \
+src/core/lib/security/transport/target_authority_table.h \
src/core/lib/security/transport/tsi_error.cc \
src/core/lib/security/transport/tsi_error.h \
src/core/lib/security/util/json_util.cc \
@@ -1331,12 +1334,12 @@ src/core/lib/slice/percent_encoding.cc \
src/core/lib/slice/percent_encoding.h \
src/core/lib/slice/slice.cc \
src/core/lib/slice/slice_buffer.cc \
-src/core/lib/slice/slice_hash_table.cc \
src/core/lib/slice/slice_hash_table.h \
src/core/lib/slice/slice_intern.cc \
src/core/lib/slice/slice_internal.h \
src/core/lib/slice/slice_string_helpers.cc \
src/core/lib/slice/slice_string_helpers.h \
+src/core/lib/slice/slice_weak_hash_table.h \
src/core/lib/surface/README.md \
src/core/lib/surface/api_trace.cc \
src/core/lib/surface/api_trace.h \
@@ -1393,6 +1396,8 @@ src/core/lib/transport/static_metadata.cc \
src/core/lib/transport/static_metadata.h \
src/core/lib/transport/status_conversion.cc \
src/core/lib/transport/status_conversion.h \
+src/core/lib/transport/status_metadata.cc \
+src/core/lib/transport/status_metadata.h \
src/core/lib/transport/timeout_encoding.cc \
src/core/lib/transport/timeout_encoding.h \
src/core/lib/transport/transport.cc \
diff --git a/tools/gce/create_interop_worker.sh b/tools/gce/create_interop_worker.sh
index 3e59dc501a..205c0bf8c5 100755
--- a/tools/gce/create_interop_worker.sh
+++ b/tools/gce/create_interop_worker.sh
@@ -20,14 +20,14 @@
set -ex
-cd $(dirname $0)
+cd "$(dirname "$0")"
CLOUD_PROJECT=grpc-testing
ZONE=us-east1-a # canary gateway is reachable from this zone
INSTANCE_NAME="${1:-grpc-canary-interop2}"
-gcloud compute instances create $INSTANCE_NAME \
+gcloud compute instances create "$INSTANCE_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
--machine-type n1-standard-16 \
@@ -42,9 +42,9 @@ sleep 60
gcloud compute copy-files \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- jenkins_master.pub linux_worker_init.sh ${INSTANCE_NAME}:~
+ jenkins_master.pub linux_worker_init.sh "${INSTANCE_NAME}":~
gcloud compute ssh \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- $INSTANCE_NAME --command "./linux_worker_init.sh"
+ "$INSTANCE_NAME" --command "./linux_worker_init.sh"
diff --git a/tools/gce/create_linux_kokoro_performance_worker.sh b/tools/gce/create_linux_kokoro_performance_worker.sh
index a25cc5b6a3..d08a1aa2c6 100755
--- a/tools/gce/create_linux_kokoro_performance_worker.sh
+++ b/tools/gce/create_linux_kokoro_performance_worker.sh
@@ -17,7 +17,7 @@
set -ex
-cd $(dirname $0)
+cd "$(dirname "$0")"
CLOUD_PROJECT=grpc-testing
ZONE=us-central1-b # this zone allows 32core machines
@@ -25,7 +25,7 @@ ZONE=us-central1-b # this zone allows 32core machines
INSTANCE_NAME="${1:-grpc-kokoro-performance-server1}"
MACHINE_TYPE=n1-standard-32
-gcloud compute instances create $INSTANCE_NAME \
+gcloud compute instances create "$INSTANCE_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
--machine-type $MACHINE_TYPE \
@@ -41,9 +41,9 @@ sleep 60
gcloud compute copy-files \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- kokoro_performance.pub linux_kokoro_performance_worker_init.sh kbuilder@${INSTANCE_NAME}:~
+ kokoro_performance.pub linux_kokoro_performance_worker_init.sh "kbuilder@${INSTANCE_NAME}":~
gcloud compute ssh \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- kbuilder@${INSTANCE_NAME} --command "./linux_kokoro_performance_worker_init.sh"
+ "kbuilder@${INSTANCE_NAME}" --command "./linux_kokoro_performance_worker_init.sh"
diff --git a/tools/gce/create_linux_performance_worker.sh b/tools/gce/create_linux_performance_worker.sh
index e3bc1d577d..e9033ec443 100755
--- a/tools/gce/create_linux_performance_worker.sh
+++ b/tools/gce/create_linux_performance_worker.sh
@@ -21,7 +21,7 @@
set -ex
-cd $(dirname $0)
+cd "$(dirname "$0")"
CLOUD_PROJECT=grpc-testing
ZONE=us-central1-b # this zone allows 32core machines
@@ -29,7 +29,7 @@ ZONE=us-central1-b # this zone allows 32core machines
INSTANCE_NAME="${1:-grpc-performance-server1}"
MACHINE_TYPE=n1-standard-32
-gcloud compute instances create $INSTANCE_NAME \
+gcloud compute instances create "$INSTANCE_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
--machine-type $MACHINE_TYPE \
@@ -45,9 +45,9 @@ sleep 60
gcloud compute copy-files \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- jenkins_master.pub linux_performance_worker_init.sh jenkins@${INSTANCE_NAME}:~
+ jenkins_master.pub linux_performance_worker_init.sh "jenkins@${INSTANCE_NAME}":~
gcloud compute ssh \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- jenkins@${INSTANCE_NAME} --command "./linux_performance_worker_init.sh"
+ "jenkins@${INSTANCE_NAME}" --command "./linux_performance_worker_init.sh"
diff --git a/tools/gce/create_linux_worker.sh b/tools/gce/create_linux_worker.sh
index 8bf44aa729..a93d8c5e83 100755
--- a/tools/gce/create_linux_worker.sh
+++ b/tools/gce/create_linux_worker.sh
@@ -17,14 +17,14 @@
set -ex
-cd $(dirname $0)
+cd "$(dirname "$0")"
CLOUD_PROJECT=grpc-testing
ZONE=us-central1-a
INSTANCE_NAME="${1:-grpc-jenkins-worker1}"
-gcloud compute instances create $INSTANCE_NAME \
+gcloud compute instances create "$INSTANCE_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
--machine-type n1-standard-16 \
@@ -40,9 +40,9 @@ sleep 60
gcloud compute copy-files \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- jenkins_master.pub linux_worker_init.sh ${INSTANCE_NAME}:~
+ jenkins_master.pub linux_worker_init.sh "${INSTANCE_NAME}":~
gcloud compute ssh \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- $INSTANCE_NAME --command "./linux_worker_init.sh"
+ "$INSTANCE_NAME" --command "./linux_worker_init.sh"
diff --git a/tools/gce/create_windows_debug_worker.sh b/tools/gce/create_windows_debug_worker.sh
index da8050be4b..6f903b58fe 100755
--- a/tools/gce/create_windows_debug_worker.sh
+++ b/tools/gce/create_windows_debug_worker.sh
@@ -19,7 +19,7 @@
set -ex
-cd $(dirname $0)
+cd "$(dirname "$0")"
CLOUD_PROJECT=grpc-testing
ZONE=us-central1-b
@@ -34,7 +34,7 @@ fi
MACHINE_TYPE=n1-standard-8
TMP_DISK_NAME="$INSTANCE_NAME-temp-disk"
-gcloud compute disks create $TMP_DISK_NAME \
+gcloud compute disks create "$TMP_DISK_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
--image-project google.com:kokoro \
@@ -44,13 +44,13 @@ gcloud compute disks create $TMP_DISK_NAME \
echo 'Created scratch disk, waiting for it to become available.'
sleep 15
-gcloud compute instances create $INSTANCE_NAME \
+gcloud compute instances create "$INSTANCE_NAME" \
--project="$CLOUD_PROJECT" \
--zone "$ZONE" \
- --machine-type $MACHINE_TYPE \
+ --machine-type "$MACHINE_TYPE" \
--image-project google.com:kokoro \
--image kokoro-win7build-v9-prod-debug \
--boot-disk-size 500 \
--boot-disk-type pd-ssd \
--tags=allow-ssh \
- --disk auto-delete=yes,boot=no,name=$TMP_DISK_NAME
+ --disk "auto-delete=yes,boot=no,name=$TMP_DISK_NAME"
diff --git a/tools/gce/linux_kokoro_performance_worker_init.sh b/tools/gce/linux_kokoro_performance_worker_init.sh
index 460f639f9f..1f98d24595 100755
--- a/tools/gce/linux_kokoro_performance_worker_init.sh
+++ b/tools/gce/linux_kokoro_performance_worker_init.sh
@@ -81,10 +81,11 @@ sudo pip install virtualenv
# is not available on Ubuntu 16.10, so install from source
curl -O https://www.python.org/ftp/python/3.4.6/Python-3.4.6.tgz
tar xzvf Python-3.4.6.tgz
-cd Python-3.4.6
+(
+cd Python-3.4.6 || exit
./configure --enable-shared --prefix=/usr/local LDFLAGS="-Wl,--rpath=/usr/local/lib"
sudo make altinstall
-cd ..
+)
rm Python-3.4.6.tgz
curl -O https://bootstrap.pypa.io/get-pip.py
@@ -95,6 +96,8 @@ sudo pip install google-api-python-client
# Node dependencies (nvm has to be installed under user kbuilder)
touch .profile
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
+# silence shellcheck as it cannot follow the following `source` path statically:
+# shellcheck disable=SC1090
source ~/.nvm/nvm.sh
nvm install 0.12 && npm config set cache /tmp/npm-cache
nvm install 4 && npm config set cache /tmp/npm-cache
@@ -130,6 +133,8 @@ sudo apt-get update && sudo apt-get install -y libicu55
# Ruby dependencies
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s stable --ruby
+# silence shellcheck as it cannot follow the following `source` path statically:
+# shellcheck disable=SC1090
source ~/.rvm/scripts/rvm
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
@@ -168,7 +173,7 @@ sudo ln -s /usr/local/go/bin/go /usr/bin/go
rm go$GO_VERSION.$OS-$ARCH.tar.gz
# Install perf, to profile benchmarks. (need to get the right linux-tools-<> for kernel version)
-sudo apt-get install -y linux-tools-common linux-tools-generic linux-tools-`uname -r`
+sudo apt-get install -y linux-tools-common linux-tools-generic "linux-tools-$(uname -r)"
# see http://unix.stackexchange.com/questions/14227/do-i-need-root-admin-permissions-to-run-userspace-perf-tool-perf-events-ar
echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid
# see http://stackoverflow.com/questions/21284906/perf-couldnt-record-kernel-reference-relocation-symbol
@@ -186,7 +191,9 @@ git clone -v https://github.com/brendangregg/FlameGraph ~/FlameGraph
sudo apt-get install -y python-scipy python-numpy
# Add pubkey of Kokoro driver VM to allow SSH
-cat kokoro_performance.pub | sudo tee --append ~kbuilder/.ssh/authorized_keys
+# silence false-positive shellcheck warning ("< redirect does not affect sudo")
+# shellcheck disable=SC2024
+sudo tee --append ~kbuilder/.ssh/authorized_keys < kokoro_performance.pub
# Restart for VM to pick up kernel update
echo 'Successfully initialized the linux worker, going for reboot in 10 seconds'
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index 8d900f1d16..6f6866096d 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -81,10 +81,11 @@ sudo pip install virtualenv
# is not available on Ubuntu 16.10, so install from source
curl -O https://www.python.org/ftp/python/3.4.6/Python-3.4.6.tgz
tar xzvf Python-3.4.6.tgz
-cd Python-3.4.6
+(
+cd Python-3.4.6 || exit
./configure --enable-shared --prefix=/usr/local LDFLAGS="-Wl,--rpath=/usr/local/lib"
sudo make altinstall
-cd ..
+)
rm Python-3.4.6.tgz
curl -O https://bootstrap.pypa.io/get-pip.py
@@ -95,6 +96,8 @@ sudo pip install google-api-python-client
# Node dependencies (nvm has to be installed under user jenkins)
touch .profile
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
+# silence shellcheck warning as it cannot follow the `source` path statically:
+# shellcheck disable=SC1090
source ~/.nvm/nvm.sh
nvm install 0.12 && npm config set cache /tmp/npm-cache
nvm install 4 && npm config set cache /tmp/npm-cache
@@ -151,7 +154,7 @@ sudo ln -s /usr/local/go/bin/go /usr/bin/go
rm go$GO_VERSION.$OS-$ARCH.tar.gz
# Install perf, to profile benchmarks. (need to get the right linux-tools-<> for kernel version)
-sudo apt-get install -y linux-tools-common linux-tools-generic linux-tools-`uname -r`
+sudo apt-get install -y linux-tools-common linux-tools-generic "linux-tools-$(uname -r)"
# see http://unix.stackexchange.com/questions/14227/do-i-need-root-admin-permissions-to-run-userspace-perf-tool-perf-events-ar
echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid
# see http://stackoverflow.com/questions/21284906/perf-couldnt-record-kernel-reference-relocation-symbol
@@ -171,7 +174,9 @@ sudo apt-get install -y python-scipy python-numpy
# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@
# This needs to happen as the last step to prevent Jenkins master from connecting
# to a machine that hasn't been properly setup yet.
-cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys
+# silence false-positive shellcheck warning ("< redirect does not affect sudo")
+# shellcheck disable=SC2024
+sudo tee --append ~jenkins/.ssh/authorized_keys < jenkins_master.pub
# Restart for VM to pick up kernel update
echo 'Successfully initialized the linux worker, going for reboot in 10 seconds'
diff --git a/tools/gce/linux_worker_init.sh b/tools/gce/linux_worker_init.sh
index a5d2706ddb..05855354ff 100755
--- a/tools/gce/linux_worker_init.sh
+++ b/tools/gce/linux_worker_init.sh
@@ -66,7 +66,10 @@ rm linux-*
# Add pubkey of jenkins@grpc-jenkins-master to authorized keys of jenkins@
# This needs to happen as the last step to prevent Jenkins master from connecting
# to a machine that hasn't been properly setup yet.
-cat jenkins_master.pub | sudo tee --append ~jenkins/.ssh/authorized_keys
+
+# disable superfluous warning by shellcheck:
+# shellcheck disable=SC2024
+sudo tee --append ~jenkins/.ssh/authorized_keys < jenkins_master.pub
# Restart for docker to pick up the config changes.
echo 'Successfully initialized the linux worker, going for reboot in 10 seconds'
diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh
new file mode 100644
index 0000000000..2f9c8531a0
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address"
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
+
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
new file mode 100755
index 0000000000..098d588e3b
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
@@ -0,0 +1,57 @@
+#!/usr/bin/env bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -ex
+
+# A temporary solution to give Kokoro credentials.
+# The file name 4321_grpc-testing-service needs to match auth_credential in
+# the build config.
+mkdir -p ${KOKORO_KEYSTORE_DIR}
+cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
+
+temp_dir=$(mktemp -d)
+ln -f "${KOKORO_GFILE_DIR}/bazel-canary" ${temp_dir}/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+export PATH="${temp_dir}:${PATH}"
+# This should show ${temp_dir}/bazel
+which bazel
+chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_linux_rc
+
+# TODO(adelez): implement size for test targets and change test_timeout back
+"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
+ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \
+ test --jobs="50" \
+ --test_timeout="3600,3600,3600,3600" \
+ --test_output=errors \
+ --verbose_failures=true \
+ --keep_going \
+ --remote_accept_cached=true \
+ --spawn_strategy=remote \
+ --remote_local_fallback=false \
+ --remote_timeout=3600 \
+ --strategy=Javac=remote \
+ --strategy=Closure=remote \
+ --genrule_strategy=remote \
+ --experimental_strict_action_env=true \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/cloud-marketplace/google/rbe-debian8@sha256:b2d946c1ddc20af250fe85cf98bd648ac5519131659f7c36e64184b433175a33" }' \
+ --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.3.0/bazel_0.10.0:toolchain \
+ --define GRPC_PORT_ISOLATED_RUNTIME=1 \
+ $1 \
+ -- //test/...
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
index c190298282..e5ffea6259 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
@@ -13,45 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-set -ex
+EXTRA_FLAGS="-c dbg"
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
-# A temporary solution to give Kokoro credentials.
-# The file name 4321_grpc-testing-service needs to match auth_credential in
-# the build config.
-mkdir -p ${KOKORO_KEYSTORE_DIR}
-cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
-
-mkdir -p /tmpfs/tmp/bazel-canary
-ln -f "${KOKORO_GFILE_DIR}/bazel-canary" /tmpfs/tmp/bazel-canary/bazel
-chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
-export PATH="/tmpfs/tmp/bazel-canary:${PATH}"
-# This should show /tmpfs/tmp/bazel-canary/bazel
-which bazel
-chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
-
-# change to grpc repo root
-cd $(dirname $0)/../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-# TODO(adelez): implement size for test targets and change test_timeout back
-"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
- --host_jvm_args=-Dbazel.DigestFunction=SHA256 \
- test --jobs="50" \
- --test_timeout="1200,1200,1200,3600" \
- --test_output=errors \
- --verbose_failures=true \
- --keep_going \
- --remote_accept_cached=true \
- --spawn_strategy=remote \
- --remote_local_fallback=false \
- --remote_timeout=3600 \
- --strategy=Javac=remote \
- --strategy=Closure=remote \
- --genrule_strategy=remote \
- --experimental_strict_action_env=true \
- --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:496193842f61c9494be68bd624e47c74d706cabf19a693c4653ffe96a97e43e3" }' \
- --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.2.0/bazel_0.7.0:toolchain \
- --define GRPC_PORT_ISOLATED_RUNTIME=1 \
- -c dbg \
- -- //test/...
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
index a8c5db4ab1..6a769b9a7c 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
@@ -13,45 +13,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-set -ex
-
-# A temporary solution to give Kokoro credentials.
-# The file name 4321_grpc-testing-service needs to match auth_credential in
-# the build config.
-mkdir -p ${KOKORO_KEYSTORE_DIR}
-cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
-
-mkdir -p /tmpfs/tmp/bazel-canary
-ln -f "${KOKORO_GFILE_DIR}/bazel-canary" /tmpfs/tmp/bazel-canary/bazel
-chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
-export PATH="/tmpfs/tmp/bazel-canary:${PATH}"
-# This should show /tmpfs/tmp/bazel-canary/bazel
-which bazel
-chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
-
-# change to grpc repo root
-cd $(dirname $0)/../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-# TODO(adelez): implement size for test targets and change test_timeout back
-"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
- --host_jvm_args=-Dbazel.DigestFunction=SHA256 \
- test --jobs="50" \
- --test_timeout="1200,1200,1200,3600" \
- --test_output=errors \
- --verbose_failures=true \
- --keep_going \
- --remote_accept_cached=true \
- --spawn_strategy=remote \
- --remote_local_fallback=false \
- --remote_timeout=3600 \
- --strategy=Javac=remote \
- --strategy=Closure=remote \
- --genrule_strategy=remote \
- --experimental_strict_action_env=true \
- --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:496193842f61c9494be68bd624e47c74d706cabf19a693c4653ffe96a97e43e3" }' \
- --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.2.0/bazel_0.7.0:toolchain \
- --define GRPC_PORT_ISOLATED_RUNTIME=1 \
- -c opt \
- -- //test/...
+EXTRA_FLAGS="-c opt"
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/grpc_msan_on_foundry.sh b/tools/internal_ci/linux/grpc_msan_on_foundry.sh
new file mode 100644
index 0000000000..2c64c7666b
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_msan_on_foundry.sh
@@ -0,0 +1,64 @@
+#!/usr/bin/env bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -ex
+
+# A temporary solution to give Kokoro credentials.
+# The file name 4321_grpc-testing-service needs to match auth_credential in
+# the build config.
+# TODO: Use keystore.
+mkdir -p ${KOKORO_KEYSTORE_DIR}
+cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
+
+temp_dir=$(mktemp -d)
+ln -f "${KOKORO_GFILE_DIR}/bazel-canary" ${temp_dir}/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+export PATH="${temp_dir}:${PATH}"
+# This should show ${temp_dir}/bazel
+which bazel
+chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_linux_rc
+
+"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
+ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \
+ test --jobs="50" \
+ --test_timeout="3600,3600,3600,3600" \
+ --test_output=errors \
+ --verbose_failures=true \
+ --keep_going \
+ --remote_accept_cached=true \
+ --spawn_strategy=remote \
+ --remote_local_fallback=false \
+ --remote_timeout=3600 \
+ --strategy=Javac=remote \
+ --strategy=Closure=remote \
+ --genrule_strategy=remote \
+ --experimental_strict_action_env=true \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-msan@sha256:8f381d55c0456fb65821c90ada902c2584977e03a1eaca8fba8ce77e644c775b" }' \
+ --define GRPC_PORT_ISOLATED_RUNTIME=1 \
+ --copt=-gmlt \
+ --strip=never \
+ --cxxopt=--stdlib=libc++ \
+ --copt=-fsanitize=memory \
+ --linkopt=-fsanitize=memory \
+ --copt=-fsanitize-memory-track-origins \
+ --action_env=LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH \
+ --host_crosstool_top=@bazel_toolchains//configs/debian8_clang/0.3.0/bazel_0.10.0:toolchain \
+ --crosstool_top=@bazel_toolchains//configs/experimental/debian8_clang/0.3.0/bazel_0.10.0/msan:msan_experimental_toolchain \
+ -- //test/...
diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
index 7da537ce49..f8e665ba8a 100644
--- a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
+++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh
@@ -13,49 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-set -ex
+EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread"
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
-# A temporary solution to give Kokoro credentials.
-# The file name 4321_grpc-testing-service needs to match auth_credential in
-# the build config.
-# TODO: Use keystore.
-mkdir -p ${KOKORO_KEYSTORE_DIR}
-cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
-
-mkdir -p /tmpfs/tmp/bazel-canary
-ln -f "${KOKORO_GFILE_DIR}/bazel-canary" /tmpfs/tmp/bazel-canary/bazel
-chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
-export PATH="/tmpfs/tmp/bazel-canary:${PATH}"
-# This should show /tmpfs/tmp/bazel-canary/bazel
-which bazel
-chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
-
-# change to grpc repo root
-cd $(dirname $0)/../../..
-
-source tools/internal_ci/helper_scripts/prepare_build_linux_rc
-
-"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
- --host_jvm_args=-Dbazel.DigestFunction=SHA256 \
- test --jobs="50" \
- --test_timeout="1500,1500,1500,3600" \
- --test_output=errors \
- --verbose_failures=true \
- --keep_going \
- --remote_accept_cached=true \
- --spawn_strategy=remote \
- --remote_local_fallback=false \
- --remote_timeout=3600 \
- --strategy=Javac=remote \
- --strategy=Closure=remote \
- --genrule_strategy=remote \
- --experimental_strict_action_env=true \
- --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/asci-toolchain/nosla-debian8-clang-fl@sha256:496193842f61c9494be68bd624e47c74d706cabf19a693c4653ffe96a97e43e3" }' \
- --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/debian8_clang/0.2.0/bazel_0.7.0:toolchain \
- --define GRPC_PORT_ISOLATED_RUNTIME=1 \
- --copt=-gmlt \
- --strip=never \
- --copt=-fsanitize=thread \
- --linkopt=-fsanitize=thread \
- --test_verbose_timeout_warnings \
- -- //test/...
diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
new file mode 100644
index 0000000000..cd1a340431
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -ex
+
+# A temporary solution to give Kokoro credentials.
+# The file name 4321_grpc-testing-service needs to match auth_credential in
+# the build config.
+# TODO: Use keystore.
+mkdir -p ${KOKORO_KEYSTORE_DIR}
+cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
+
+temp_dir=$(mktemp -d)
+ln -f "${KOKORO_GFILE_DIR}/bazel-canary" ${temp_dir}/bazel
+chmod 755 "${KOKORO_GFILE_DIR}/bazel-canary"
+export PATH="${temp_dir}:${PATH}"
+# This should show ${temp_dir}/bazel
+which bazel
+chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py"
+
+# change to grpc repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_linux_rc
+
+"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \
+ --host_jvm_args=-Dbazel.DigestFunction=SHA256 \
+ test --jobs="50" \
+ --test_timeout="3600,3600,3600,3600" \
+ --test_output=errors \
+ --verbose_failures=true \
+ --keep_going \
+ --remote_accept_cached=true \
+ --spawn_strategy=remote \
+ --remote_local_fallback=false \
+ --remote_timeout=3600 \
+ --strategy=Javac=remote \
+ --strategy=Closure=remote \
+ --genrule_strategy=remote \
+ --experimental_strict_action_env=true \
+ --experimental_remote_platform_override='properties:{name:"container-image" value:"docker://gcr.io/cloud-marketplace/google/rbe-debian8@sha256:b2d946c1ddc20af250fe85cf98bd648ac5519131659f7c36e64184b433175a33" }' \
+ --define GRPC_PORT_ISOLATED_RUNTIME=1 \
+ --copt=-gmlt \
+ --strip=never \
+ --copt=-fsanitize=undefined \
+ --linkopt=-fsanitize=undefined \
+ --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/debian8_clang/0.3.0/bazel_0.10.0/ubsan:ubsan_experimental_toolchain \
+ -- //test/...
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index a5436f1b76..906f690d98 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -18,11 +18,11 @@
def get_github_repo(lang):
return {
- 'go': 'git@github.com:grpc/grpc-go.git',
- 'java': 'git@github.com:grpc/grpc-java.git',
- 'node': 'git@github.com:grpc/grpc-node.git',
+ 'go': 'https://github.com/grpc/grpc-go.git',
+ 'java': 'https://github.com/grpc/grpc-java.git',
+ 'node': 'https://github.com/grpc/grpc-node.git',
# all other languages use the grpc.git repo.
- }.get(lang, 'git@github.com:grpc/grpc.git')
+ }.get(lang, 'https://github.com/grpc/grpc.git')
def get_release_tags(lang):
@@ -80,6 +80,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.8.0': None
},
+ {
+ 'v1.9.1': None
+ },
],
'go': [
{
@@ -109,6 +112,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.9.2': None
},
+ {
+ 'v1.10.0': None
+ },
],
'java': [
{
@@ -141,6 +147,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.9.1': None
},
+ {
+ 'v1.10.0': None
+ },
],
'python': [
{
@@ -167,6 +176,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.8.1': None # first python 1.8 release is 1.8.1
},
+ {
+ 'v1.9.1': None
+ },
],
'node': [
{
@@ -219,6 +231,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.8.0': None
},
+ {
+ 'v1.9.1': None
+ },
],
'php': [
{
@@ -245,6 +260,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.8.0': None
},
+ {
+ 'v1.9.1': None
+ },
],
'csharp': [
#{'v1.0.1': None},
@@ -269,5 +287,8 @@ LANG_RELEASE_MATRIX = {
{
'v1.8.0': None
},
+ {
+ 'v1.9.1': None
+ },
],
}
diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh
index 10d8211e23..9ea0f05660 100755
--- a/tools/run_tests/artifacts/build_artifact_python.sh
+++ b/tools/run_tests/artifacts/build_artifact_python.sh
@@ -35,6 +35,34 @@ ${SETARCH_CMD} "${PYTHON}" setup.py sdist
# https://bitbucket.org/pypa/wheel/issues/99/cannot-exclude-directory
${SETARCH_CMD} "${PYTHON}" setup.py bdist_wheel
+GRPCIO_STRIP_TEMPDIR=$(mktemp -d)
+GRPCIO_TAR_GZ_LIST=( dist/grpcio-*.tar.gz )
+GRPCIO_TAR_GZ=${GRPCIO_TAR_GZ_LIST[0]}
+GRPCIO_STRIPPED_TAR_GZ=$(mktemp -t "XXXXXXXXXX.tar.gz")
+
+clean_non_source_files() {
+( cd "$1"
+ find . -type f \
+ | grep -v '\.c$' | grep -v '\.cc$' | grep -v '\.cpp$' \
+ | grep -v '\.h$' | grep -v '\.hh$' \
+ | grep -v '\.s$' | grep -v '\.py$' \
+ | while read -r file; do
+ rm -f "$file" || true
+ done
+ find . -type d -empty -delete
+)
+}
+
+tar xzf "${GRPCIO_TAR_GZ}" -C "${GRPCIO_STRIP_TEMPDIR}"
+( cd "${GRPCIO_STRIP_TEMPDIR}"
+ find . -type d -name .git -exec rm -fr {} \; || true
+ for dir in */third_party/*; do
+ clean_non_source_files "${dir}" || true
+ done
+ tar czf "${GRPCIO_STRIPPED_TAR_GZ}" -- *
+)
+mv "${GRPCIO_STRIPPED_TAR_GZ}" "${GRPCIO_TAR_GZ}"
+
# Build gRPC tools package distribution
"${PYTHON}" tools/distrib/python/make_grpcio_tools.py
diff --git a/tools/run_tests/dockerize/docker_run.sh b/tools/run_tests/dockerize/docker_run.sh
index ac0d09c28b..e525019c44 100755
--- a/tools/run_tests/dockerize/docker_run.sh
+++ b/tools/run_tests/dockerize/docker_run.sh
@@ -25,9 +25,8 @@ then
# clone gRPC submodules, use data from locally cloned submodules where possible
# TODO: figure out a way to eliminate this following shellcheck suppressions
# shellcheck disable=SC2016,SC1004
- (cd "${EXTERNAL_GIT_ROOT}" && git submodule foreach 'cd /var/local/git/grpc \
- && git submodule update --init --reference ${EXTERNAL_GIT_ROOT}/${name} \
- ${name}')
+ (cd "${EXTERNAL_GIT_ROOT}" && git submodule foreach 'git clone ${EXTERNAL_GIT_ROOT}/${name} /var/local/git/grpc/${name}')
+ (cd /var/local/git/grpc && git submodule init)
else
mkdir -p "/var/local/git/grpc/$RELATIVE_COPY_PATH"
cp -r "$EXTERNAL_GIT_ROOT/$RELATIVE_COPY_PATH"/* "/var/local/git/grpc/$RELATIVE_COPY_PATH"
diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh
index 89ee315fd2..c41734c92d 100755
--- a/tools/run_tests/dockerize/docker_run_tests.sh
+++ b/tools/run_tests/dockerize/docker_run_tests.sh
@@ -23,13 +23,12 @@ export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer
export PATH=$PATH:/usr/bin/llvm-symbolizer
mkdir -p /var/local/git
-git clone /var/local/jenkins/grpc /var/local/git/grpc
+git clone /var/local/jenkins/grpc /var/local/git/grpc
# clone gRPC submodules, use data from locally cloned submodules where possible
# TODO: figure out a way to eliminate this shellcheck suppression:
-# shellcheck disable=SC2016,SC1004
-(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \
-&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
-${name}')
+# shellcheck disable=SC2016
+(cd /var/local/jenkins/grpc/ && git submodule foreach 'git clone /var/local/jenkins/grpc/${name} /var/local/git/grpc/${name}')
+(cd /var/local/git/grpc/ && git submodule init)
mkdir -p reports
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index c3c67d4fab..5e6dadfc89 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -1981,23 +1981,6 @@
"headers": [],
"is_filegroup": false,
"language": "c",
- "name": "slice_hash_table_test",
- "src": [
- "test/core/slice/slice_hash_table_test.cc"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc_test_util"
- ],
- "headers": [],
- "is_filegroup": false,
- "language": "c",
"name": "slice_string_helpers_test",
"src": [
"test/core/slice/slice_string_helpers_test.cc"
@@ -3441,29 +3424,6 @@
"gpr_test_util",
"grpc",
"grpc++",
- "grpc++_test_util",
- "grpc_test_util"
- ],
- "headers": [
- "src/proto/grpc/lb/v1/load_balancer.grpc.pb.h",
- "src/proto/grpc/lb/v1/load_balancer.pb.h",
- "src/proto/grpc/lb/v1/load_balancer_mock.grpc.pb.h"
- ],
- "is_filegroup": false,
- "language": "c++",
- "name": "grpclb_test",
- "src": [
- "test/cpp/grpclb/grpclb_test.cc"
- ],
- "third_party": false,
- "type": "target"
- },
- {
- "deps": [
- "gpr",
- "gpr_test_util",
- "grpc",
- "grpc++",
"grpc++_test",
"grpc_test_util"
],
@@ -3707,13 +3667,15 @@
"grpc_test_util"
],
"headers": [
- "include/grpc++/test/mock_stream.h"
+ "include/grpc++/test/mock_stream.h",
+ "include/grpcpp/test/mock_stream.h"
],
"is_filegroup": false,
"language": "c++",
"name": "mock_test",
"src": [
"include/grpc++/test/mock_stream.h",
+ "include/grpcpp/test/mock_stream.h",
"test/cpp/end2end/mock_test.cc"
],
"third_party": false,
@@ -4213,6 +4175,40 @@
"gpr",
"gpr_test_util",
"grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "slice_hash_table_test",
+ "src": [
+ "test/core/slice/slice_hash_table_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "slice_weak_hash_table_test",
+ "src": [
+ "test/core/slice/slice_weak_hash_table_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
"grpc++_test_util",
"grpc_test_util"
],
@@ -4228,6 +4224,20 @@
},
{
"deps": [
+ "grpc"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "status_metadata_test",
+ "src": [
+ "test/core/transport/status_metadata_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
"gpr",
"gpr_test_util",
"grpc",
@@ -4246,6 +4256,20 @@
},
{
"deps": [
+ "grpc"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "status_util_test",
+ "src": [
+ "test/core/client_channel/status_util_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
"gpr",
"gpr_test_util",
"grpc",
@@ -6503,6 +6527,7 @@
],
"headers": [
"include/grpc++/impl/codegen/core_codegen.h",
+ "include/grpcpp/impl/codegen/core_codegen.h",
"src/cpp/client/secure_credentials.h",
"src/cpp/common/secure_auth_context.h",
"src/cpp/server/secure_server_credentials.h"
@@ -6512,6 +6537,7 @@
"name": "grpc++",
"src": [
"include/grpc++/impl/codegen/core_codegen.h",
+ "include/grpcpp/impl/codegen/core_codegen.h",
"src/cpp/client/insecure_credentials.cc",
"src/cpp/client/secure_credentials.cc",
"src/cpp/client/secure_credentials.h",
@@ -6578,6 +6604,7 @@
],
"headers": [
"include/grpc++/support/error_details.h",
+ "include/grpcpp/support/error_details.h",
"src/proto/grpc/status/status.grpc.pb.h",
"src/proto/grpc/status/status.pb.h",
"src/proto/grpc/status/status_mock.grpc.pb.h"
@@ -6587,6 +6614,7 @@
"name": "grpc++_error_details",
"src": [
"include/grpc++/support/error_details.h",
+ "include/grpcpp/support/error_details.h",
"src/cpp/util/error_details.cc"
],
"third_party": false,
@@ -6620,6 +6648,7 @@
],
"headers": [
"include/grpc++/ext/proto_server_reflection_plugin.h",
+ "include/grpcpp/ext/proto_server_reflection_plugin.h",
"src/cpp/ext/proto_server_reflection.h"
],
"is_filegroup": false,
@@ -6627,6 +6656,7 @@
"name": "grpc++_reflection",
"src": [
"include/grpc++/ext/proto_server_reflection_plugin.h",
+ "include/grpcpp/ext/proto_server_reflection_plugin.h",
"src/cpp/ext/proto_server_reflection.cc",
"src/cpp/ext/proto_server_reflection.h",
"src/cpp/ext/proto_server_reflection_plugin.cc"
@@ -7131,20 +7161,80 @@
"third_party/boringssl/crypto/curve25519/internal.h",
"third_party/boringssl/crypto/err/internal.h",
"third_party/boringssl/crypto/evp/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/aes/aes.c",
"third_party/boringssl/crypto/fipsmodule/aes/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c",
+ "third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/add.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/asm/x86_64-gcc.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/bn.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/bytes.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/cmp.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/ctx.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/div.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/gcd.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/generic.c",
"third_party/boringssl/crypto/fipsmodule/bn/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/bn/jacobi.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/montgomery.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/mul.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/prime.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/random.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c",
"third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.h",
+ "third_party/boringssl/crypto/fipsmodule/bn/shift.c",
+ "third_party/boringssl/crypto/fipsmodule/bn/sqrt.c",
+ "third_party/boringssl/crypto/fipsmodule/cipher/aead.c",
+ "third_party/boringssl/crypto/fipsmodule/cipher/cipher.c",
+ "third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c",
+ "third_party/boringssl/crypto/fipsmodule/cipher/e_des.c",
"third_party/boringssl/crypto/fipsmodule/cipher/internal.h",
"third_party/boringssl/crypto/fipsmodule/delocate.h",
+ "third_party/boringssl/crypto/fipsmodule/des/des.c",
"third_party/boringssl/crypto/fipsmodule/des/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/digest/digest.c",
+ "third_party/boringssl/crypto/fipsmodule/digest/digests.c",
"third_party/boringssl/crypto/fipsmodule/digest/internal.h",
"third_party/boringssl/crypto/fipsmodule/digest/md32_common.h",
+ "third_party/boringssl/crypto/fipsmodule/ec/ec.c",
+ "third_party/boringssl/crypto/fipsmodule/ec/ec_key.c",
+ "third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c",
"third_party/boringssl/crypto/fipsmodule/ec/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/ec/oct.c",
+ "third_party/boringssl/crypto/fipsmodule/ec/p224-64.c",
+ "third_party/boringssl/crypto/fipsmodule/ec/p256-64.c",
"third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64-table.h",
+ "third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c",
"third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.h",
+ "third_party/boringssl/crypto/fipsmodule/ec/simple.c",
+ "third_party/boringssl/crypto/fipsmodule/ec/util-64.c",
+ "third_party/boringssl/crypto/fipsmodule/ec/wnaf.c",
+ "third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c",
+ "third_party/boringssl/crypto/fipsmodule/hmac/hmac.c",
+ "third_party/boringssl/crypto/fipsmodule/md4/md4.c",
+ "third_party/boringssl/crypto/fipsmodule/md5/md5.c",
+ "third_party/boringssl/crypto/fipsmodule/modes/cbc.c",
+ "third_party/boringssl/crypto/fipsmodule/modes/cfb.c",
+ "third_party/boringssl/crypto/fipsmodule/modes/ctr.c",
+ "third_party/boringssl/crypto/fipsmodule/modes/gcm.c",
"third_party/boringssl/crypto/fipsmodule/modes/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/modes/ofb.c",
+ "third_party/boringssl/crypto/fipsmodule/modes/polyval.c",
+ "third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c",
"third_party/boringssl/crypto/fipsmodule/rand/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/rand/rand.c",
+ "third_party/boringssl/crypto/fipsmodule/rand/urandom.c",
+ "third_party/boringssl/crypto/fipsmodule/rsa/blinding.c",
"third_party/boringssl/crypto/fipsmodule/rsa/internal.h",
+ "third_party/boringssl/crypto/fipsmodule/rsa/padding.c",
+ "third_party/boringssl/crypto/fipsmodule/rsa/rsa.c",
+ "third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c",
+ "third_party/boringssl/crypto/fipsmodule/sha/sha1-altivec.c",
+ "third_party/boringssl/crypto/fipsmodule/sha/sha1.c",
+ "third_party/boringssl/crypto/fipsmodule/sha/sha256.c",
+ "third_party/boringssl/crypto/fipsmodule/sha/sha512.c",
"third_party/boringssl/crypto/internal.h",
"third_party/boringssl/crypto/obj/obj_dat.h",
"third_party/boringssl/crypto/pkcs7/internal.h",
@@ -8083,6 +8173,21 @@
"test/core/end2end/tests/request_with_flags.cc",
"test/core/end2end/tests/request_with_payload.cc",
"test/core/end2end/tests/resource_quota_server.cc",
+ "test/core/end2end/tests/retry.cc",
+ "test/core/end2end/tests/retry_cancellation.cc",
+ "test/core/end2end/tests/retry_disabled.cc",
+ "test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc",
+ "test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc",
+ "test/core/end2end/tests/retry_non_retriable_status.cc",
+ "test/core/end2end/tests/retry_recv_initial_metadata.cc",
+ "test/core/end2end/tests/retry_recv_message.cc",
+ "test/core/end2end/tests/retry_server_pushback_delay.cc",
+ "test/core/end2end/tests/retry_server_pushback_disabled.cc",
+ "test/core/end2end/tests/retry_streaming.cc",
+ "test/core/end2end/tests/retry_streaming_after_commit.cc",
+ "test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc",
+ "test/core/end2end/tests/retry_throttled.cc",
+ "test/core/end2end/tests/retry_too_many_attempts.cc",
"test/core/end2end/tests/server_finishes_request.cc",
"test/core/end2end/tests/shutdown_finishes_calls.cc",
"test/core/end2end/tests/shutdown_finishes_tags.cc",
@@ -8165,6 +8270,21 @@
"test/core/end2end/tests/request_with_flags.cc",
"test/core/end2end/tests/request_with_payload.cc",
"test/core/end2end/tests/resource_quota_server.cc",
+ "test/core/end2end/tests/retry.cc",
+ "test/core/end2end/tests/retry_cancellation.cc",
+ "test/core/end2end/tests/retry_disabled.cc",
+ "test/core/end2end/tests/retry_exceeds_buffer_size_in_initial_batch.cc",
+ "test/core/end2end/tests/retry_exceeds_buffer_size_in_subsequent_batch.cc",
+ "test/core/end2end/tests/retry_non_retriable_status.cc",
+ "test/core/end2end/tests/retry_recv_initial_metadata.cc",
+ "test/core/end2end/tests/retry_recv_message.cc",
+ "test/core/end2end/tests/retry_server_pushback_delay.cc",
+ "test/core/end2end/tests/retry_server_pushback_disabled.cc",
+ "test/core/end2end/tests/retry_streaming.cc",
+ "test/core/end2end/tests/retry_streaming_after_commit.cc",
+ "test/core/end2end/tests/retry_streaming_succeeds_before_replay_finished.cc",
+ "test/core/end2end/tests/retry_throttled.cc",
+ "test/core/end2end/tests/retry_too_many_attempts.cc",
"test/core/end2end/tests/server_finishes_request.cc",
"test/core/end2end/tests/shutdown_finishes_calls.cc",
"test/core/end2end/tests/shutdown_finishes_tags.cc",
@@ -8293,7 +8413,7 @@
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_windows.h",
- "include/grpc/support/thd.h",
+ "include/grpc/support/thd_id.h",
"include/grpc/support/time.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
@@ -8304,7 +8424,7 @@
"src/core/lib/gpr/spinlock.h",
"src/core/lib/gpr/string.h",
"src/core/lib/gpr/string_windows.h",
- "src/core/lib/gpr/thd_internal.h",
+ "src/core/lib/gpr/thd.h",
"src/core/lib/gpr/time_precise.h",
"src/core/lib/gpr/tls.h",
"src/core/lib/gpr/tls_gcc.h",
@@ -8339,7 +8459,7 @@
"include/grpc/support/sync_generic.h",
"include/grpc/support/sync_posix.h",
"include/grpc/support/sync_windows.h",
- "include/grpc/support/thd.h",
+ "include/grpc/support/thd_id.h",
"include/grpc/support/time.h",
"src/core/lib/gpr/arena.h",
"src/core/lib/gpr/env.h",
@@ -8350,7 +8470,7 @@
"src/core/lib/gpr/spinlock.h",
"src/core/lib/gpr/string.h",
"src/core/lib/gpr/string_windows.h",
- "src/core/lib/gpr/thd_internal.h",
+ "src/core/lib/gpr/thd.h",
"src/core/lib/gpr/time_precise.h",
"src/core/lib/gpr/tls.h",
"src/core/lib/gpr/tls_gcc.h",
@@ -8551,7 +8671,6 @@
"src/core/lib/slice/percent_encoding.cc",
"src/core/lib/slice/slice.cc",
"src/core/lib/slice/slice_buffer.cc",
- "src/core/lib/slice/slice_hash_table.cc",
"src/core/lib/slice/slice_intern.cc",
"src/core/lib/slice/slice_string_helpers.cc",
"src/core/lib/surface/api_trace.cc",
@@ -8582,6 +8701,7 @@
"src/core/lib/transport/service_config.cc",
"src/core/lib/transport/static_metadata.cc",
"src/core/lib/transport/status_conversion.cc",
+ "src/core/lib/transport/status_metadata.cc",
"src/core/lib/transport/timeout_encoding.cc",
"src/core/lib/transport/transport.cc",
"src/core/lib/transport/transport_op_string.cc"
@@ -8708,6 +8828,7 @@
"src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/slice/slice_weak_hash_table.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
"src/core/lib/surface/call_test_only.h",
@@ -8732,6 +8853,7 @@
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
+ "src/core/lib/transport/status_metadata.h",
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h"
@@ -8852,6 +8974,7 @@
"src/core/lib/slice/slice_hash_table.h",
"src/core/lib/slice/slice_internal.h",
"src/core/lib/slice/slice_string_helpers.h",
+ "src/core/lib/slice/slice_weak_hash_table.h",
"src/core/lib/surface/api_trace.h",
"src/core/lib/surface/call.h",
"src/core/lib/surface/call_test_only.h",
@@ -8876,6 +8999,7 @@
"src/core/lib/transport/service_config.h",
"src/core/lib/transport/static_metadata.h",
"src/core/lib/transport/status_conversion.h",
+ "src/core/lib/transport/status_metadata.h",
"src/core/lib/transport/timeout_encoding.h",
"src/core/lib/transport/transport.h",
"src/core/lib/transport/transport_impl.h"
@@ -8899,6 +9023,7 @@
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
+ "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
@@ -8906,6 +9031,7 @@
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/status_util.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h",
"src/core/ext/filters/client_channel/uri_parser.h"
@@ -8934,6 +9060,8 @@
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
+ "src/core/ext/filters/client_channel/method_params.cc",
+ "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
@@ -8947,6 +9075,8 @@
"src/core/ext/filters/client_channel/resolver_registry.h",
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/status_util.cc",
+ "src/core/ext/filters/client_channel/status_util.h",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.cc",
@@ -9040,7 +9170,6 @@
],
"headers": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
- "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -9053,7 +9182,6 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc",
- "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
@@ -9077,7 +9205,6 @@
],
"headers": [
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
- "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h",
@@ -9090,7 +9217,6 @@
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc",
- "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc",
"src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc",
@@ -9288,11 +9414,11 @@
"src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
+ "src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
- "src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/secure_endpoint.h",
- "src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/transport/security_handshaker.h",
+ "src/core/lib/security/transport/target_authority_table.h",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/json_util.h"
],
@@ -9328,17 +9454,17 @@
"src/core/lib/security/credentials/plugin/plugin_credentials.h",
"src/core/lib/security/credentials/ssl/ssl_credentials.cc",
"src/core/lib/security/credentials/ssl/ssl_credentials.h",
+ "src/core/lib/security/security_connector/security_connector.cc",
+ "src/core/lib/security/security_connector/security_connector.h",
"src/core/lib/security/transport/auth_filters.h",
"src/core/lib/security/transport/client_auth_filter.cc",
- "src/core/lib/security/transport/lb_targets_info.cc",
- "src/core/lib/security/transport/lb_targets_info.h",
"src/core/lib/security/transport/secure_endpoint.cc",
"src/core/lib/security/transport/secure_endpoint.h",
- "src/core/lib/security/transport/security_connector.cc",
- "src/core/lib/security/transport/security_connector.h",
"src/core/lib/security/transport/security_handshaker.cc",
"src/core/lib/security/transport/security_handshaker.h",
"src/core/lib/security/transport/server_auth_filter.cc",
+ "src/core/lib/security/transport/target_authority_table.cc",
+ "src/core/lib/security/transport/target_authority_table.h",
"src/core/lib/security/transport/tsi_error.cc",
"src/core/lib/security/transport/tsi_error.h",
"src/core/lib/security/util/json_util.cc",
@@ -9919,7 +10045,37 @@
"include/grpc++/impl/codegen/string_ref.h",
"include/grpc++/impl/codegen/stub_options.h",
"include/grpc++/impl/codegen/sync_stream.h",
- "include/grpc++/impl/codegen/time.h"
+ "include/grpc++/impl/codegen/time.h",
+ "include/grpcpp/impl/codegen/async_stream.h",
+ "include/grpcpp/impl/codegen/async_unary_call.h",
+ "include/grpcpp/impl/codegen/byte_buffer.h",
+ "include/grpcpp/impl/codegen/call.h",
+ "include/grpcpp/impl/codegen/call_hook.h",
+ "include/grpcpp/impl/codegen/channel_interface.h",
+ "include/grpcpp/impl/codegen/client_context.h",
+ "include/grpcpp/impl/codegen/client_unary_call.h",
+ "include/grpcpp/impl/codegen/completion_queue.h",
+ "include/grpcpp/impl/codegen/completion_queue_tag.h",
+ "include/grpcpp/impl/codegen/config.h",
+ "include/grpcpp/impl/codegen/core_codegen_interface.h",
+ "include/grpcpp/impl/codegen/create_auth_context.h",
+ "include/grpcpp/impl/codegen/grpc_library.h",
+ "include/grpcpp/impl/codegen/metadata_map.h",
+ "include/grpcpp/impl/codegen/method_handler_impl.h",
+ "include/grpcpp/impl/codegen/rpc_method.h",
+ "include/grpcpp/impl/codegen/rpc_service_method.h",
+ "include/grpcpp/impl/codegen/security/auth_context.h",
+ "include/grpcpp/impl/codegen/serialization_traits.h",
+ "include/grpcpp/impl/codegen/server_context.h",
+ "include/grpcpp/impl/codegen/server_interface.h",
+ "include/grpcpp/impl/codegen/service_type.h",
+ "include/grpcpp/impl/codegen/slice.h",
+ "include/grpcpp/impl/codegen/status.h",
+ "include/grpcpp/impl/codegen/status_code_enum.h",
+ "include/grpcpp/impl/codegen/string_ref.h",
+ "include/grpcpp/impl/codegen/stub_options.h",
+ "include/grpcpp/impl/codegen/sync_stream.h",
+ "include/grpcpp/impl/codegen/time.h"
],
"is_filegroup": true,
"language": "c++",
@@ -9954,7 +10110,37 @@
"include/grpc++/impl/codegen/string_ref.h",
"include/grpc++/impl/codegen/stub_options.h",
"include/grpc++/impl/codegen/sync_stream.h",
- "include/grpc++/impl/codegen/time.h"
+ "include/grpc++/impl/codegen/time.h",
+ "include/grpcpp/impl/codegen/async_stream.h",
+ "include/grpcpp/impl/codegen/async_unary_call.h",
+ "include/grpcpp/impl/codegen/byte_buffer.h",
+ "include/grpcpp/impl/codegen/call.h",
+ "include/grpcpp/impl/codegen/call_hook.h",
+ "include/grpcpp/impl/codegen/channel_interface.h",
+ "include/grpcpp/impl/codegen/client_context.h",
+ "include/grpcpp/impl/codegen/client_unary_call.h",
+ "include/grpcpp/impl/codegen/completion_queue.h",
+ "include/grpcpp/impl/codegen/completion_queue_tag.h",
+ "include/grpcpp/impl/codegen/config.h",
+ "include/grpcpp/impl/codegen/core_codegen_interface.h",
+ "include/grpcpp/impl/codegen/create_auth_context.h",
+ "include/grpcpp/impl/codegen/grpc_library.h",
+ "include/grpcpp/impl/codegen/metadata_map.h",
+ "include/grpcpp/impl/codegen/method_handler_impl.h",
+ "include/grpcpp/impl/codegen/rpc_method.h",
+ "include/grpcpp/impl/codegen/rpc_service_method.h",
+ "include/grpcpp/impl/codegen/security/auth_context.h",
+ "include/grpcpp/impl/codegen/serialization_traits.h",
+ "include/grpcpp/impl/codegen/server_context.h",
+ "include/grpcpp/impl/codegen/server_interface.h",
+ "include/grpcpp/impl/codegen/service_type.h",
+ "include/grpcpp/impl/codegen/slice.h",
+ "include/grpcpp/impl/codegen/status.h",
+ "include/grpcpp/impl/codegen/status_code_enum.h",
+ "include/grpcpp/impl/codegen/string_ref.h",
+ "include/grpcpp/impl/codegen/stub_options.h",
+ "include/grpcpp/impl/codegen/sync_stream.h",
+ "include/grpcpp/impl/codegen/time.h"
],
"third_party": false,
"type": "filegroup"
@@ -9979,13 +10165,15 @@
"grpc++_config_proto"
],
"headers": [
- "include/grpc++/impl/codegen/proto_utils.h"
+ "include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpcpp/impl/codegen/proto_utils.h"
],
"is_filegroup": true,
"language": "c++",
"name": "grpc++_codegen_proto",
"src": [
- "include/grpc++/impl/codegen/proto_utils.h"
+ "include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpcpp/impl/codegen/proto_utils.h"
],
"third_party": false,
"type": "filegroup"
@@ -10045,6 +10233,51 @@
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
+ "include/grpcpp/alarm.h",
+ "include/grpcpp/channel.h",
+ "include/grpcpp/client_context.h",
+ "include/grpcpp/completion_queue.h",
+ "include/grpcpp/create_channel.h",
+ "include/grpcpp/create_channel_posix.h",
+ "include/grpcpp/ext/health_check_service_server_builder_option.h",
+ "include/grpcpp/generic/async_generic_service.h",
+ "include/grpcpp/generic/generic_stub.h",
+ "include/grpcpp/grpcpp.h",
+ "include/grpcpp/health_check_service_interface.h",
+ "include/grpcpp/impl/call.h",
+ "include/grpcpp/impl/channel_argument_option.h",
+ "include/grpcpp/impl/client_unary_call.h",
+ "include/grpcpp/impl/codegen/core_codegen.h",
+ "include/grpcpp/impl/grpc_library.h",
+ "include/grpcpp/impl/method_handler_impl.h",
+ "include/grpcpp/impl/rpc_method.h",
+ "include/grpcpp/impl/rpc_service_method.h",
+ "include/grpcpp/impl/serialization_traits.h",
+ "include/grpcpp/impl/server_builder_option.h",
+ "include/grpcpp/impl/server_builder_plugin.h",
+ "include/grpcpp/impl/server_initializer.h",
+ "include/grpcpp/impl/service_type.h",
+ "include/grpcpp/resource_quota.h",
+ "include/grpcpp/security/auth_context.h",
+ "include/grpcpp/security/auth_metadata_processor.h",
+ "include/grpcpp/security/credentials.h",
+ "include/grpcpp/security/server_credentials.h",
+ "include/grpcpp/server.h",
+ "include/grpcpp/server_builder.h",
+ "include/grpcpp/server_context.h",
+ "include/grpcpp/server_posix.h",
+ "include/grpcpp/support/async_stream.h",
+ "include/grpcpp/support/async_unary_call.h",
+ "include/grpcpp/support/byte_buffer.h",
+ "include/grpcpp/support/channel_arguments.h",
+ "include/grpcpp/support/config.h",
+ "include/grpcpp/support/slice.h",
+ "include/grpcpp/support/status.h",
+ "include/grpcpp/support/status_code_enum.h",
+ "include/grpcpp/support/string_ref.h",
+ "include/grpcpp/support/stub_options.h",
+ "include/grpcpp/support/sync_stream.h",
+ "include/grpcpp/support/time.h",
"src/cpp/client/create_channel_internal.h",
"src/cpp/common/channel_filter.h",
"src/cpp/server/dynamic_thread_pool.h",
@@ -10102,6 +10335,51 @@
"include/grpc++/support/stub_options.h",
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
+ "include/grpcpp/alarm.h",
+ "include/grpcpp/channel.h",
+ "include/grpcpp/client_context.h",
+ "include/grpcpp/completion_queue.h",
+ "include/grpcpp/create_channel.h",
+ "include/grpcpp/create_channel_posix.h",
+ "include/grpcpp/ext/health_check_service_server_builder_option.h",
+ "include/grpcpp/generic/async_generic_service.h",
+ "include/grpcpp/generic/generic_stub.h",
+ "include/grpcpp/grpcpp.h",
+ "include/grpcpp/health_check_service_interface.h",
+ "include/grpcpp/impl/call.h",
+ "include/grpcpp/impl/channel_argument_option.h",
+ "include/grpcpp/impl/client_unary_call.h",
+ "include/grpcpp/impl/codegen/core_codegen.h",
+ "include/grpcpp/impl/grpc_library.h",
+ "include/grpcpp/impl/method_handler_impl.h",
+ "include/grpcpp/impl/rpc_method.h",
+ "include/grpcpp/impl/rpc_service_method.h",
+ "include/grpcpp/impl/serialization_traits.h",
+ "include/grpcpp/impl/server_builder_option.h",
+ "include/grpcpp/impl/server_builder_plugin.h",
+ "include/grpcpp/impl/server_initializer.h",
+ "include/grpcpp/impl/service_type.h",
+ "include/grpcpp/resource_quota.h",
+ "include/grpcpp/security/auth_context.h",
+ "include/grpcpp/security/auth_metadata_processor.h",
+ "include/grpcpp/security/credentials.h",
+ "include/grpcpp/security/server_credentials.h",
+ "include/grpcpp/server.h",
+ "include/grpcpp/server_builder.h",
+ "include/grpcpp/server_context.h",
+ "include/grpcpp/server_posix.h",
+ "include/grpcpp/support/async_stream.h",
+ "include/grpcpp/support/async_unary_call.h",
+ "include/grpcpp/support/byte_buffer.h",
+ "include/grpcpp/support/channel_arguments.h",
+ "include/grpcpp/support/config.h",
+ "include/grpcpp/support/slice.h",
+ "include/grpcpp/support/status.h",
+ "include/grpcpp/support/status_code_enum.h",
+ "include/grpcpp/support/string_ref.h",
+ "include/grpcpp/support/stub_options.h",
+ "include/grpcpp/support/sync_stream.h",
+ "include/grpcpp/support/time.h",
"src/cpp/client/channel_cc.cc",
"src/cpp/client/client_context.cc",
"src/cpp/client/create_channel.cc",
@@ -10150,13 +10428,15 @@
{
"deps": [],
"headers": [
- "include/grpc++/impl/codegen/config_protobuf.h"
+ "include/grpc++/impl/codegen/config_protobuf.h",
+ "include/grpcpp/impl/codegen/config_protobuf.h"
],
"is_filegroup": true,
"language": "c++",
"name": "grpc++_config_proto",
"src": [
- "include/grpc++/impl/codegen/config_protobuf.h"
+ "include/grpc++/impl/codegen/config_protobuf.h",
+ "include/grpcpp/impl/codegen/config_protobuf.h"
],
"third_party": false,
"type": "filegroup"
@@ -10182,14 +10462,18 @@
],
"headers": [
"include/grpc++/test/mock_stream.h",
- "include/grpc++/test/server_context_test_spouse.h"
+ "include/grpc++/test/server_context_test_spouse.h",
+ "include/grpcpp/test/mock_stream.h",
+ "include/grpcpp/test/server_context_test_spouse.h"
],
"is_filegroup": true,
"language": "c++",
"name": "grpc++_test",
"src": [
"include/grpc++/test/mock_stream.h",
- "include/grpc++/test/server_context_test_spouse.h"
+ "include/grpc++/test/server_context_test_spouse.h",
+ "include/grpcpp/test/mock_stream.h",
+ "include/grpcpp/test/server_context_test_spouse.h"
],
"third_party": false,
"type": "filegroup"
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 3bd79b7690..fdcac9318c 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -2298,30 +2298,6 @@
"flaky": false,
"gtest": false,
"language": "c",
- "name": "slice_hash_table_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": false
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
- "gtest": false,
- "language": "c",
"name": "slice_string_helpers_test",
"platforms": [
"linux",
@@ -3902,30 +3878,6 @@
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
- "gtest": false,
- "language": "c++",
- "name": "grpclb_test",
- "platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "uses_polling": true
- },
- {
- "args": [],
- "benchmark": false,
- "ci_platforms": [
- "linux",
- "mac",
- "posix",
- "windows"
- ],
- "cpu_cost": 1.0,
- "exclude_configs": [],
- "exclude_iomgrs": [],
- "flaky": false,
"gtest": true,
"language": "c++",
"name": "h2_ssl_cert_test",
@@ -4513,6 +4465,54 @@
"windows"
],
"cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "slice_hash_table_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "slice_weak_hash_table_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
"exclude_configs": [
"tsan"
],
@@ -4543,6 +4543,30 @@
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "status_metadata_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
"gtest": false,
"language": "c++",
"name": "status_test",
@@ -4560,6 +4584,30 @@
"ci_platforms": [
"linux",
"mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "status_util_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
"posix"
],
"cpu_cost": 1.0,
@@ -7344,6 +7392,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -8682,6 +9075,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -9999,6 +10737,336 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_fakesec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -12541,6 +13609,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -13722,6 +15135,291 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -14977,6 +16675,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -16338,6 +18381,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -17763,6 +20151,366 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -19139,6 +21887,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -20540,6 +23633,366 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_oauth2_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -26818,6 +30271,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_ssl_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -29304,6 +33102,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -31585,6 +35728,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_census_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -32900,6 +37388,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_compress_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -35411,6 +40244,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -36573,6 +41751,291 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+pipe_nosec_test",
+ "platforms": [
+ "linux"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -37805,6 +43268,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+trace_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -39143,6 +44951,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_full+workarounds_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -40544,6 +46697,366 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_http_proxy_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -41897,6 +48410,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_load_reporting_nosec_test",
+ "platforms": [
+ "windows",
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -48012,6 +54870,351 @@
},
{
"args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_uds_nosec_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
"server_finishes_request"
],
"ci_platforms": [
@@ -93264,6 +100467,98 @@
},
{
"args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4774951120797696"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-4829913342279680"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-5632636438446080"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
+ "test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-minimized-api_fuzzer-6192640044302336"
+ ],
+ "ci_platforms": [
+ "linux"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [
+ "tsan"
+ ],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "api_fuzzer_one_entry",
+ "platforms": [
+ "mac",
+ "linux"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [
"test/core/end2end/fuzzers/api_fuzzer_corpus/crash-0597bbdd657fa4ed14443994c9147a1a7bbc205f"
],
"ci_platforms": [
diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py
index 433137a9bc..1c99e794a9 100755
--- a/tools/run_tests/run_tests_matrix.py
+++ b/tools/run_tests/run_tests_matrix.py
@@ -37,6 +37,9 @@ _CPP_RUNTESTS_TIMEOUT = 4 * 60 * 60
# C++ TSAN takes longer than other sanitizers
_CPP_TSAN_RUNTESTS_TIMEOUT = 8 * 60 * 60
+# Set timeout high for ObjC for Cocoapods to install pods
+_OBJC_RUNTESTS_TIMEOUT = 90 * 60
+
# Number of jobs assigned to each run_tests.py instance
_DEFAULT_INNER_JOBS = 2
@@ -213,7 +216,8 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS):
platforms=['macos'],
labels=['basictests', 'multilang'],
extra_args=extra_args,
- inner_jobs=inner_jobs)
+ inner_jobs=inner_jobs,
+ timeout_seconds=_OBJC_RUNTESTS_TIMEOUT)
# sanitizers
test_jobs += _generate_jobs(
diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py
index 62a6229c5d..555149c820 100755
--- a/tools/run_tests/sanity/check_bazel_workspace.py
+++ b/tools/run_tests/sanity/check_bazel_workspace.py
@@ -35,6 +35,11 @@ git_submodule_hashes = {
}
_BAZEL_TOOLCHAINS_DEP_NAME = 'com_github_bazelbuild_bazeltoolchains'
+_TWISTED_TWISTED_DEP_NAME = 'com_github_twisted_twisted'
+_YAML_PYYAML_DEP_NAME = 'com_github_yaml_pyyaml'
+_TWISTED_INCREMENTAL_DEP_NAME = 'com_github_twisted_incremental'
+_ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME = 'com_github_zopefoundation_zope_interface'
+_TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly'
_GRPC_DEP_NAMES = [
'boringssl',
@@ -46,6 +51,20 @@ _GRPC_DEP_NAMES = [
'com_github_cares_cares',
'com_google_absl',
_BAZEL_TOOLCHAINS_DEP_NAME,
+ _TWISTED_TWISTED_DEP_NAME,
+ _YAML_PYYAML_DEP_NAME,
+ _TWISTED_INCREMENTAL_DEP_NAME,
+ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME,
+ _TWISTED_CONSTANTLY_DEP_NAME,
+]
+
+_GRPC_BAZEL_ONLY_DEPS = [
+ _BAZEL_TOOLCHAINS_DEP_NAME,
+ _TWISTED_TWISTED_DEP_NAME,
+ _YAML_PYYAML_DEP_NAME,
+ _TWISTED_INCREMENTAL_DEP_NAME,
+ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME,
+ _TWISTED_CONSTANTLY_DEP_NAME,
]
@@ -70,7 +89,8 @@ class BazelEvalState(object):
return []
def archive(self, **args):
- if args['name'] == _BAZEL_TOOLCHAINS_DEP_NAME:
+ assert self.names_and_urls.get(args['name']) is None
+ if args['name'] in _GRPC_BAZEL_ONLY_DEPS:
self.names_and_urls[args['name']] = 'dont care'
return
self.names_and_urls[args['name']] = args['url']
@@ -82,8 +102,10 @@ with open(os.path.join('bazel', 'grpc_deps.bzl'), 'r') as f:
eval_state = BazelEvalState(names_and_urls)
bazel_file = f.read()
-# grpc_deps.bzl only defines 'grpc_deps', add this to call it
+# grpc_deps.bzl only defines 'grpc_deps' and 'grpc_test_only_deps', add these
+# lines to call them.
bazel_file += '\ngrpc_deps()\n'
+bazel_file += '\ngrpc_test_only_deps()\n'
build_rules = {
'native': eval_state,
}
@@ -92,11 +114,12 @@ for name in _GRPC_DEP_NAMES:
assert name in names_and_urls.keys()
assert len(_GRPC_DEP_NAMES) == len(names_and_urls.keys())
-# bazeltoolschains is an exception to this sanity check,
-# we don't require that there is a corresponding git module.
-names_without_bazeltoolchains = names_and_urls.keys()
-names_without_bazeltoolchains.remove(_BAZEL_TOOLCHAINS_DEP_NAME)
-archive_urls = [names_and_urls[name] for name in names_without_bazeltoolchains]
+# There are some "bazel-only" deps that are exceptions to this sanity check,
+# we don't require that there is a corresponding git module for these.
+names_without_bazel_only_deps = names_and_urls.keys()
+for dep_name in _GRPC_BAZEL_ONLY_DEPS:
+ names_without_bazel_only_deps.remove(dep_name)
+archive_urls = [names_and_urls[name] for name in names_without_bazel_only_deps]
workspace_git_hashes = {
re.search(git_hash_pattern, url).group()
for url in archive_urls
diff --git a/tools/run_tests/sanity/check_deprecated_grpc++.py b/tools/run_tests/sanity/check_deprecated_grpc++.py
new file mode 100755
index 0000000000..4ec49fae39
--- /dev/null
+++ b/tools/run_tests/sanity/check_deprecated_grpc++.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python
+
+# Copyright 2018 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+
+import os
+import sys
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+expected_files = [
+ "include/grpc++/create_channel_posix.h", "include/grpc++/server_builder.h",
+ "include/grpc++/resource_quota.h", "include/grpc++/create_channel.h",
+ "include/grpc++/alarm.h", "include/grpc++/server.h",
+ "include/grpc++/server_context.h", "include/grpc++/client_context.h",
+ "include/grpc++/server_posix.h", "include/grpc++/grpc++.h",
+ "include/grpc++/health_check_service_interface.h",
+ "include/grpc++/completion_queue.h", "include/grpc++/channel.h",
+ "include/grpc++/support/sync_stream.h", "include/grpc++/support/status.h",
+ "include/grpc++/support/config.h",
+ "include/grpc++/support/status_code_enum.h",
+ "include/grpc++/support/byte_buffer.h",
+ "include/grpc++/support/error_details.h",
+ "include/grpc++/support/async_unary_call.h",
+ "include/grpc++/support/channel_arguments.h",
+ "include/grpc++/support/async_stream.h", "include/grpc++/support/slice.h",
+ "include/grpc++/support/stub_options.h",
+ "include/grpc++/support/string_ref.h", "include/grpc++/support/time.h",
+ "include/grpc++/security/auth_metadata_processor.h",
+ "include/grpc++/security/credentials.h",
+ "include/grpc++/security/server_credentials.h",
+ "include/grpc++/security/auth_context.h",
+ "include/grpc++/impl/rpc_method.h",
+ "include/grpc++/impl/server_builder_option.h", "include/grpc++/impl/call.h",
+ "include/grpc++/impl/service_type.h", "include/grpc++/impl/grpc_library.h",
+ "include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/channel_argument_option.h",
+ "include/grpc++/impl/rpc_service_method.h",
+ "include/grpc++/impl/method_handler_impl.h",
+ "include/grpc++/impl/server_builder_plugin.h",
+ "include/grpc++/impl/sync_cxx11.h",
+ "include/grpc++/impl/server_initializer.h",
+ "include/grpc++/impl/serialization_traits.h",
+ "include/grpc++/impl/sync_no_cxx11.h",
+ "include/grpc++/impl/codegen/sync_stream.h",
+ "include/grpc++/impl/codegen/channel_interface.h",
+ "include/grpc++/impl/codegen/config_protobuf.h",
+ "include/grpc++/impl/codegen/status.h",
+ "include/grpc++/impl/codegen/core_codegen.h",
+ "include/grpc++/impl/codegen/config.h",
+ "include/grpc++/impl/codegen/core_codegen_interface.h",
+ "include/grpc++/impl/codegen/status_code_enum.h",
+ "include/grpc++/impl/codegen/metadata_map.h",
+ "include/grpc++/impl/codegen/rpc_method.h",
+ "include/grpc++/impl/codegen/server_context.h",
+ "include/grpc++/impl/codegen/byte_buffer.h",
+ "include/grpc++/impl/codegen/async_unary_call.h",
+ "include/grpc++/impl/codegen/server_interface.h",
+ "include/grpc++/impl/codegen/call.h",
+ "include/grpc++/impl/codegen/client_context.h",
+ "include/grpc++/impl/codegen/service_type.h",
+ "include/grpc++/impl/codegen/grpc_library.h",
+ "include/grpc++/impl/codegen/async_stream.h",
+ "include/grpc++/impl/codegen/slice.h",
+ "include/grpc++/impl/codegen/client_unary_call.h",
+ "include/grpc++/impl/codegen/proto_utils.h",
+ "include/grpc++/impl/codegen/stub_options.h",
+ "include/grpc++/impl/codegen/rpc_service_method.h",
+ "include/grpc++/impl/codegen/method_handler_impl.h",
+ "include/grpc++/impl/codegen/string_ref.h",
+ "include/grpc++/impl/codegen/completion_queue_tag.h",
+ "include/grpc++/impl/codegen/call_hook.h",
+ "include/grpc++/impl/codegen/completion_queue.h",
+ "include/grpc++/impl/codegen/serialization_traits.h",
+ "include/grpc++/impl/codegen/create_auth_context.h",
+ "include/grpc++/impl/codegen/time.h",
+ "include/grpc++/impl/codegen/security/auth_context.h",
+ "include/grpc++/ext/health_check_service_server_builder_option.h",
+ "include/grpc++/ext/proto_server_reflection_plugin.h",
+ "include/grpc++/generic/async_generic_service.h",
+ "include/grpc++/generic/generic_stub.h",
+ "include/grpc++/test/mock_stream.h",
+ "include/grpc++/test/server_context_test_spouse.h"
+]
+
+file_template = '''/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// DEPRECATED: The headers in include/grpc++ are deprecated. Please include the
+// headers in include/grpcpp instead. This header exists only for backwards
+// compatibility.
+
+#ifndef GRPCXX_FILE_PATH_NAME_UPPER
+#define GRPCXX_FILE_PATH_NAME_UPPER
+
+#include <grpcpp/FILE_PATH_NAME_LOWER>
+
+#endif // GRPCXX_FILE_PATH_NAME_UPPER
+'''
+
+errors = 0
+
+path_files = []
+for root, dirs, files in os.walk('include/grpc++'):
+ for filename in files:
+ path_file = os.path.join(root, filename)
+ path_files.append(path_file)
+
+if path_files.sort() != expected_files.sort():
+ diff_plus = [file for file in path_files if file not in expected_files]
+ diff_minus = [file for file in expected_files if file not in path_files]
+ for file in diff_minus:
+ print('- ', file)
+ for file in diff_plus:
+ print('+ ', file)
+ errors += 1
+
+if errors > 0:
+ sys.exit(errors)
+
+for path_file in expected_files:
+ relative_path_file = path_file.split('/', 2)[2]
+
+ replace_lower = relative_path_file.replace('+', 'p')
+
+ replace_upper = relative_path_file.replace('/', '_')
+ replace_upper = replace_upper.replace('.', '_')
+ replace_upper = replace_upper.upper().replace('+', 'X')
+
+ expected_content = file_template.replace('FILE_PATH_NAME_LOWER',
+ replace_lower)
+ expected_content = expected_content.replace('FILE_PATH_NAME_UPPER',
+ replace_upper)
+
+ path_file_expected = path_file + '.expected'
+ with open(path_file_expected, "w") as fo:
+ fo.write(expected_content)
+
+ if 0 != os.system('diff %s %s' % (path_file_expected, path_file)):
+ print('Difference found in file:', path_file)
+ errors += 1
+
+ os.remove(path_file_expected)
+
+check_extensions = [".h", ".cc", ".c", ".m"]
+
+for root, dirs, files in os.walk('src'):
+ for filename in files:
+ path_file = os.path.join(root, filename)
+ for ext in check_extensions:
+ if path_file.endswith(ext):
+ try:
+ with open(path_file, "r") as fi:
+ content = fi.read()
+ if '#include <grpc++/' in content:
+ print(
+ 'Failed: invalid include of deprecated headers in include/grpc++ in %s'
+ % path_file)
+ errors += 1
+ except IOError:
+ pass
+
+sys.exit(errors)
diff --git a/tools/run_tests/sanity/check_port_platform.py b/tools/run_tests/sanity/check_port_platform.py
new file mode 100755
index 0000000000..fff828eaee
--- /dev/null
+++ b/tools/run_tests/sanity/check_port_platform.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# Copyright 2017 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import sys
+
+os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+
+
+def check_port_platform_inclusion(directory_root):
+ bad_files = []
+ for root, dirs, files in os.walk(directory_root):
+ for filename in files:
+ path = os.path.join(root, filename)
+ if os.path.splitext(path)[1] not in ['.c', '.cc', '.h']: continue
+ if path in [
+ os.path.join('include', 'grpc', 'support',
+ 'port_platform.h'),
+ os.path.join('include', 'grpc', 'impl', 'codegen',
+ 'port_platform.h'),
+ ]:
+ continue
+ if filename.endswith('.pb.h') or filename.endswith('.pb.c'):
+ continue
+ with open(path) as f:
+ all_lines_in_file = f.readlines()
+ for index, l in enumerate(all_lines_in_file):
+ if '#include' in l:
+ if l not in [
+ '#include <grpc/support/port_platform.h>\n',
+ '#include <grpc/impl/codegen/port_platform.h>\n'
+ ]:
+ bad_files.append(path)
+ elif all_lines_in_file[index + 1] != '\n':
+ # Require a blank line after including port_platform.h in
+ # order to prevent the formatter from reording it's
+ # inclusion order upon future changes.
+ bad_files.append(path)
+ break
+ return bad_files
+
+
+all_bad_files = []
+all_bad_files += check_port_platform_inclusion(os.path.join('src', 'core'))
+all_bad_files += check_port_platform_inclusion(os.path.join('include', 'grpc'))
+
+if len(all_bad_files) > 0:
+ for f in all_bad_files:
+ print(('port_platform.h is not the first included header or there '
+ 'is not a blank line following its inclusion in %s') % f)
+ sys.exit(1)
diff --git a/tools/run_tests/sanity/check_shellcheck.sh b/tools/run_tests/sanity/check_shellcheck.sh
index 6e60ea2fee..b94d822789 100755
--- a/tools/run_tests/sanity/check_shellcheck.sh
+++ b/tools/run_tests/sanity/check_shellcheck.sh
@@ -20,6 +20,7 @@ ROOT="$(dirname "$0")/../../.."
DIRS=(
'test'
+ 'tools/gce'
'tools/run_tests'
)
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index efdb4d84b5..a15473db0f 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -10,6 +10,8 @@
- script: tools/run_tests/sanity/check_unsecure.sh
- script: tools/run_tests/sanity/core_banned_functions.py
- script: tools/run_tests/sanity/core_untyped_structs.sh
+- script: tools/run_tests/sanity/check_deprecated_grpc++.py
+- script: tools/run_tests/sanity/check_port_platform.py
- script: tools/buildgen/generate_projects.sh -j 3
cpu_cost: 3
- script: tools/distrib/check_copyright.py